From 574968b1c655ab5d7c9a704dbc3ebfbe53ad27f1 Mon Sep 17 00:00:00 2001 From: Konstantin Kutscher <kutscher@irmb.tu-bs.de> Date: Sat, 10 Feb 2018 00:40:01 +0100 Subject: [PATCH] -fixed F16 setup -add directions into SpongeLayerBlockVisitor -add mq selection --- .../Applications/DLR-F16-Solid/f16-solid.cfg | 80 +- source/Applications/DLR-F16-Solid/f16.cpp | 376 +-- source/CMakeLists.txt | 13 +- source/VirtualFluids.h | 1 + .../MPIIOMigrationCoProcessor.cpp | 2401 +++++++++++---- .../CoProcessors/MPIIOMigrationCoProcessor.h | 156 +- .../CoProcessors/MPIIORestartCoProcessor.cpp | 2659 ++++++++++++----- .../CoProcessors/MPIIORestartCoProcessor.h | 167 +- .../WriteMQFromSelectionCoProcessor.cpp | 237 ++ .../WriteMQFromSelectionCoProcessor.h | 57 + .../WriteMacroscopicQuantitiesCoProcessor.h | 5 +- .../Interactors/Interactor3D.cpp | 12 +- .../Visitors/GenBlocksGridVisitor.cpp | 20 +- .../Visitors/SpongeLayerBlockVisitor.cpp | 58 +- .../Visitors/SpongeLayerBlockVisitor.h | 7 +- 15 files changed, 4629 insertions(+), 1620 deletions(-) create mode 100644 source/VirtualFluidsCore/CoProcessors/WriteMQFromSelectionCoProcessor.cpp create mode 100644 source/VirtualFluidsCore/CoProcessors/WriteMQFromSelectionCoProcessor.h diff --git a/source/Applications/DLR-F16-Solid/f16-solid.cfg b/source/Applications/DLR-F16-Solid/f16-solid.cfg index ad1a2468f..944a53c02 100644 --- a/source/Applications/DLR-F16-Solid/f16-solid.cfg +++ b/source/Applications/DLR-F16-Solid/f16-solid.cfg @@ -1,70 +1,62 @@ -pathOut = d:/temp/DLR-F16-Solid2 +pathOut = d:/temp/DLR-F16-Solid6 pathGeo = d:/Projects/SFB880/DLR-F16/Geometry -fngFileWhole = F16_broad_full_coarse.stl +#fngFileWhole = F16_broad_full.stl +#fngFileWhole = F16_broad_full_coarse.stl +#fngFileWhole = F16withTapeMeshedFineBig.stl +#fngFileWhole = F16withTapeMeshedFine.stl +#fngFileWhole = f16-ascii.stl +#fngFileWhole = f16.stl +fngFileWhole = F16_broad_Quad_full.stl +#fngFileWhole = F16_broad_noTape_full_bin.stl pathReInit = /work/koskuche/DLR-F16_L7 stepReInit = 10000 numOfThreads = 4 -availMem = 15e9 +availMem = 3.5e9 logToFile = false #x1min x1max x2min x2max x3min x3max [m] -#deltaXfine = 0.00001171875 -#deltaXfine = 0.00075 -#boundingBox = -0.90 1.20 0.035 0.065 -0.65 0.65 -#boundingBox = -0.90 2.1 0.035 0.065 -0.66 0.66 -boundingBox = -0.12 1.1 0.0 0.03 -0.24 0.24 -#boundingBox = 0.1 0.15 -0.002 0.0302 -0.01 0.01 -#boundingBox = -0.01 0.0 -0.06 0.06 0.01 0.03 -blockNx = 10 5 10 - -#deltaXfine = 13393e-9 -#boundingBox = -0.90 1.19145087 0.035 0.06928608 -0.65 0.65 -#blockNx = 10 10 10 - -#boundingBox = -0.90 1.19998697917 0.035 6.49869791667e-2 -0.65 0.65 -#deltaXfine = 1.30208333333e-5 -#blockNx = 9 9 9 - -refineLevel = 1 - -#deltaXfine = 0.001 -#deltaXfine = 0.006 #level 0 +boundingBox = -0.90 2.1 0.0 0.03 -0.66 0.66 + +blockNx = 10 10 10 + +refineLevel = 0 + deltaXfine = 0.003 -#deltaXfine = 0.0015 #level 0 -#deltaXfine = 0.00075 #level 1 -#deltaXfine = 0.000375 #level 2 -#deltaXfine = 0.0001875 #level 3 -#deltaXfine = 0.00009375 #level 4 -#deltaXfine = 0.000046875 #level 5 -#deltaXfine = 0.0000234375 #level 6 - -startDistance = -1.0 -#refineDistance = 12 -#refineDistance = 1.2 -refineDistance = 0.6 -#refineDistance = 0.3 +#deltaXfine = 0.00075 #level 0 +#deltaXfine = 0.000375 #level 1 +#deltaXfine = 0.0001875 #level 2 +#deltaXfine = 0.00009375 #level 3 +#deltaXfine = 0.000046875 #level 4 +#deltaXfine = 0.0000234375 #level 5 + +#startDistance = -0.0007 +#refineDistance = 0.0008 + +startDistance = -1.0e-3 +refineDistance = 0.6e-3 writeBlocks = true newStart = true -restartStep = 40000 +restartStep = 50 + +cpStep = 50 +cpStart = 50 -cpStep = 400000 -cpStart = 400000 +outTimeStep = 10 +outTimeStart = 10 -outTimeStep = 400000 -outTimeStart = 0 +endTime = 100 -endTime = 40000 #Cp pcpStart = 1000000 pcpStop = 1000000 -timeAvStart = 10000 +timeAvStart = 0 timeAvStop = 40000 nupsStep = 1000 1000 10000000 diff --git a/source/Applications/DLR-F16-Solid/f16.cpp b/source/Applications/DLR-F16-Solid/f16.cpp index b62a4d442..5b855d5d2 100644 --- a/source/Applications/DLR-F16-Solid/f16.cpp +++ b/source/Applications/DLR-F16-Solid/f16.cpp @@ -75,13 +75,13 @@ void run(string configname) //the geometry is in mm - double g_minX1 = boundingBox[0]; - double g_minX2 = boundingBox[2]; - double g_minX3 = boundingBox[4]; - - double g_maxX1 = boundingBox[1]; - double g_maxX2 = boundingBox[3]; - double g_maxX3 = boundingBox[5]; + double g_minX1 = boundingBox[0];//*1000.0; + double g_minX2 = boundingBox[2];//*1000.0; + double g_minX3 = boundingBox[4];//*1000.0; + double g_maxX1 = boundingBox[1];//*1000.0; + double g_maxX2 = boundingBox[3];//*1000.0; + double g_maxX3 = boundingBox[5];//*1000.0; + //deltaXfine *=1000.0; ////////////////////////////////////////////////////////////////////////// double deltaXcoarse = deltaXfine*(double)(1<<refineLevel); @@ -111,7 +111,7 @@ void run(string configname) double uLB = uReal * unitConverter.getFactorVelocityWToLb(); double nuLB = nuReal * unitConverter.getFactorViscosityWToLb(); - double lLB = lReal*1000.0/deltaXcoarse; + double lLB = lReal/deltaXcoarse; //double nuLB = (uLB*lLB)/Re; //0.005; //double nuLB = 0.005; @@ -150,20 +150,24 @@ void run(string configname) bcVisitor.addBC(velBCAdapter); bcVisitor.addBC(outflowBCAdapter); + SPtr<BCProcessor> bcProc; + bcProc = SPtr<BCProcessor>(new BCProcessor()); + //SPtr<LBMKernel> kernel = SPtr<LBMKernel>(new CompressibleCumulantLBMKernel()); //dynamicPointerCast<CompressibleCumulantLBMKernel>(kernel)->setRelaxationParameter(CompressibleCumulantLBMKernel::NORMAL); SPtr<LBMKernel> kernel = SPtr<LBMKernel>(new CompressibleCumulant4thOrderViscosityLBMKernel()); //dynamicPointerCast<CompressibleCumulant4thOrderViscosityLBMKernel>(kernel)->setBulkViscosity(nuLB*2.0e3); - - SPtr<BCProcessor> bcProc; - bcProc = SPtr<BCProcessor>(new BCProcessor()); kernel->setBCProcessor(bcProc); + + SPtr<LBMKernel> spKernel = SPtr<LBMKernel>(new CompressibleCumulantLBMKernel()); + spKernel->setBCProcessor(bcProc); ////////////////////////////////////////////////////////////////////////// //restart SPtr<UbScheduler> rSch(new UbScheduler(cpStep, cpStart)); SPtr<MPIIORestartCoProcessor> restartCoProcessor(new MPIIORestartCoProcessor(grid, rSch, pathOut, comm)); + //SPtr<MPIIOMigrationCoProcessor> restartCoProcessor(new MPIIOMigrationCoProcessor(grid, rSch, pathOut, comm)); restartCoProcessor->setLBMKernel(kernel); restartCoProcessor->setBCProcessor(bcProc); ////////////////////////////////////////////////////////////////////////// @@ -223,8 +227,8 @@ void run(string configname) fngMeshWhole = SPtr<GbTriFaceMesh3D>(GbTriFaceMesh3DCreator::getInstance()->readMeshFromSTLFile2(pathGeo+"/"+fngFileWhole, "fngMeshWhole", GbTriFaceMesh3D::KDTREE_SAHPLIT, false)); if (myid==0) UBLOG(logINFO, "Read fngFileWhole:end"); fngMeshWhole->rotate(0.0, 0.5, 0.0); - //fngMeshWhole->scale(1e-3,1e-3,1e-3); - //fngMeshWhole->translate(-150.0,-50.0,-1.28); + //fngMeshWhole->scale(1e3,1e3,1e3); + //fngMeshWhole->translate(1.932008e-5-149.867,-0.03-49.95,-0.0172298-1.32814); if (myid==0) GbSystem3D::writeGeoObject(fngMeshWhole.get(), pathOut+"/geo/fngMeshWhole", WbWriterVtkXmlBinary::getInstance()); if (myid==0) @@ -235,7 +239,7 @@ void run(string configname) ////////////////////////////////////////////////////////////////////////// SPtr<Interactor3D> fngIntrWhole; //fngIntrWhole = SPtr<D3Q27Interactor>(new D3Q27Interactor(fngMeshWhole, grid, noSlipBCAdapter, Interactor3D::SOLID));//, Interactor3D::POINTS)); - fngIntrWhole = SPtr<D3Q27TriFaceMeshInteractor>(new D3Q27TriFaceMeshInteractor(fngMeshWhole, grid, noSlipBCAdapter, Interactor3D::SOLID, Interactor3D::POINTS)); + fngIntrWhole = SPtr<D3Q27TriFaceMeshInteractor>(new D3Q27TriFaceMeshInteractor(fngMeshWhole, grid, noSlipBCAdapter, Interactor3D::SOLID));//, Interactor3D::POINTS)); if (refineLevel>0 && myid==0 && writeBlocks) { @@ -243,77 +247,82 @@ void run(string configname) int rank = grid->getRank(); grid->setRank(0); + int level; //level 1 level = 1; if (refineLevel - level >= 0) { - SPtr<GbObject3D> refCylinderL2(new GbCylinder3D(0.015, 0.0, 0.0, 0.015, 0.1, 0.0, 0.040)); - GbSystem3D::writeGeoObject(refCylinderL2.get(), pathOut + "/geo/refCylinderL2", WbWriterVtkXmlBinary::getInstance()); - RefineCrossAndInsideGbObjectBlockVisitor refVisitorCylinderL2(refCylinderL2, level); - grid->accept(refVisitorCylinderL2); - - //SPtr<GbObject3D> refBoxL2(new GbCuboid3D(0.015, 0.0, -0.04, 1.100, 0.1, 0.04)); - SPtr<GbObject3D> refBoxL2(new GbCuboid3D(0.015, 0.0, -0.04, 0.5, 0.1, 0.04)); - if (myid==0) GbSystem3D::writeGeoObject(refBoxL2.get(), pathOut+"/geo/refBoxL2", WbWriterVtkXmlASCII::getInstance()); - RefineCrossAndInsideGbObjectBlockVisitor refVisitorBoxL2(refBoxL2, level); - grid->accept(refVisitorBoxL2); + SPtr<GbObject3D> refCylinderL1(new GbCylinder3D(0.015, -0.03, 0.0, 0.015, 0.06, 0.0, 0.03)); + GbSystem3D::writeGeoObject(refCylinderL1.get(), pathOut + "/geo/refCylinderL1", WbWriterVtkXmlBinary::getInstance()); + RefineCrossAndInsideGbObjectBlockVisitor refVisitorCylinderL1(refCylinderL1, level); + grid->accept(refVisitorCylinderL1); + + SPtr<GbObject3D> refBoxL1(new GbCuboid3D(0.015, -0.03, -0.03, 1.100, 0.06, 0.03)); + //SPtr<GbObject3D> refBoxL1(new GbCuboid3D(0.015, 0.0, -0.04, 0.5, 0.1, 0.04)); + if (myid==0) GbSystem3D::writeGeoObject(refBoxL1.get(), pathOut+"/geo/refBoxL1", WbWriterVtkXmlASCII::getInstance()); + RefineCrossAndInsideGbObjectBlockVisitor refVisitorBoxL1(refBoxL1, level); + grid->accept(refVisitorBoxL1); } //level 2 level = 2; if (refineLevel - level >= 0) { - SPtr<GbObject3D> refCylinderL3(new GbCylinder3D(15.0, 0.0, 0.0, 15.0, 100.0, 0.0, 30.0)); - GbSystem3D::writeGeoObject(refCylinderL3.get(), pathOut + "/geo/refCylinderL3", WbWriterVtkXmlBinary::getInstance()); - RefineCrossAndInsideGbObjectBlockVisitor refVisitorCylinderL3(refCylinderL3, level); - grid->accept(refVisitorCylinderL3); + //SPtr<GbObject3D> refCylinderL2(new GbCylinder3D(0.015, -0.03, 0.0, 0.015, 0.06, 0.0, 0.03)); + //GbSystem3D::writeGeoObject(refCylinderL2.get(), pathOut + "/geo/refCylinderL2", WbWriterVtkXmlBinary::getInstance()); + //RefineCrossAndInsideGbObjectBlockVisitor refVisitorCylinderL2(refCylinderL2, level); + //grid->accept(refVisitorCylinderL2); - SPtr<GbObject3D> refBoxL3(new GbCuboid3D(15.0, 0.0, -30.0, 700.0, 100.0, 30.0)); - if (myid==0) GbSystem3D::writeGeoObject(refBoxL3.get(), pathOut+"/geo/refBoxL3", WbWriterVtkXmlASCII::getInstance()); - RefineCrossAndInsideGbObjectBlockVisitor refVisitorBoxL3(refBoxL3, level); - grid->accept(refVisitorBoxL3); + SPtr<GbObject3D> refBoxL2(new GbCuboid3D(0.15, -0.03, -0.015, 0.7, 0.06, 0.015)); + if (myid==0) GbSystem3D::writeGeoObject(refBoxL2.get(), pathOut+"/geo/refBoxL2", WbWriterVtkXmlASCII::getInstance()); + RefineCrossAndInsideGbObjectBlockVisitor refVisitorBoxL2(refBoxL2, level); + grid->accept(refVisitorBoxL2); + + //dynamicPointerCast<D3Q27TriFaceMeshInteractor>(fngIntrWhole)->refineBlockGridToLevel(level, startDistance, 0.01); } //level 3 level = 3; if (refineLevel - level >= 0) { - SPtr<GbObject3D> refCylinderL4(new GbCylinder3D(15.0, 0.0, 0.0, 15.0, 100.0, 0.0, 25.0)); - GbSystem3D::writeGeoObject(refCylinderL4.get(), pathOut + "/geo/refCylinderL4", WbWriterVtkXmlBinary::getInstance()); - RefineCrossAndInsideGbObjectBlockVisitor refVisitorCylinderL4(refCylinderL4, level); - grid->accept(refVisitorCylinderL4); + //SPtr<GbObject3D> refCylinderL3(new GbCylinder3D(0.015, -0.03, 0.0, 0.015, 0.06, 0.0, 0.025)); + //GbSystem3D::writeGeoObject(refCylinderL3.get(), pathOut + "/geo/refCylinderL3", WbWriterVtkXmlBinary::getInstance()); + //RefineCrossAndInsideGbObjectBlockVisitor refVisitorCylinderL3(refCylinderL3, level); + //grid->accept(refVisitorCylinderL3); - SPtr<GbObject3D> refBoxL4(new GbCuboid3D(15.0, 0.0, -25.0, 400.0, 100.0, 25.0)); - if (myid==0) GbSystem3D::writeGeoObject(refBoxL4.get(), pathOut+"/geo/refBoxL4", WbWriterVtkXmlASCII::getInstance()); - RefineCrossAndInsideGbObjectBlockVisitor refVisitorBoxL4(refBoxL4, level); - grid->accept(refVisitorBoxL4); + SPtr<GbObject3D> refBoxL3(new GbCuboid3D(0.15, -0.03, -0.010, 0.4, 0.06, 0.012)); + if (myid==0) GbSystem3D::writeGeoObject(refBoxL3.get(), pathOut+"/geo/refBoxL3", WbWriterVtkXmlASCII::getInstance()); + RefineCrossAndInsideGbObjectBlockVisitor refVisitorBoxL3(refBoxL3, level); + grid->accept(refVisitorBoxL3); + + //dynamicPointerCast<D3Q27TriFaceMeshInteractor>(fngIntrWhole)->refineBlockGridToLevel(level, startDistance, 0.005); } //level 4 level = 4; if (refineLevel - level >= 0) { - SPtr<GbObject3D> refBoxL5(new GbCuboid3D(120.0, 0.0, -9.0, 320.0, 100.0, 18.0)); - if (myid==0) GbSystem3D::writeGeoObject(refBoxL5.get(), pathOut+"/geo/refBoxL5", WbWriterVtkXmlASCII::getInstance()); - RefineCrossAndInsideGbObjectBlockVisitor refVisitorBoxL5(refBoxL5, level); - grid->accept(refVisitorBoxL5); - } + SPtr<GbObject3D> refBoxL4(new GbCuboid3D(0.15, -0.03, -0.005, 0.32, 0.06, 0.01)); + if (myid==0) GbSystem3D::writeGeoObject(refBoxL4.get(), pathOut+"/geo/refBoxL4", WbWriterVtkXmlASCII::getInstance()); + RefineCrossAndInsideGbObjectBlockVisitor refVisitorBoxL4(refBoxL4, level); + grid->accept(refVisitorBoxL4); - //level 5 - level = 5; - if (refineLevel - level >= 0) - { - dynamicPointerCast<D3Q27TriFaceMeshInteractor>(fngIntrWhole)->refineBlockGridToLevel(refineLevel, startDistance, refineDistance); + //dynamicPointerCast<D3Q27TriFaceMeshInteractor>(fngIntrWhole)->refineBlockGridToLevel(level, startDistance, 0.0016); } - grid->setRank(rank); - { - WriteBlocksCoProcessor ppblocks(grid, SPtr<UbScheduler>(new UbScheduler(1)), pathOut, WbWriterVtkXmlBinary::getInstance(), comm); - ppblocks.process(0); - } + + ////level 5 + //level = 5; + //if (refineLevel - level >= 0) + //{ + // dynamicPointerCast<D3Q27TriFaceMeshInteractor>(fngIntrWhole)->refineBlockGridToLevel(level, startDistance, refineDistance); + //} + + dynamicPointerCast<D3Q27TriFaceMeshInteractor>(fngIntrWhole)->refineBlockGridToLevel(refineLevel, startDistance, refineDistance); + // /////delete solid blocks if (myid==0) UBLOG(logINFO, "deleteSolidBlocks - start"); @@ -328,18 +337,41 @@ void run(string configname) fngIntrWhole->removeSolidBlocks(); fngIntrWhole->removeBcBlocks(); + //SPtr<GbObject3D> delBox(new GbCuboid3D(0.03, -0.03, -0.010, 0.2, 0.06, 0.012)); + //if (myid==0) GbSystem3D::writeGeoObject(delBox.get(), pathOut+"/geo/delBox", WbWriterVtkXmlASCII::getInstance()); + //SPtr<D3Q27Interactor> delBoxInter(new D3Q27Interactor(delBox, grid, noSlipBCAdapter, Interactor3D::SOLID)); + //SetSolidBlockVisitor v(delBoxInter, BlockType::SOLID); + //grid->accept(v); + //std::vector<SPtr<Block3D>>& sb = delBoxInter->getSolidBlockSet(); + //for (SPtr<Block3D> block : sb) + //{ + // grid->deleteBlock(block); + //} + //delBoxInter->removeSolidBlocks(); + //delBoxInter->removeBcBlocks(); + if (myid==0) UBLOG(logINFO, "deleteSolidBlocks - end"); - ////////////////////////////////////// + //////////////////////////////////////// + { + WriteBlocksCoProcessor ppblocks(grid, SPtr<UbScheduler>(new UbScheduler(1)), pathOut, WbWriterVtkXmlBinary::getInstance(), comm); + ppblocks.process(0); + } + + grid->setRank(rank); RatioBlockVisitor ratioVisitor(refineLevel); CheckRatioBlockVisitor checkRatio(refineLevel); int count = 0; do { + if (myid==0) UBLOG(logINFO, "ratioVisitor - strat"); grid->accept(ratioVisitor); + if (myid==0) UBLOG(logINFO, "ratioVisitor - end"); + if (myid==0) UBLOG(logINFO, "checkRatio - strat"); checkRatio.resetState(); grid->accept(checkRatio); + if (myid==0) UBLOG(logINFO, "checkRatio - end"); if (myid==0) UBLOG(logINFO, "count = "<<count++<<" state = "<<checkRatio.getState()); } while (!checkRatio.getState()); @@ -442,6 +474,7 @@ void run(string configname) UBLOG(logINFO, "Available memory per process = "<<availMem<<" bytes"); } + restartCoProcessor->writeBlocks(0); SetKernelBlockVisitor kernelVisitor(kernel, nuLB, availMem, needMem); grid->accept(kernelVisitor); @@ -512,30 +545,25 @@ void run(string configname) ////sponge layer //////////////////////////////////////////////////////////////////////////// - GbCuboid3DPtr spongeLayerX1max(new GbCuboid3D(g_maxX1-8.0*blockLength, g_minX2-blockLength, g_minX3-blockLength, g_maxX1+blockLength, g_maxX2+blockLength, g_maxX3+blockLength)); + GbCuboid3DPtr spongeLayerX1max(new GbCuboid3D(g_maxX1-0.7, g_minX2-blockLength, g_minX3-blockLength, g_maxX1, g_maxX2+blockLength, g_maxX3+blockLength)); if (myid==0) GbSystem3D::writeGeoObject(spongeLayerX1max.get(), pathOut+"/geo/spongeLayerX1max", WbWriterVtkXmlASCII::getInstance()); - SpongeLayerBlockVisitor slVisitorX1max; - slVisitorX1max.setBoundingBox(spongeLayerX1max); - SPtr<LBMKernel> spKernel = SPtr<LBMKernel>(new CompressibleCumulantLBMKernel()); - dynamicPointerCast<CompressibleCumulantLBMKernel>(spKernel)->setRelaxationParameter(CompressibleCumulantLBMKernel::NORMAL); - spKernel->setBCProcessor(bcProc); - slVisitorX1max.setKernel(spKernel); + SpongeLayerBlockVisitor slVisitorX1max(spongeLayerX1max, spKernel, D3Q27System::E); grid->accept(slVisitorX1max); - //GbCuboid3DPtr spongeLayerX1min(new GbCuboid3D(g_minX1-blockLength, g_minX2-blockLength, g_minX3-blockLength, g_minX1+75, g_maxX2+blockLength, g_maxX3+blockLength)); - //if (myid==0) GbSystem3D::writeGeoObject(spongeLayerX1min.get(), pathOut+"/geo/spongeLayerX1min", WbWriterVtkXmlASCII::getInstance()); - //SpongeLayerBlockVisitor slVisitorX1min(spongeLayerX1min); - //grid->accept(slVisitorX1min); + GbCuboid3DPtr spongeLayerX1min(new GbCuboid3D(g_minX1-blockLength, g_minX2-blockLength, g_minX3-blockLength, g_minX1+0.25, g_maxX2+blockLength, g_maxX3+blockLength)); + if (myid==0) GbSystem3D::writeGeoObject(spongeLayerX1min.get(), pathOut+"/geo/spongeLayerX1min", WbWriterVtkXmlASCII::getInstance()); + SpongeLayerBlockVisitor slVisitorX1min(spongeLayerX1min, spKernel,D3Q27System::W); + grid->accept(slVisitorX1min); - //GbCuboid3DPtr spongeLayerX3min(new GbCuboid3D(g_minX1-blockLength, g_minX2-blockLength, g_minX3-blockLength, g_maxX1+blockLength, g_maxX2+blockLength, g_minX3+75)); - //if (myid==0) GbSystem3D::writeGeoObject(spongeLayerX3min.get(), pathOut+"/geo/spongeLayerX3min", WbWriterVtkXmlASCII::getInstance()); - //SpongeLayerBlockVisitor slVisitorX3min(spongeLayerX3min); - //grid->accept(slVisitorX3min); + GbCuboid3DPtr spongeLayerX3min(new GbCuboid3D(g_minX1+0.25, g_minX2-blockLength, g_minX3-blockLength, g_maxX1-0.7, g_maxX2+blockLength, g_minX3+0.25)); + if (myid==0) GbSystem3D::writeGeoObject(spongeLayerX3min.get(), pathOut+"/geo/spongeLayerX3min", WbWriterVtkXmlASCII::getInstance()); + SpongeLayerBlockVisitor slVisitorX3min(spongeLayerX3min, spKernel, D3Q27System::B); + grid->accept(slVisitorX3min); - //GbCuboid3DPtr spongeLayerX3max(new GbCuboid3D(g_minX1-blockLength, g_minX2-blockLength, g_maxX3-75, g_maxX1+blockLength, g_maxX2+blockLength, g_maxX3+blockLength)); - //if (myid==0) GbSystem3D::writeGeoObject(spongeLayerX3max.get(), pathOut+"/geo/spongeLayerX3max", WbWriterVtkXmlASCII::getInstance()); - //SpongeLayerBlockVisitor slVisitorX3max(spongeLayerX3max); - //grid->accept(slVisitorX3max); + GbCuboid3DPtr spongeLayerX3max(new GbCuboid3D(g_minX1+0.25, g_minX2-blockLength, g_maxX3-0.25, g_maxX1-0.7, g_maxX2+blockLength, g_maxX3+blockLength)); + if (myid==0) GbSystem3D::writeGeoObject(spongeLayerX3max.get(), pathOut+"/geo/spongeLayerX3max", WbWriterVtkXmlASCII::getInstance()); + SpongeLayerBlockVisitor slVisitorX3max(spongeLayerX3max, spKernel, D3Q27System::T); + grid->accept(slVisitorX3max); ///////////////////////////////////////////////////////////////////////////// if (myid==0) UBLOG(logINFO, "Preprozess - end"); @@ -554,14 +582,9 @@ void run(string configname) ////sponge layer //////////////////////////////////////////////////////////////////////////// - GbCuboid3DPtr spongeLayerX1max(new GbCuboid3D(g_maxX1-8.0*blockLength, g_minX2-blockLength, g_minX3-blockLength, g_maxX1+blockLength, g_maxX2+blockLength, g_maxX3+blockLength)); + GbCuboid3DPtr spongeLayerX1max(new GbCuboid3D(g_maxX1-0.7, g_minX2-blockLength, g_minX3-blockLength, g_maxX1+blockLength, g_maxX2+blockLength, g_maxX3+blockLength)); if (myid==0) GbSystem3D::writeGeoObject(spongeLayerX1max.get(), pathOut+"/geo/spongeLayerX1max", WbWriterVtkXmlASCII::getInstance()); - SpongeLayerBlockVisitor slVisitorX1max; - slVisitorX1max.setBoundingBox(spongeLayerX1max); - SPtr<LBMKernel> spKernel = SPtr<LBMKernel>(new CompressibleCumulantLBMKernel()); - dynamicPointerCast<CompressibleCumulantLBMKernel>(spKernel)->setRelaxationParameter(CompressibleCumulantLBMKernel::NORMAL); - spKernel->setBCProcessor(bcProc); - slVisitorX1max.setKernel(spKernel); + SpongeLayerBlockVisitor slVisitorX1max(spongeLayerX1max, spKernel, D3Q27System::E); grid->accept(slVisitorX1max); } @@ -578,6 +601,10 @@ void run(string configname) SPtr<WriteMacroscopicQuantitiesCoProcessor> writeMQCoProcessor(new WriteMacroscopicQuantitiesCoProcessor(grid, stepSch, pathOut, WbWriterVtkXmlBinary::getInstance(), conv, comm)); + SPtr<GbObject3D> bbBox(new GbCuboid3D(g_minX1-blockLength, (g_maxX2-g_minX2)/2.0, g_minX3-blockLength, g_maxX1+blockLength, (g_maxX2-g_minX2)/2.0+deltaXfine, g_maxX3+blockLength)); + if (myid==0) GbSystem3D::writeGeoObject(bbBox.get(), pathOut+"/geo/bbBox", WbWriterVtkXmlASCII::getInstance()); + SPtr<WriteMQFromSelectionCoProcessor> writeMQSelectCoProcessor(new WriteMQFromSelectionCoProcessor(grid, stepSch, bbBox, pathOut, WbWriterVtkXmlBinary::getInstance(), conv, comm)); + SPtr<UbScheduler> tavSch(new UbScheduler(1, timeAvStart, timeAvStop)); SPtr<TimeAveragedValuesCoProcessor> tav(new TimeAveragedValuesCoProcessor(grid, pathOut, WbWriterVtkXmlBinary::getInstance(), tavSch, comm, TimeAveragedValuesCoProcessor::Density | TimeAveragedValuesCoProcessor::Velocity | TimeAveragedValuesCoProcessor::Fluctuations)); @@ -589,11 +616,12 @@ void run(string configname) //TimeseriesCoProcessor tsp1(grid, stepMV, mic1, pathOut+"/mic/mic1", comm); omp_set_num_threads(numOfThreads); - SPtr<Calculator> calculator(new BasicCalculator(grid, tavSch, endTime)); + SPtr<Calculator> calculator(new BasicCalculator(grid, stepSch, endTime)); calculator->addCoProcessor(nupsCoProcessor); calculator->addCoProcessor(restartCoProcessor); + calculator->addCoProcessor(writeMQSelectCoProcessor); calculator->addCoProcessor(writeMQCoProcessor); - calculator->addCoProcessor(tav); + //calculator->addCoProcessor(tav); if (myid==0) UBLOG(logINFO, "Simulation-start"); @@ -621,96 +649,96 @@ void run(string configname) } -void test_run() -{ - try - { - - SPtr<Communicator> comm = MPICommunicator::getInstance(); - int myid = comm->getProcessID(); - - if (myid==0) - { - UBLOG(logINFO, "PID = "<<myid<<" Point 1"); - UBLOG(logINFO, "PID = "<<myid<<" Total Physical Memory (RAM): "<<Utilities::getTotalPhysMem()); - UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used: "<<Utilities::getPhysMemUsed()); - UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); - } - - double g_minX1 = 0; - double g_minX2 = 0; - double g_minX3 = 0; - - double g_maxX1 = 5; - double g_maxX2 = 5; - double g_maxX3 = 5; - - int blockNx[3] ={ 5, 5, 5 }; - - string pathOut = "d:/temp/DLR-F16-Solid-test"; - - double deltaX = 1; - double rhoLB = 0.0; - double uLB = 0.0866025; - double nuLB = 0.001; //4.33013e-06; - SPtr<LBMUnitConverter> conv = SPtr<LBMUnitConverter>(new LBMUnitConverter()); - //////////////////////////////////////////////////////////////////////// - //Grid - ////////////////////////////////////////////////////////////////////////// - SPtr<Grid3D> grid(new Grid3D(comm)); - grid->setDeltaX(deltaX); - grid->setBlockNX(blockNx[0], blockNx[1], blockNx[2]); - grid->setPeriodicX1(false); - grid->setPeriodicX2(false); - grid->setPeriodicX3(false); - - SPtr<GbObject3D> gridCube(new GbCuboid3D(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3)); - if (myid==0) GbSystem3D::writeGeoObject(gridCube.get(), pathOut+"/geo/gridCube", WbWriterVtkXmlASCII::getInstance()); - GenBlocksGridVisitor genBlocks(gridCube); - grid->accept(genBlocks); - - WriteBlocksCoProcessor ppblocks(grid, SPtr<UbScheduler>(new UbScheduler(1)), pathOut, WbWriterVtkXmlBinary::getInstance(), comm); - ppblocks.process(0); - - SPtr<LBMKernel> kernel = SPtr<LBMKernel>(new CompressibleCumulant4thOrderViscosityLBMKernel()); - kernel->setNX(std::array<int, 3>{ {blockNx[0], blockNx[1], blockNx[2]}}); - SPtr<BCProcessor> bcProc; - bcProc = SPtr<BCProcessor>(new BCProcessor()); - kernel->setBCProcessor(bcProc); - - SetKernelBlockVisitor kernelVisitor(kernel, nuLB, 1e9, 12); - grid->accept(kernelVisitor); - - //initialization of distributions - InitDistributionsBlockVisitor initVisitor1; - initVisitor1.setVx1(0.001); - grid->accept(initVisitor1); - - SPtr<UbScheduler> stepSch(new UbScheduler(1)); - SPtr<WriteMacroscopicQuantitiesCoProcessor> writeMQCoProcessor(new WriteMacroscopicQuantitiesCoProcessor(grid, stepSch, pathOut, WbWriterVtkXmlBinary::getInstance(), conv, comm)); - - //omp_set_num_threads(numOfThreads); - SPtr<Calculator> calculator(new BasicCalculator(grid, stepSch, 2)); - calculator->addCoProcessor(writeMQCoProcessor); - - - if (myid==0) UBLOG(logINFO, "Simulation-start"); - calculator->calculate(); - if (myid==0) UBLOG(logINFO, "Simulation-end"); - } - catch (std::exception& e) - { - cerr<<e.what()<<endl<<flush; - } - catch (std::string& s) - { - cerr<<s<<endl; - } - catch (...) - { - cerr<<"unknown exception"<<endl; - } -} +//void test_run() +//{ +// try +// { +// +// SPtr<Communicator> comm = MPICommunicator::getInstance(); +// int myid = comm->getProcessID(); +// +// if (myid==0) +// { +// UBLOG(logINFO, "PID = "<<myid<<" Point 1"); +// UBLOG(logINFO, "PID = "<<myid<<" Total Physical Memory (RAM): "<<Utilities::getTotalPhysMem()); +// UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used: "<<Utilities::getPhysMemUsed()); +// UBLOG(logINFO, "PID = "<<myid<<" Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); +// } +// +// double g_minX1 = 0; +// double g_minX2 = 0; +// double g_minX3 = 0; +// +// double g_maxX1 = 5; +// double g_maxX2 = 5; +// double g_maxX3 = 5; +// +// int blockNx[3] ={ 5, 5, 5 }; +// +// string pathOut = "d:/temp/DLR-F16-Solid-test"; +// +// double deltaX = 1; +// double rhoLB = 0.0; +// double uLB = 0.0866025; +// double nuLB = 0.001; //4.33013e-06; +// SPtr<LBMUnitConverter> conv = SPtr<LBMUnitConverter>(new LBMUnitConverter()); +// //////////////////////////////////////////////////////////////////////// +// //Grid +// ////////////////////////////////////////////////////////////////////////// +// SPtr<Grid3D> grid(new Grid3D(comm)); +// grid->setDeltaX(deltaX); +// grid->setBlockNX(blockNx[0], blockNx[1], blockNx[2]); +// grid->setPeriodicX1(false); +// grid->setPeriodicX2(false); +// grid->setPeriodicX3(false); +// +// SPtr<GbObject3D> gridCube(new GbCuboid3D(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3)); +// if (myid==0) GbSystem3D::writeGeoObject(gridCube.get(), pathOut+"/geo/gridCube", WbWriterVtkXmlASCII::getInstance()); +// GenBlocksGridVisitor genBlocks(gridCube); +// grid->accept(genBlocks); +// +// WriteBlocksCoProcessor ppblocks(grid, SPtr<UbScheduler>(new UbScheduler(1)), pathOut, WbWriterVtkXmlBinary::getInstance(), comm); +// ppblocks.process(0); +// +// SPtr<LBMKernel> kernel = SPtr<LBMKernel>(new CompressibleCumulant4thOrderViscosityLBMKernel()); +// kernel->setNX(std::array<int, 3>{ {blockNx[0], blockNx[1], blockNx[2]}}); +// SPtr<BCProcessor> bcProc; +// bcProc = SPtr<BCProcessor>(new BCProcessor()); +// kernel->setBCProcessor(bcProc); +// +// SetKernelBlockVisitor kernelVisitor(kernel, nuLB, 1e9, 12); +// grid->accept(kernelVisitor); +// +// //initialization of distributions +// InitDistributionsBlockVisitor initVisitor1; +// initVisitor1.setVx1(0.001); +// grid->accept(initVisitor1); +// +// SPtr<UbScheduler> stepSch(new UbScheduler(1)); +// SPtr<WriteMacroscopicQuantitiesCoProcessor> writeMQCoProcessor(new WriteMacroscopicQuantitiesCoProcessor(grid, stepSch, pathOut, WbWriterVtkXmlBinary::getInstance(), conv, comm)); +// +// //omp_set_num_threads(numOfThreads); +// SPtr<Calculator> calculator(new BasicCalculator(grid, stepSch, 2)); +// calculator->addCoProcessor(writeMQCoProcessor); +// +// +// if (myid==0) UBLOG(logINFO, "Simulation-start"); +// calculator->calculate(); +// if (myid==0) UBLOG(logINFO, "Simulation-end"); +// } +// catch (std::exception& e) +// { +// cerr<<e.what()<<endl<<flush; +// } +// catch (std::string& s) +// { +// cerr<<s<<endl; +// } +// catch (...) +// { +// cerr<<"unknown exception"<<endl; +// } +//} int main(int argc, char* argv[]) { diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index b3618d463..994e2c6ae 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -33,11 +33,11 @@ SET(USE_METIS ON CACHE BOOL "include METIS library support") SET(USE_MPI ON CACHE BOOL "include MPI library support") SET(USE_VTK OFF CACHE BOOL "include VTK library support") SET(USE_CATALYST OFF CACHE BOOL "include Paraview Catalyst support") -SET(USE_BOOST OFF CACHE BOOL "include Paraview Catalyst support") +SET(USE_BOOST OFF CACHE BOOL "include Boost support") #SET(USE_PYTHON OFF CACHE BOOL "include Python scripting support") #SET(USE_FETOL OFF CACHE BOOL "include FETOL library support") SET(USE_INTEL OFF CACHE BOOL "include Intel compiler support") -#SET(USE_GCC OFF CACHE BOOL "include gcc compiler support") +SET(USE_GCC OFF CACHE BOOL "include gcc compiler support") SET(USE_HLRN_LUSTRE OFF CACHE BOOL "include HLRN Lustre support") #CAB @@ -118,14 +118,19 @@ IF(${USE_BOOST}) LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DVF_BOOST) ENDIF() +IF(${USE_HLRN_LUSTRE}) + LIST(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DHLRN_LUSTRE) +ENDIF() + IF(${USE_INTEL}) SET(CAB_ADDITIONAL_LINK_FLAGS ${CAB_ADDITIONAL_LINK_FLAGS} -parallel) ENDIF() -IF(${USE_HLRN_LUSTRE}) - SET(APPEND CAB_ADDTIONAL_COMPILER_FLAGS -DHLRN_LUSTRE) +IF(${USE_GCC}) + SET(CAB_ADDITIONAL_LINK_FLAGS ${CAB_ADDITIONAL_LINK_FLAGS} -lgomp) ENDIF() + # IF(${USE_PYTHON}) # FIND_PACKAGE(PythonLibs) # INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIR}) diff --git a/source/VirtualFluids.h b/source/VirtualFluids.h index 09701541e..42e746115 100644 --- a/source/VirtualFluids.h +++ b/source/VirtualFluids.h @@ -145,6 +145,7 @@ #include <CoProcessors/AdjustForcingCoProcessor.h> #include <CoProcessors/CalculateForcesCoProcessor.h> #include <CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h> +#include <CoProcessors/WriteMQFromSelectionCoProcessor.h> #include <CoProcessors/WriteBoundaryConditionsCoProcessor.h> //#include <CoProcessors/PathLineCoProcessor.h> //#include <CoProcessors/PathLineCoProcessorMcpart.h> diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIOMigrationCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/MPIIOMigrationCoProcessor.cpp index 7a540fac0..1a2b427bb 100644 --- a/source/VirtualFluidsCore/CoProcessors/MPIIOMigrationCoProcessor.cpp +++ b/source/VirtualFluidsCore/CoProcessors/MPIIOMigrationCoProcessor.cpp @@ -24,14 +24,12 @@ MPIIOMigrationCoProcessor::MPIIOMigrationCoProcessor(SPtr<Grid3D> grid, SPtr<UbS SPtr<Communicator> comm) : CoProcessor(grid, s), path(path), - comm(comm), - mpiTypeFreeFlag(false) + comm(comm) { - UbSystem::makeDirectory(path+"/mpi_io_cp"); + UbSystem::makeDirectory(path + "/mpi_io_cp"); - memset(&dataSetParamStr, 0, sizeof(dataSetParamStr)); memset(&boundCondParamStr, 0, sizeof(boundCondParamStr)); - + //------------------------- define MPI types --------------------------------- MPI_Datatype typesGP[3] = { MPI_DOUBLE, MPI_INT, MPI_CHAR }; @@ -40,50 +38,55 @@ MPIIOMigrationCoProcessor::MPIIOMigrationCoProcessor(SPtr<Grid3D> grid, SPtr<UbS offsetsGP[0] = 0; MPI_Type_get_extent(MPI_DOUBLE, &lbGP, &extentGP); - offsetsGP[1] = blocksGP[0]*extentGP; + offsetsGP[1] = blocksGP[0] * extentGP; MPI_Type_get_extent(MPI_INT, &lbGP, &extentGP); - offsetsGP[2] = offsetsGP[1]+blocksGP[1]*extentGP; + offsetsGP[2] = offsetsGP[1] + blocksGP[1] * extentGP; MPI_Type_create_struct(3, blocksGP, offsetsGP, typesGP, &gridParamType); MPI_Type_commit(&gridParamType); //----------------------------------------------------------------------- - MPI_Type_contiguous(40, MPI_INT, &dataSetParamType); - MPI_Type_commit(&dataSetParamType); - - //----------------------------------------------------------------------- - MPI_Datatype typesBlock[2] = { MPI_INT, MPI_CHAR }; int blocksBlock[2] = { 13, 1 }; MPI_Aint offsetsBlock[2], lbBlock, extentBlock; offsetsBlock[0] = 0; MPI_Type_get_extent(MPI_INT, &lbBlock, &extentBlock); - offsetsBlock[1] = blocksBlock[0]*extentBlock; + offsetsBlock[1] = blocksBlock[0] * extentBlock; MPI_Type_create_struct(2, blocksBlock, offsetsBlock, typesBlock, &block3dType); MPI_Type_commit(&block3dType); //----------------------------------------------------------------------- + MPI_Type_contiguous(7, MPI_INT, &dataSetParamType); + MPI_Type_commit(&dataSetParamType); + + //----------------------------------------------------------------------- + MPI_Datatype typesDataSet[3] = { MPI_DOUBLE, MPI_INT, MPI_CHAR }; int blocksDataSet[3] = { 2, 2, 2 }; MPI_Aint offsetsDatatSet[3], lbDataSet, extentDataSet; offsetsDatatSet[0] = 0; MPI_Type_get_extent(MPI_DOUBLE, &lbDataSet, &extentDataSet); - offsetsDatatSet[1] = blocksDataSet[0]*extentDataSet; + offsetsDatatSet[1] = blocksDataSet[0] * extentDataSet; MPI_Type_get_extent(MPI_INT, &lbDataSet, &extentDataSet); - offsetsDatatSet[2] = offsetsDatatSet[1]+blocksDataSet[1]*extentDataSet; + offsetsDatatSet[2] = offsetsDatatSet[1] + blocksDataSet[1] * extentDataSet; MPI_Type_create_struct(3, blocksDataSet, offsetsDatatSet, typesDataSet, &dataSetType); MPI_Type_commit(&dataSetType); //----------------------------------------------------------------------- + MPI_Type_contiguous(1, MPI_INT, &dataSetSmallType); + MPI_Type_commit(&dataSetSmallType); + + //----------------------------------------------------------------------- + MPI_Type_contiguous(4, MPI_INT, &boundCondParamType); MPI_Type_commit(&boundCondParamType); @@ -95,10 +98,10 @@ MPIIOMigrationCoProcessor::MPIIOMigrationCoProcessor(SPtr<Grid3D> grid, SPtr<UbS offsetsBC[0] = 0; MPI_Type_get_extent(MPI_LONG_LONG_INT, &lbBC, &extentBC); - offsetsBC[1] = blocksBC[0]*extentBC; + offsetsBC[1] = blocksBC[0] * extentBC; MPI_Type_get_extent(MPI_FLOAT, &lbBC, &extentBC); - offsetsBC[2] = offsetsBC[1]+blocksBC[1]*extentBC; + offsetsBC[2] = offsetsBC[1] + blocksBC[1] * extentBC; MPI_Type_create_struct(3, blocksBC, offsetsBC, typesBC, &boundCondType); MPI_Type_commit(&boundCondType); @@ -107,6 +110,10 @@ MPIIOMigrationCoProcessor::MPIIOMigrationCoProcessor(SPtr<Grid3D> grid, SPtr<UbS MPI_Type_contiguous(3, MPI_INT, &boundCondTypeAdd); MPI_Type_commit(&boundCondTypeAdd); + //--------------------------------------- + + MPI_Type_contiguous(6, MPI_CHAR, &arrayPresenceType); + MPI_Type_commit(&arrayPresenceType); } ////////////////////////////////////////////////////////////////////////// @@ -116,15 +123,11 @@ MPIIOMigrationCoProcessor::~MPIIOMigrationCoProcessor() MPI_Type_free(&dataSetParamType); MPI_Type_free(&block3dType); MPI_Type_free(&dataSetType); + MPI_Type_free(&dataSetSmallType); MPI_Type_free(&boundCondParamType); MPI_Type_free(&boundCondType); MPI_Type_free(&boundCondTypeAdd); - - if (mpiTypeFreeFlag) - { - MPI_Type_free(&dataSetDoubleType); - MPI_Type_free(&bcindexmatrixType); - } + MPI_Type_free(&arrayPresenceType); } ////////////////////////////////////////////////////////////////////////// @@ -132,46 +135,91 @@ void MPIIOMigrationCoProcessor::process(double step) { if (scheduler->isDue(step)) { - if (comm->isRoot()) UBLOG(logINFO, "MPIIOMigrationCoProcessor save step: "<<step); + if (comm->isRoot()) UBLOG(logINFO, "MPIIOMigrationCoProcessor save step: " << step); if (comm->isRoot()) UBLOG(logINFO, "Save check point - start"); /*if (comm->isRoot())*/ clearAllFiles((int)step); + writeBlocks((int)step); writeDataSet((int)step); writeBoundaryConds((int)step); + if (comm->isRoot()) UBLOG(logINFO, "Save check point - end"); } } -////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// void MPIIOMigrationCoProcessor::clearAllFiles(int step) { - MPI_File file_handler1, file_handler2, file_handler3; + MPI_File file_handler; MPI_Info info = MPI_INFO_NULL; MPI_Offset new_size = 0; UbSystem::makeDirectory(path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step)); + std::string filename1 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin"; - //MPI_File_delete(filename1.c_str(), info); - int rc1 = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler1); + int rc1 = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler); if (rc1 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename1); - MPI_File_set_size(file_handler1, new_size); - //MPI_File_sync(file_handler1); - MPI_File_close(&file_handler1); + MPI_File_set_size(file_handler, new_size); + MPI_File_close(&file_handler); std::string filename2 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin"; - //MPI_File_delete(filename2.c_str(), info); - int rc2 = MPI_File_open(MPI_COMM_WORLD, filename2.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler2); + int rc2 = MPI_File_open(MPI_COMM_WORLD, filename2.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); if (rc2 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename2); - MPI_File_set_size(file_handler2, new_size); - //MPI_File_sync(file_handler2); - MPI_File_close(&file_handler2); + MPI_File_set_size(file_handler, new_size); + MPI_File_close(&file_handler); - std::string filename3 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin"; - //MPI_File_delete(filename3.c_str(), info); - int rc3 = MPI_File_open(MPI_COMM_WORLD, filename3.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler3); + std::string filename3 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpArrays.bin"; + int rc3 = MPI_File_open(MPI_COMM_WORLD, filename3.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); if (rc3 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename3); - MPI_File_set_size(file_handler3, new_size); - //MPI_File_sync(file_handler3); - MPI_File_close(&file_handler3); + MPI_File_set_size(file_handler, new_size); + MPI_File_close(&file_handler); + + std::string filename4 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageDensityArray.bin"; + MPI_File_delete(filename4.c_str(), info); + //int rc4 = MPI_File_open(MPI_COMM_WORLD, filename4.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc4 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename4); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename5 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageVelocityArray.bin"; + MPI_File_delete(filename5.c_str(), info); + //int rc5 = MPI_File_open(MPI_COMM_WORLD, filename5.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc5 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename5); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename6 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageFluktuationsArray.bin"; + MPI_File_delete(filename6.c_str(), info); + //int rc6 = MPI_File_open(MPI_COMM_WORLD, filename6.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc6 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename6); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename7 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageTripleArray.bin"; + MPI_File_delete(filename7.c_str(), info); + //int rc7 = MPI_File_open(MPI_COMM_WORLD, filename7.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc7 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename7); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename8 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpShearStressValArray.bin"; + MPI_File_delete(filename8.c_str(), info); + //int rc8 = MPI_File_open(MPI_COMM_WORLD, filename8.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc8 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename8); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename9 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpRelaxationFactor.bin"; + MPI_File_delete(filename9.c_str(), info); + //int rc9 = MPI_File_open(MPI_COMM_WORLD, filename9.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc9 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename9); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename10 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin"; + int rc10 = MPI_File_open(MPI_COMM_WORLD, filename10.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc10 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename10); + MPI_File_set_size(file_handler, new_size); + MPI_File_close(&file_handler); } ////////////////////////////////////////////////////////////////////////// void MPIIOMigrationCoProcessor::writeBlocks(int step) @@ -179,7 +227,7 @@ void MPIIOMigrationCoProcessor::writeBlocks(int step) int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); //MPI_Comm_size(MPI_COMM_WORLD, &size); - size=1; + size = 1; grid->deleteBlockIDs(); RenumberBlockVisitor renumber; @@ -187,8 +235,8 @@ void MPIIOMigrationCoProcessor::writeBlocks(int step) if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBlocks start collect data rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBlocks start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } int blocksCount = 0; // quantity of all the blocks in the grid, max 2147483648 blocks! @@ -196,7 +244,7 @@ void MPIIOMigrationCoProcessor::writeBlocks(int step) int maxInitLevel = this->grid->getFinestInitializedLevel(); std::vector<SPtr<Block3D>> blocksVector[25]; // max 25 levels - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { //grid->getBlocks(level, rank, blockVector[level]); grid->getBlocks(level, blocksVector[level]); @@ -259,9 +307,9 @@ void MPIIOMigrationCoProcessor::writeBlocks(int step) Block3d* block3dArray = new Block3d[blocksCount]; int ic = 0; - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { - for(SPtr<Block3D> block : blocksVector[level]) // all the blocks of the current level + for (SPtr<Block3D> block : blocksVector[level]) // all the blocks of the current level { // save data describing the block block3dArray[ic].x1 = block->getX1(); @@ -285,8 +333,8 @@ void MPIIOMigrationCoProcessor::writeBlocks(int step) if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBlocks start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBlocks start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } // write to the file @@ -299,33 +347,33 @@ void MPIIOMigrationCoProcessor::writeBlocks(int step) // if (comm->isRoot()) // { - UbSystem::makeDirectory(path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step)); - std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin"; - int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler); - if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + UbSystem::makeDirectory(path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step)); + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); // } double start, finish; - MPI_Offset write_offset = (MPI_Offset)(size*sizeof(int)); - + MPI_Offset write_offset = (MPI_Offset)(size * sizeof(int)); + if (comm->isRoot()) { start = MPI_Wtime(); - + // each process writes the quantity of it's blocks MPI_File_write_at(file_handler, 0/*rank*sizeof(int)*/, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); // each process writes parameters of the grid MPI_File_write_at(file_handler, write_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE); // each process writes it's blocks - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset +sizeof(GridParam)), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(GridParam)), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE); //MPI_File_sync(file_handler); } MPI_File_close(&file_handler); - + if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBlocks time: "<<finish-start<<" s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBlocks time: " << finish - start << " s"); } delete[] block3dArray; @@ -343,26 +391,29 @@ void MPIIOMigrationCoProcessor::writeDataSet(int step) std::vector<SPtr<Block3D>> blocksVector[25]; int minInitLevel = this->grid->getCoarsestInitializedLevel(); int maxInitLevel = this->grid->getFinestInitializedLevel(); - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { grid->getBlocks(level, rank, blocksVector[level]); blocksCount += static_cast<int>(blocksVector[level].size()); } + dataSetParam dataSetParamStr1, dataSetParamStr2, dataSetParamStr3; DataSet* dataSetArray = new DataSet[blocksCount]; std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeDataSet start collect data rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeDataSet start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } + DSArraysPresence arrPresence; bool firstBlock = true; + int doubleCountInBlock = 0; int ic = 0; - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { - for(SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level { dataSetArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid dataSetArray[ic].ghostLayerWidth = block->getKernel()->getGhostLayerWidth(); @@ -371,144 +422,89 @@ void MPIIOMigrationCoProcessor::writeDataSet(int step) dataSetArray[ic].compressible = block->getKernel()->getCompressible(); dataSetArray[ic].withForcing = block->getKernel()->getWithForcing(); + SPtr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions()); + CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions(); + CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions(); + CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions(); + if (firstBlock)// && block->getKernel()) // when first (any) valid block... { - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageValuesArray3D = block->getKernel()->getDataSet()->getAverageValues(); - if (averageValuesArray3D) - { - dataSetParamStr.nx[0][0] = static_cast<int>(averageValuesArray3D->getNX1()); - dataSetParamStr.nx[0][1] = static_cast<int>(averageValuesArray3D->getNX2()); - dataSetParamStr.nx[0][2] = static_cast<int>(averageValuesArray3D->getNX3()); - dataSetParamStr.nx[0][3] = static_cast<int>(averageValuesArray3D->getNX4()); - } - - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity(); - if (AverageVelocityArray3DPtr) - { - dataSetParamStr.nx[1][0] = static_cast<int>(AverageVelocityArray3DPtr->getNX1()); - dataSetParamStr.nx[1][1] = static_cast<int>(AverageVelocityArray3DPtr->getNX2()); - dataSetParamStr.nx[1][2] = static_cast<int>(AverageVelocityArray3DPtr->getNX3()); - dataSetParamStr.nx[1][3] = static_cast<int>(AverageVelocityArray3DPtr->getNX4()); - } - - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations(); - if (AverageFluctArray3DPtr) - { - dataSetParamStr.nx[2][0] = static_cast<int>(AverageFluctArray3DPtr->getNX1()); - dataSetParamStr.nx[2][1] = static_cast<int>(AverageFluctArray3DPtr->getNX2()); - dataSetParamStr.nx[2][2] = static_cast<int>(AverageFluctArray3DPtr->getNX3()); - dataSetParamStr.nx[2][3] = static_cast<int>(AverageFluctArray3DPtr->getNX4()); - } - - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations(); - if (AverageTripleArray3DPtr) - { - dataSetParamStr.nx[3][0] = static_cast<int>(AverageTripleArray3DPtr->getNX1()); - dataSetParamStr.nx[3][1] = static_cast<int>(AverageTripleArray3DPtr->getNX2()); - dataSetParamStr.nx[3][2] = static_cast<int>(AverageTripleArray3DPtr->getNX3()); - dataSetParamStr.nx[3][3] = static_cast<int>(AverageTripleArray3DPtr->getNX4()); - } - - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues(); - if (ShearStressValArray3DPtr) - { - dataSetParamStr.nx[4][0] = static_cast<int>(ShearStressValArray3DPtr->getNX1()); - dataSetParamStr.nx[4][1] = static_cast<int>(ShearStressValArray3DPtr->getNX2()); - dataSetParamStr.nx[4][2] = static_cast<int>(ShearStressValArray3DPtr->getNX3()); - dataSetParamStr.nx[4][3] = static_cast<int>(ShearStressValArray3DPtr->getNX4()); - } - - SPtr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor(); - if (relaxationFactor3DPtr) - { - dataSetParamStr.nx[5][0] = static_cast<int>(relaxationFactor3DPtr->getNX1()); - dataSetParamStr.nx[5][1] = static_cast<int>(relaxationFactor3DPtr->getNX2()); - dataSetParamStr.nx[5][2] = static_cast<int>(relaxationFactor3DPtr->getNX3()); - dataSetParamStr.nx[5][3] = 1; - } - - SPtr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions()); - CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions(); if (localDistributions) { - dataSetParamStr.nx[6][0] = static_cast<int>(localDistributions->getNX1()); - dataSetParamStr.nx[6][1] = static_cast<int>(localDistributions->getNX2()); - dataSetParamStr.nx[6][2] = static_cast<int>(localDistributions->getNX3()); - dataSetParamStr.nx[6][3] = static_cast<int>(localDistributions->getNX4()); + dataSetParamStr1.nx[0] = static_cast<int>(localDistributions->getNX1()); + dataSetParamStr1.nx[1] = static_cast<int>(localDistributions->getNX2()); + dataSetParamStr1.nx[2] = static_cast<int>(localDistributions->getNX3()); + dataSetParamStr1.nx[3] = static_cast<int>(localDistributions->getNX4()); } - CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions(); if (nonLocalDistributions) { - dataSetParamStr.nx[7][0] = static_cast<int>(nonLocalDistributions->getNX1()); - dataSetParamStr.nx[7][1] = static_cast<int>(nonLocalDistributions->getNX2()); - dataSetParamStr.nx[7][2] = static_cast<int>(nonLocalDistributions->getNX3()); - dataSetParamStr.nx[7][3] = static_cast<int>(nonLocalDistributions->getNX4()); + dataSetParamStr2.nx[0] = static_cast<int>(nonLocalDistributions->getNX1()); + dataSetParamStr2.nx[1] = static_cast<int>(nonLocalDistributions->getNX2()); + dataSetParamStr2.nx[2] = static_cast<int>(nonLocalDistributions->getNX3()); + dataSetParamStr2.nx[3] = static_cast<int>(nonLocalDistributions->getNX4()); } - - CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions(); if (zeroDistributions) { - dataSetParamStr.nx[8][0] = static_cast<int>(zeroDistributions->getNX1()); - dataSetParamStr.nx[8][1] = static_cast<int>(zeroDistributions->getNX2()); - dataSetParamStr.nx[8][2] = static_cast<int>(zeroDistributions->getNX3()); - dataSetParamStr.nx[8][3] = 1; + dataSetParamStr3.nx[0] = static_cast<int>(zeroDistributions->getNX1()); + dataSetParamStr3.nx[1] = static_cast<int>(zeroDistributions->getNX2()); + dataSetParamStr3.nx[2] = static_cast<int>(zeroDistributions->getNX3()); + dataSetParamStr3.nx[3] = 1; } // ... than save some parameters that are equal in all blocks - dataSetParamStr.nx1 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX1()); - dataSetParamStr.nx2 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX2()); - dataSetParamStr.nx3 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX3()); + dataSetParamStr1.nx1 = dataSetParamStr2.nx1 = dataSetParamStr3.nx1 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX1()); + dataSetParamStr1.nx2 = dataSetParamStr2.nx2 = dataSetParamStr3.nx2 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX2()); + dataSetParamStr1.nx3 = dataSetParamStr2.nx3 = dataSetParamStr3.nx3 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX3()); - firstBlock = false; + doubleCountInBlock = dataSetParamStr1.nx[0] * dataSetParamStr1.nx[1] * dataSetParamStr1.nx[2] * dataSetParamStr1.nx[3] + + dataSetParamStr2.nx[0] * dataSetParamStr2.nx[1] * dataSetParamStr2.nx[2] * dataSetParamStr2.nx[3] + + dataSetParamStr3.nx[0] * dataSetParamStr3.nx[1] * dataSetParamStr3.nx[2] * dataSetParamStr3.nx[3]; - // how many elements are in all arrays of DataSet (equal in all blocks) - int doubleCount = 0, temp; - for (int i = 0; i < 9; i++) // 9 arrays ( averageValues, averageVelocity, averageFluktuations, - { // averageTriplecorrelations, shearStressValues, relaxationFactor, 3 * fdistributions - temp = 1; - for (int ii = 0; ii < 4; ii++) // 4 values (nx1, nx2, nx3, nx4) - temp *= dataSetParamStr.nx[i][ii]; - doubleCount += temp; - } - dataSetParamStr.doubleCountInBlock = doubleCount; - } + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageDensityArray = block->getKernel()->getDataSet()->getAverageDencity(); + if (averageDensityArray) + arrPresence.isAverageDensityArrayPresent = true; + else + arrPresence.isAverageDensityArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageValuesArray3D = block->getKernel()->getDataSet()->getAverageValues(); - if (averageValuesArray3D&&(dataSetParamStr.nx[0][0]>0)&&(dataSetParamStr.nx[0][1]>0)&&(dataSetParamStr.nx[0][2]>0)&&(dataSetParamStr.nx[0][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), averageValuesArray3D->getDataVector().begin(), averageValuesArray3D->getDataVector().end()); + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity(); + if (AverageVelocityArray3DPtr) + arrPresence.isAverageVelocityArrayPresent = true; + else + arrPresence.isAverageVelocityArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity(); - if (AverageVelocityArray3DPtr&&(dataSetParamStr.nx[1][0]>0)&&(dataSetParamStr.nx[1][1]>0)&&(dataSetParamStr.nx[1][2]>0)&&(dataSetParamStr.nx[1][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), AverageVelocityArray3DPtr->getDataVector().begin(), AverageVelocityArray3DPtr->getDataVector().end()); + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations(); + if (AverageFluctArray3DPtr) + arrPresence.isAverageFluktuationsArrayPresent = true; + else + arrPresence.isAverageFluktuationsArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations(); - if (AverageFluctArray3DPtr&&(dataSetParamStr.nx[2][0]>0)&&(dataSetParamStr.nx[2][1]>0)&&(dataSetParamStr.nx[2][2]>0)&&(dataSetParamStr.nx[2][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), AverageFluctArray3DPtr->getDataVector().begin(), AverageFluctArray3DPtr->getDataVector().end()); + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations(); + if (AverageTripleArray3DPtr) + arrPresence.isAverageTripleArrayPresent = true; + else + arrPresence.isAverageTripleArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations(); - if (AverageTripleArray3DPtr&&(dataSetParamStr.nx[3][0]>0)&&(dataSetParamStr.nx[3][1]>0)&&(dataSetParamStr.nx[3][2]>0)&&(dataSetParamStr.nx[3][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), AverageTripleArray3DPtr->getDataVector().begin(), AverageTripleArray3DPtr->getDataVector().end()); + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues(); + if (ShearStressValArray3DPtr) + arrPresence.isShearStressValArrayPresent = true; + else + arrPresence.isShearStressValArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues(); - if (ShearStressValArray3DPtr&&(dataSetParamStr.nx[4][0]>0)&&(dataSetParamStr.nx[4][1]>0)&&(dataSetParamStr.nx[4][2]>0)&&(dataSetParamStr.nx[4][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), ShearStressValArray3DPtr->getDataVector().begin(), ShearStressValArray3DPtr->getDataVector().end()); + SPtr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor(); + if (relaxationFactor3DPtr) + arrPresence.isRelaxationFactorPresent = true; + else + arrPresence.isRelaxationFactorPresent = false; - SPtr< CbArray3D<LBMReal, IndexerX3X2X1> > RelaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor(); - if (RelaxationFactor3DPtr&&(dataSetParamStr.nx[5][0]>0)&&(dataSetParamStr.nx[5][1]>0)&&(dataSetParamStr.nx[5][2]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), RelaxationFactor3DPtr->getDataVector().begin(), RelaxationFactor3DPtr->getDataVector().end()); + firstBlock = false; + } - SPtr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions()); - CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions(); - if (localDistributions&&(dataSetParamStr.nx[6][0]>0)&&(dataSetParamStr.nx[6][1]>0)&&(dataSetParamStr.nx[6][2]>0)&&(dataSetParamStr.nx[6][3]>0)) + if (localDistributions && (dataSetParamStr1.nx[0]>0) && (dataSetParamStr1.nx[1]>0) && (dataSetParamStr1.nx[2]>0) && (dataSetParamStr1.nx[3]>0)) doubleValuesArray.insert(doubleValuesArray.end(), localDistributions->getDataVector().begin(), localDistributions->getDataVector().end()); - - CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions(); - if (nonLocalDistributions&&(dataSetParamStr.nx[7][0]>0)&&(dataSetParamStr.nx[7][1]>0)&&(dataSetParamStr.nx[7][2]>0)&&(dataSetParamStr.nx[7][3]>0)) + if (nonLocalDistributions && (dataSetParamStr2.nx[0]>0) && (dataSetParamStr2.nx[1]>0) && (dataSetParamStr2.nx[2]>0) && (dataSetParamStr2.nx[3]>0)) doubleValuesArray.insert(doubleValuesArray.end(), nonLocalDistributions->getDataVector().begin(), nonLocalDistributions->getDataVector().end()); - - CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions(); - if (zeroDistributions&&(dataSetParamStr.nx[8][0]>0)&&(dataSetParamStr.nx[8][1]>0)&&(dataSetParamStr.nx[8][2]>0)) + if (zeroDistributions && (dataSetParamStr3.nx[0]>0) && (dataSetParamStr3.nx[1]>0) && (dataSetParamStr3.nx[2]>0)) doubleValuesArray.insert(doubleValuesArray.end(), zeroDistributions->getDataVector().begin(), zeroDistributions->getDataVector().end()); ic++; @@ -516,14 +512,13 @@ void MPIIOMigrationCoProcessor::writeDataSet(int step) } // register new MPI-type depending on the block-specific information - MPI_Type_contiguous(dataSetParamStr.doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); MPI_Type_commit(&dataSetDoubleType); - mpiTypeFreeFlag = true; if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeDataSet start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeDataSet start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } double start, finish; @@ -538,380 +533,1648 @@ void MPIIOMigrationCoProcessor::writeDataSet(int step) // write to the file MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpDataSet.bin"; - int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE|MPI_MODE_WRONLY, info, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); - - size_t sizeofOneDataSet = sizeof(DataSet) + dataSetParamStr.doubleCountInBlock * sizeof(double); - MPI_Offset write_offset = 0; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); - MPI_File_write_at(file_handler, write_offset, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)0, &dataSetParamStr1, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(sizeof(dataSetParam)), &dataSetParamStr2, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(2 * sizeof(dataSetParam)), &dataSetParamStr3, 1, dataSetParamType, MPI_STATUS_IGNORE); + + MPI_Offset write_offset; + size_t sizeofOneDataSet = sizeof(DataSet) + doubleCountInBlock * sizeof(double); for (int nb = 0; nb < blocksCount; nb++) { - write_offset = (MPI_Offset)(sizeof(dataSetParam) + dataSetArray[nb].globalID * sizeofOneDataSet); + write_offset = (MPI_Offset)(3 * sizeof(dataSetParam) + dataSetArray[nb].globalID * sizeofOneDataSet); MPI_File_write_at(file_handler, write_offset, &dataSetArray[nb], 1, dataSetType, MPI_STATUS_IGNORE); - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(DataSet)), &doubleValuesArray[nb * dataSetParamStr.doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(DataSet)), &doubleValuesArray[nb * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); } MPI_File_sync(file_handler); MPI_File_close(&file_handler); + MPI_Type_free(&dataSetDoubleType); + if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeDataSet time: "<<finish-start<<" s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeDataSet time: " << finish - start << " s"); } delete[] dataSetArray; + + MPI_File file_handler1; + std::string filename1 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpArrays.bin"; + rc = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler1); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename1); + MPI_File_write_at(file_handler1, (MPI_Offset)0, &arrPresence, 1, arrayPresenceType, MPI_STATUS_IGNORE); + MPI_File_sync(file_handler1); + MPI_File_close(&file_handler1); + + if (arrPresence.isAverageDensityArrayPresent) + writeAverageDensityArray(step); + + if (arrPresence.isAverageVelocityArrayPresent) + writeAverageVelocityArray(step); + + if (arrPresence.isAverageFluktuationsArrayPresent) + writeAverageFluktuationsArray(step); + + if (arrPresence.isAverageTripleArrayPresent) + writeAverageTripleArray(step); + + if (arrPresence.isShearStressValArrayPresent) + writeShearStressValArray(step); + + if (arrPresence.isRelaxationFactorPresent) + writeRelaxationFactor(step); + } -void MPIIOMigrationCoProcessor::writeBoundaryConds(int step) +void MPIIOMigrationCoProcessor::writeAverageDensityArray(int step) { int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); - if (comm->isRoot()) - { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBoundaryConds start collect data rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); - } - - int blocksCount = 0; // quantity of blocks, that belong to this process - size_t allBytesCount = 0; // quantity of bytes, that one process writes to the file - size_t count_boundCond = 0; // how many BoundaryConditions in all blocks - int count_indexContainer = 0; // how many indexContainer-values in all blocks + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! std::vector<SPtr<Block3D>> blocksVector[25]; int minInitLevel = this->grid->getCoarsestInitializedLevel(); int maxInitLevel = this->grid->getFinestInitializedLevel(); - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { grid->getBlocks(level, rank, blocksVector[level]); blocksCount += static_cast<int>(blocksVector[level].size()); } - BCAdd* bcAddArray = new BCAdd[blocksCount]; - size_t* bytesCount = new size_t[blocksCount]; // quantity of bytes, that each block writes to the file - std::vector<BoundaryCondition>* bcVector = new std::vector<BoundaryCondition>[blocksCount]; - std::vector<int>* bcindexmatrixVector = new std::vector<int>[blocksCount]; - std::vector<int>* indexContainerVector = new std::vector<int>[blocksCount]; + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values of the AverageDensityArray in all blocks + dataSetParam dataSetParamStr; - bool bcindexmatrixCountNotInit = true; + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageDensityArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; int ic = 0; - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { - for(SPtr<Block3D> block : blocksVector[level]) // all the blocks of the current level + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level { - SPtr<BCArray3D> bcArr = block->getKernel()->getBCProcessor()->getBCArray(); + dataSetSmallArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid - bcAddArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid - bcAddArray[ic].boundCond_count = 0; // how many BoundaryConditions in this block - bcAddArray[ic].indexContainer_count = 0; // how many indexContainer-values in this block - bytesCount[ic] = sizeof(BCAdd); - bcVector[ic].resize(0); - bcindexmatrixVector[ic].resize(0); - indexContainerVector[ic].resize(0); + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageDensityArray = block->getKernel()->getDataSet()->getAverageDencity(); - for (int bc = 0; bc<bcArr->getBCVectorSize(); bc++) + if (firstBlock) // when first (any) valid block... { - BoundaryCondition* bouCond = new BoundaryCondition(); - if (bcArr->bcvector[bc]==NULL) - { - memset(bouCond, 0, sizeof(BoundaryCondition)); - } - else - { - bouCond->noslipBoundaryFlags = bcArr->bcvector[bc]->getNoSlipBoundary(); - bouCond->slipBoundaryFlags = bcArr->bcvector[bc]->getSlipBoundary(); - bouCond->velocityBoundaryFlags = bcArr->bcvector[bc]->getVelocityBoundary(); - bouCond->densityBoundaryFlags = bcArr->bcvector[bc]->getDensityBoundary(); - bouCond->wallModelBoundaryFlags = bcArr->bcvector[bc]->getWallModelBoundary(); - bouCond->bcVelocityX1 = bcArr->bcvector[bc]->getBoundaryVelocityX1(); - bouCond->bcVelocityX2 = bcArr->bcvector[bc]->getBoundaryVelocityX2(); - bouCond->bcVelocityX3 = bcArr->bcvector[bc]->getBoundaryVelocityX3(); - bouCond->bcDensity = bcArr->bcvector[bc]->getBoundaryDensity(); - bouCond->bcLodiDensity = bcArr->bcvector[bc]->getDensityLodiDensity(); - bouCond->bcLodiVelocityX1 = bcArr->bcvector[bc]->getDensityLodiVelocityX1(); - bouCond->bcLodiVelocityX2 = bcArr->bcvector[bc]->getDensityLodiVelocityX2(); - bouCond->bcLodiVelocityX3 = bcArr->bcvector[bc]->getDensityLodiVelocityX3(); - bouCond->bcLodiLentgh = bcArr->bcvector[bc]->getDensityLodiLength(); - bouCond->nx1 = bcArr->bcvector[bc]->nx1; - bouCond->nx2 = bcArr->bcvector[bc]->nx2; - bouCond->nx3 = bcArr->bcvector[bc]->nx3; - for (int iq = 0; iq<26; iq++) - bouCond->q[iq] = bcArr->bcvector[bc]->getQ(iq); - bouCond->algorithmType = bcArr->bcvector[bc]->getBcAlgorithmType(); - } + //if (averageDensityArray) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(averageDensityArray->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(averageDensityArray->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(averageDensityArray->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(averageDensityArray->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; - bcVector[ic].push_back(*bouCond); - bcAddArray[ic].boundCond_count++; - count_boundCond++; - bytesCount[ic] += sizeof(BoundaryCondition); - } - - if (bcindexmatrixCountNotInit) - { - boundCondParamStr.nx1 = static_cast<int>(bcArr->bcindexmatrix.getNX1()); - boundCondParamStr.nx2 = static_cast<int>(bcArr->bcindexmatrix.getNX2()); - boundCondParamStr.nx3 = static_cast<int>(bcArr->bcindexmatrix.getNX3()); - boundCondParamStr.bcindexmatrixCount = static_cast<int>(bcArr->bcindexmatrix.getDataVector().size()); - bcindexmatrixCountNotInit = false; + firstBlock = false; } - bcindexmatrixVector[ic].insert(bcindexmatrixVector[ic].begin(), bcArr->bcindexmatrix.getDataVector().begin(), bcArr->bcindexmatrix.getDataVector().end()); - bytesCount[ic] += boundCondParamStr.bcindexmatrixCount * sizeof(int); - - indexContainerVector[ic].insert(indexContainerVector[ic].begin(), bcArr->indexContainer.begin(), bcArr->indexContainer.end()); - bcAddArray[ic].indexContainer_count = static_cast<int>(bcArr->indexContainer.size()); - count_indexContainer += bcAddArray[ic].indexContainer_count; - bytesCount[ic] += bcAddArray[ic].indexContainer_count * sizeof(int); - allBytesCount += bytesCount[ic]; + if (averageDensityArray && (dataSetParamStr.nx[0] > 0) && (dataSetParamStr.nx[1] > 0) && (dataSetParamStr.nx[2] > 0) && (dataSetParamStr.nx[3] > 0)) + doubleValuesArray.insert(doubleValuesArray.end(), averageDensityArray->getDataVector().begin(), averageDensityArray->getDataVector().end()); ic++; } } - MPI_Type_contiguous(boundCondParamStr.bcindexmatrixCount, MPI_INT, &bcindexmatrixType); - MPI_Type_commit(&bcindexmatrixType); - mpiTypeFreeFlag = true; + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBoundaryConds start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageDensityArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } double start, finish; if (comm->isRoot()) start = MPI_Wtime(); MPI_Info info = MPI_INFO_NULL; - //MPI_Info_create (&info); - //MPI_Info_set(info,"romio_cb_write","enable"); - //MPI_Info_set(info,"cb_buffer_size","4194304"); - //MPI_Info_set(info,"striping_unit","4194304"); MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBC.bin"; - int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE|MPI_MODE_WRONLY, info, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); - - MPI_Offset write_offset = (MPI_Offset)(sizeof(boundCondParam) + grid->getNumberOfBlocks() * sizeof(size_t)); - size_t next_file_offset = 0; - if (size > 1) - { - if (rank == 0) - { - next_file_offset = write_offset + allBytesCount; - MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); - } - else - { - MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - next_file_offset = write_offset + allBytesCount; - if (rank < size - 1) - MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); - } - } + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageDensityArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); - MPI_File_write_at(file_handler, 0, &boundCondParamStr, 1, boundCondParamType, MPI_STATUS_IGNORE); + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, 0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); - MPI_Offset write_offsetIndex; + MPI_Offset write_offset; + size_t sizeofOneDataSet = sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double); for (int nb = 0; nb < blocksCount; nb++) { - write_offsetIndex = (MPI_Offset)(sizeof(boundCondParam) + bcAddArray[nb].globalID * sizeof(size_t)); - MPI_File_write_at(file_handler, write_offsetIndex, &write_offset, 1, MPI_LONG_LONG_INT, MPI_STATUS_IGNORE); - - MPI_File_write_at(file_handler, write_offset, &bcAddArray[nb], 1, boundCondTypeAdd, MPI_STATUS_IGNORE); - if (bcVector[nb].size() > 0) - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(BCAdd)), &bcVector[nb][0], bcAddArray[nb].boundCond_count, boundCondType, MPI_STATUS_IGNORE); - - if (bcindexmatrixVector[nb].size() > 0) - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(BCAdd) + bcAddArray[nb].boundCond_count * sizeof(BoundaryCondition)), - &bcindexmatrixVector[nb][0], 1, bcindexmatrixType, MPI_STATUS_IGNORE); - - if (indexContainerVector[nb].size() > 0) - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(BCAdd) + bcAddArray[nb].boundCond_count * sizeof(BoundaryCondition) + boundCondParamStr.bcindexmatrixCount * sizeof(int)), - &indexContainerVector[nb][0], bcAddArray[nb].indexContainer_count, MPI_INT, MPI_STATUS_IGNORE); - - write_offset += bytesCount[nb]; + write_offset = (MPI_Offset)(sizeof(dataSetParam) + dataSetSmallArray[nb].globalID * sizeofOneDataSet); + MPI_File_write_at(file_handler, write_offset, &dataSetSmallArray[nb], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(DataSetSmall)), &doubleValuesArray[nb * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); } MPI_File_sync(file_handler); MPI_File_close(&file_handler); + MPI_Type_free(&dataSetDoubleType); + if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBoundaryConds time: "<<finish-start<<" s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageDensityArray time: " << finish - start << " s"); } - delete[] bcAddArray; - delete[] bytesCount; - delete[] bcVector; - delete[] bcindexmatrixVector; - delete[] indexContainerVector; -} - -//------------------------------------------- READ ----------------------------------------------- -void MPIIOMigrationCoProcessor::restart(int step) -{ - if (comm->isRoot()) UBLOG(logINFO, "MPIIOMigrationCoProcessor restart step: "<<step); - if (comm->isRoot()) UBLOG(logINFO, "Load check point - start"); - readBlocks(step); - - SPtr<Grid3DVisitor> metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::BSW, MetisPartitioner::KWAY)); - grid->accept(metisVisitor); - - readDataSet(step); - readBoundaryConds(step); - if (comm->isRoot()) UBLOG(logINFO, "Load check point - end"); + delete[] dataSetSmallArray; } -void MPIIOMigrationCoProcessor::readBlocks(int step) +void MPIIOMigrationCoProcessor::writeAverageVelocityArray(int step) { int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - //MPI_Comm_size(MPI_COMM_WORLD, &size); - size = 1; - - if (comm->isRoot()) - { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBlocks start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); - } + MPI_Comm_size(MPI_COMM_WORLD, &size); - double start, finish; - if (comm->isRoot()) start = MPI_Wtime(); + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageVelocityArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid + + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity(); + + if (firstBlock) // when first (any) valid block... + { + //if (AverageVelocityArray3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(AverageVelocityArray3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(AverageVelocityArray3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(AverageVelocityArray3DPtr->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(AverageVelocityArray3DPtr->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (AverageVelocityArray3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0) && (dataSetParamStr.nx[3]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), AverageVelocityArray3DPtr->getDataVector().begin(), AverageVelocityArray3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageVelocityArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageVelocityArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, 0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + MPI_Offset write_offset; + size_t sizeofOneDataSet = sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double); + + for (int nb = 0; nb < blocksCount; nb++) + { + write_offset = (MPI_Offset)(sizeof(dataSetParam) + dataSetSmallArray[nb].globalID * sizeofOneDataSet); + MPI_File_write_at(file_handler, write_offset, &dataSetSmallArray[nb], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(DataSetSmall)), &doubleValuesArray[nb * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + } + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageVelocityArray time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIOMigrationCoProcessor::writeAverageFluktuationsArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageFluktuationsArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid + + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations(); + + if (firstBlock) // when first (any) valid block... + { + //if (AverageFluctArray3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(AverageFluctArray3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(AverageFluctArray3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(AverageFluctArray3DPtr->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(AverageFluctArray3DPtr->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (AverageFluctArray3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0) && (dataSetParamStr.nx[3]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), AverageFluctArray3DPtr->getDataVector().begin(), AverageFluctArray3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageFluktuationsArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageFluktuationsArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, 0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + MPI_Offset write_offset; + size_t sizeofOneDataSet = sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double); + + for (int nb = 0; nb < blocksCount; nb++) + { + write_offset = (MPI_Offset)(sizeof(dataSetParam) + dataSetSmallArray[nb].globalID * sizeofOneDataSet); + MPI_File_write_at(file_handler, write_offset, &dataSetSmallArray[nb], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(DataSetSmall)), &doubleValuesArray[nb * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + } + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageFluktuationsArray time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIOMigrationCoProcessor::writeAverageTripleArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageTripleArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid + + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations(); + + if (firstBlock) // when first (any) valid block... + { + //if (AverageTripleArray3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(AverageTripleArray3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(AverageTripleArray3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(AverageTripleArray3DPtr->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(AverageTripleArray3DPtr->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (AverageTripleArray3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0) && (dataSetParamStr.nx[3]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), AverageTripleArray3DPtr->getDataVector().begin(), AverageTripleArray3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageTripleArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageTripleArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, 0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + MPI_Offset write_offset; + size_t sizeofOneDataSet = sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double); + + for (int nb = 0; nb < blocksCount; nb++) + { + write_offset = (MPI_Offset)(sizeof(dataSetParam) + dataSetSmallArray[nb].globalID * sizeofOneDataSet); + MPI_File_write_at(file_handler, write_offset, &dataSetSmallArray[nb], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(DataSetSmall)), &doubleValuesArray[nb * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + } + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeAverageTripleArray time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIOMigrationCoProcessor::writeShearStressValArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeShearStressValArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid + + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues(); + + if (firstBlock) // when first (any) valid block... + { + //if (ShearStressValArray3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(ShearStressValArray3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(ShearStressValArray3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(ShearStressValArray3DPtr->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(ShearStressValArray3DPtr->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (ShearStressValArray3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0) && (dataSetParamStr.nx[3]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), ShearStressValArray3DPtr->getDataVector().begin(), ShearStressValArray3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeShearStressValArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpShearStressValArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, 0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + MPI_Offset write_offset; + size_t sizeofOneDataSet = sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double); + + for (int nb = 0; nb < blocksCount; nb++) + { + write_offset = (MPI_Offset)(sizeof(dataSetParam) + dataSetSmallArray[nb].globalID * sizeofOneDataSet); + MPI_File_write_at(file_handler, write_offset, &dataSetSmallArray[nb], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(DataSetSmall)), &doubleValuesArray[nb * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + } + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeShearStressValArray time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIOMigrationCoProcessor::writeRelaxationFactor(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeRelaxationFactor start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid + + SPtr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor(); + + if (firstBlock) // when first (any) valid block... + { + //if (relaxationFactor3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(relaxationFactor3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(relaxationFactor3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(relaxationFactor3DPtr->getNX3()); + dataSetParamStr.nx[3] = 1; + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (relaxationFactor3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), relaxationFactor3DPtr->getDataVector().begin(), relaxationFactor3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeRelaxationFactor start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpRelaxationFactor.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, 0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + MPI_Offset write_offset; + size_t sizeofOneDataSet = sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double); + + for (int nb = 0; nb < blocksCount; nb++) + { + write_offset = (MPI_Offset)(sizeof(dataSetParam) + dataSetSmallArray[nb].globalID * sizeofOneDataSet); + MPI_File_write_at(file_handler, write_offset, &dataSetSmallArray[nb], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(DataSetSmall)), &doubleValuesArray[nb * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + } + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeRelaxationFactor time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIOMigrationCoProcessor::writeBoundaryConds(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBoundaryConds start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + int blocksCount = 0; // quantity of blocks, that belong to this process + size_t allBytesCount = 0; // quantity of bytes, that one process writes to the file + size_t count_boundCond = 0; // how many BoundaryConditions in all blocks + int count_indexContainer = 0; // how many indexContainer-values in all blocks + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + BCAdd* bcAddArray = new BCAdd[blocksCount]; + size_t* bytesCount = new size_t[blocksCount]; // quantity of bytes, that each block writes to the file + std::vector<BoundaryCondition>* bcVector = new std::vector<BoundaryCondition>[blocksCount]; + std::vector<int>* bcindexmatrixVector = new std::vector<int>[blocksCount]; + std::vector<int>* indexContainerVector = new std::vector<int>[blocksCount]; + + bool bcindexmatrixCountNotInit = true; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // all the blocks of the current level + { + SPtr<BCArray3D> bcArr = block->getKernel()->getBCProcessor()->getBCArray(); + + bcAddArray[ic].globalID = block->getGlobalID(); // id of the block needed to find it while regenerating the grid + bcAddArray[ic].boundCond_count = 0; // how many BoundaryConditions in this block + bcAddArray[ic].indexContainer_count = 0; // how many indexContainer-values in this block + bytesCount[ic] = sizeof(BCAdd); + bcVector[ic].resize(0); + bcindexmatrixVector[ic].resize(0); + indexContainerVector[ic].resize(0); + + for (int bc = 0; bc<bcArr->getBCVectorSize(); bc++) + { + BoundaryCondition* bouCond = new BoundaryCondition(); + if (bcArr->bcvector[bc] == NULL) + { + memset(bouCond, 0, sizeof(BoundaryCondition)); + } + else + { + bouCond->noslipBoundaryFlags = bcArr->bcvector[bc]->getNoSlipBoundary(); + bouCond->slipBoundaryFlags = bcArr->bcvector[bc]->getSlipBoundary(); + bouCond->velocityBoundaryFlags = bcArr->bcvector[bc]->getVelocityBoundary(); + bouCond->densityBoundaryFlags = bcArr->bcvector[bc]->getDensityBoundary(); + bouCond->wallModelBoundaryFlags = bcArr->bcvector[bc]->getWallModelBoundary(); + bouCond->bcVelocityX1 = bcArr->bcvector[bc]->getBoundaryVelocityX1(); + bouCond->bcVelocityX2 = bcArr->bcvector[bc]->getBoundaryVelocityX2(); + bouCond->bcVelocityX3 = bcArr->bcvector[bc]->getBoundaryVelocityX3(); + bouCond->bcDensity = bcArr->bcvector[bc]->getBoundaryDensity(); + bouCond->bcLodiDensity = bcArr->bcvector[bc]->getDensityLodiDensity(); + bouCond->bcLodiVelocityX1 = bcArr->bcvector[bc]->getDensityLodiVelocityX1(); + bouCond->bcLodiVelocityX2 = bcArr->bcvector[bc]->getDensityLodiVelocityX2(); + bouCond->bcLodiVelocityX3 = bcArr->bcvector[bc]->getDensityLodiVelocityX3(); + bouCond->bcLodiLentgh = bcArr->bcvector[bc]->getDensityLodiLength(); + bouCond->nx1 = bcArr->bcvector[bc]->nx1; + bouCond->nx2 = bcArr->bcvector[bc]->nx2; + bouCond->nx3 = bcArr->bcvector[bc]->nx3; + for (int iq = 0; iq<26; iq++) + bouCond->q[iq] = bcArr->bcvector[bc]->getQ(iq); + bouCond->algorithmType = bcArr->bcvector[bc]->getBcAlgorithmType(); + } + + bcVector[ic].push_back(*bouCond); + bcAddArray[ic].boundCond_count++; + count_boundCond++; + bytesCount[ic] += sizeof(BoundaryCondition); + } + + if (bcindexmatrixCountNotInit) + { + boundCondParamStr.nx1 = static_cast<int>(bcArr->bcindexmatrix.getNX1()); + boundCondParamStr.nx2 = static_cast<int>(bcArr->bcindexmatrix.getNX2()); + boundCondParamStr.nx3 = static_cast<int>(bcArr->bcindexmatrix.getNX3()); + boundCondParamStr.bcindexmatrixCount = static_cast<int>(bcArr->bcindexmatrix.getDataVector().size()); + bcindexmatrixCountNotInit = false; + } + bcindexmatrixVector[ic].insert(bcindexmatrixVector[ic].begin(), bcArr->bcindexmatrix.getDataVector().begin(), bcArr->bcindexmatrix.getDataVector().end()); + bytesCount[ic] += boundCondParamStr.bcindexmatrixCount * sizeof(int); + + indexContainerVector[ic].insert(indexContainerVector[ic].begin(), bcArr->indexContainer.begin(), bcArr->indexContainer.end()); + bcAddArray[ic].indexContainer_count = static_cast<int>(bcArr->indexContainer.size()); + count_indexContainer += bcAddArray[ic].indexContainer_count; + bytesCount[ic] += bcAddArray[ic].indexContainer_count * sizeof(int); + + allBytesCount += bytesCount[ic]; + + ic++; + } + } + + MPI_Type_contiguous(boundCondParamStr.bcindexmatrixCount, MPI_INT, &bcindexmatrixType); + MPI_Type_commit(&bcindexmatrixType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBoundaryConds start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + //MPI_Info_create (&info); + //MPI_Info_set(info,"romio_cb_write","enable"); + //MPI_Info_set(info,"cb_buffer_size","4194304"); + //MPI_Info_set(info,"striping_unit","4194304"); + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + MPI_Offset write_offset = (MPI_Offset)(sizeof(boundCondParam) + grid->getNumberOfBlocks() * sizeof(size_t)); + size_t next_file_offset = 0; + if (size > 1) + { + if (rank == 0) + { + next_file_offset = write_offset + allBytesCount; + MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_file_offset = write_offset + allBytesCount; + if (rank < size - 1) + MPI_Send(&next_file_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + MPI_File_write_at(file_handler, 0, &boundCondParamStr, 1, boundCondParamType, MPI_STATUS_IGNORE); + + MPI_Offset write_offsetIndex; + + for (int nb = 0; nb < blocksCount; nb++) + { + write_offsetIndex = (MPI_Offset)(sizeof(boundCondParam) + bcAddArray[nb].globalID * sizeof(size_t)); + MPI_File_write_at(file_handler, write_offsetIndex, &write_offset, 1, MPI_LONG_LONG_INT, MPI_STATUS_IGNORE); + + MPI_File_write_at(file_handler, write_offset, &bcAddArray[nb], 1, boundCondTypeAdd, MPI_STATUS_IGNORE); + if (bcVector[nb].size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(BCAdd)), &bcVector[nb][0], bcAddArray[nb].boundCond_count, boundCondType, MPI_STATUS_IGNORE); + + if (bcindexmatrixVector[nb].size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(BCAdd) + bcAddArray[nb].boundCond_count * sizeof(BoundaryCondition)), + &bcindexmatrixVector[nb][0], 1, bcindexmatrixType, MPI_STATUS_IGNORE); + + if (indexContainerVector[nb].size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(BCAdd) + bcAddArray[nb].boundCond_count * sizeof(BoundaryCondition) + boundCondParamStr.bcindexmatrixCount * sizeof(int)), + &indexContainerVector[nb][0], bcAddArray[nb].indexContainer_count, MPI_INT, MPI_STATUS_IGNORE); + + write_offset += bytesCount[nb]; + } + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&bcindexmatrixType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::writeBoundaryConds time: " << finish - start << " s"); + } + + delete[] bcAddArray; + delete[] bytesCount; + delete[] bcVector; + delete[] bcindexmatrixVector; + delete[] indexContainerVector; +} + +//------------------------------------------- READ ----------------------------------------------- +void MPIIOMigrationCoProcessor::restart(int step) +{ + if (comm->isRoot()) UBLOG(logINFO, "MPIIOMigrationCoProcessor restart step: " << step); + if (comm->isRoot()) UBLOG(logINFO, "Load check point - start"); + + readBlocks(step); + + SPtr<Grid3DVisitor> metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, D3Q27System::BSW, MetisPartitioner::KWAY)); + grid->accept(metisVisitor); + + readDataSet(step); + readBoundaryConds(step); + + if (comm->isRoot()) UBLOG(logINFO, "Load check point - end"); + //this->reconnect(grid); +} + +void MPIIOMigrationCoProcessor::readBlocks(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + //MPI_Comm_size(MPI_COMM_WORLD, &size); + size = 1; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBlocks start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // read count of blocks + int blocksCount = 0; + //MPI_File_read_at(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, 0, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + Block3d* block3dArray = new Block3d[blocksCount]; + + GridParam* gridParameters = new GridParam; + + // calculate the read offset + MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int)); + + // read parameters of the grid + MPI_File_read_at(file_handler, read_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE); + // read all the blocks + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(GridParam)), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE); + + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBlocks time: " << finish - start << " s"); + } + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBlocks start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + // clear the grid + std::vector<SPtr<Block3D>> blocksVector; + grid->getBlocks(0, blocksVector); + int del = 0; + for (SPtr<Block3D> block : blocksVector) + { + grid->deleteBlock(block); + del++; + } + + // restore the grid + SPtr<CoordinateTransformation3D> trafo(new CoordinateTransformation3D()); + trafo->Tx1 = gridParameters->trafoParams[0]; + trafo->Tx2 = gridParameters->trafoParams[1]; + trafo->Tx3 = gridParameters->trafoParams[2]; + trafo->Sx1 = gridParameters->trafoParams[3]; + trafo->Sx2 = gridParameters->trafoParams[4]; + trafo->Sx3 = gridParameters->trafoParams[5]; + trafo->alpha = gridParameters->trafoParams[6]; + trafo->beta = gridParameters->trafoParams[7]; + trafo->gamma = gridParameters->trafoParams[8]; + + trafo->toX1factorX1 = gridParameters->trafoParams[9]; + trafo->toX1factorX2 = gridParameters->trafoParams[10]; + trafo->toX1factorX3 = gridParameters->trafoParams[11]; + trafo->toX1delta = gridParameters->trafoParams[12]; + trafo->toX2factorX1 = gridParameters->trafoParams[13]; + trafo->toX2factorX2 = gridParameters->trafoParams[14]; + trafo->toX2factorX3 = gridParameters->trafoParams[15]; + trafo->toX2delta = gridParameters->trafoParams[16]; + trafo->toX3factorX1 = gridParameters->trafoParams[17]; + trafo->toX3factorX2 = gridParameters->trafoParams[18]; + trafo->toX3factorX3 = gridParameters->trafoParams[19]; + trafo->toX3delta = gridParameters->trafoParams[20]; + + trafo->fromX1factorX1 = gridParameters->trafoParams[21]; + trafo->fromX1factorX2 = gridParameters->trafoParams[22]; + trafo->fromX1factorX3 = gridParameters->trafoParams[23]; + trafo->fromX1delta = gridParameters->trafoParams[24]; + trafo->fromX2factorX1 = gridParameters->trafoParams[25]; + trafo->fromX2factorX2 = gridParameters->trafoParams[26]; + trafo->fromX2factorX3 = gridParameters->trafoParams[27]; + trafo->fromX2delta = gridParameters->trafoParams[28]; + trafo->fromX3factorX1 = gridParameters->trafoParams[29]; + trafo->fromX3factorX2 = gridParameters->trafoParams[30]; + trafo->fromX3factorX3 = gridParameters->trafoParams[31]; + trafo->fromX3delta = gridParameters->trafoParams[32]; + + trafo->active = gridParameters->active; + trafo->transformation = gridParameters->transformation; + + grid->setCoordinateTransformator(trafo); + + grid->setDeltaX(gridParameters->deltaX); + grid->setBlockNX(gridParameters->blockNx1, gridParameters->blockNx2, gridParameters->blockNx3); + grid->setNX1(gridParameters->nx1); + grid->setNX2(gridParameters->nx2); + grid->setNX3(gridParameters->nx3); + grid->setPeriodicX1(gridParameters->periodicX1); + grid->setPeriodicX2(gridParameters->periodicX2); + grid->setPeriodicX3(gridParameters->periodicX3); + + // regenerate blocks + for (int n = 0; n<blocksCount; n++) + { + SPtr<Block3D> block(new Block3D(block3dArray[n].x1, block3dArray[n].x2, block3dArray[n].x3, block3dArray[n].level)); + block->setActive(block3dArray[n].active); + block->setBundle(block3dArray[n].bundle); + block->setRank(block3dArray[n].rank); + block->setLocalRank(block3dArray[n].lrank); + block->setGlobalID(block3dArray[n].globalID); + block->setLocalID(block3dArray[n].localID); + block->setPart(block3dArray[n].part); + block->setLevel(block3dArray[n].level); + block->interpolationFlagCF = block3dArray[n].interpolationFlagCF; + block->interpolationFlagFC = block3dArray[n].interpolationFlagFC; + + grid->addBlock(block); + } + + delete gridParameters; + delete[] block3dArray; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBlocks end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } +} + +void MPIIOMigrationCoProcessor::readDataSet(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readDataSet start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + int blocksCount = 0; // quantity of the blocks, that belong to this process + dataSetParam dataSetParamStr1, dataSetParamStr2, dataSetParamStr3; + + // read from the grid the blocks, that belong to this process + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSet* dataSetArray = new DataSet[blocksCount]; + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + MPI_File_read_at(file_handler, (MPI_Offset)0, &dataSetParamStr1, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(sizeof(dataSetParam)), &dataSetParamStr2, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(2 * sizeof(dataSetParam)), &dataSetParamStr3, 1, dataSetParamType, MPI_STATUS_IGNORE); + + double doubleCountInBlock = dataSetParamStr1.nx[0] * dataSetParamStr1.nx[1] * dataSetParamStr1.nx[2] * dataSetParamStr1.nx[3] + + dataSetParamStr2.nx[0] * dataSetParamStr2.nx[1] * dataSetParamStr2.nx[2] * dataSetParamStr2.nx[3] + + dataSetParamStr3.nx[0] * dataSetParamStr3.nx[1] * dataSetParamStr3.nx[2] * dataSetParamStr3.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + int ic = 0; + MPI_Offset read_offset; + size_t sizeofOneDataSet = size_t(sizeof(DataSet) + doubleCountInBlock * sizeof(double)); + + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + read_offset = (MPI_Offset)(3 * sizeof(dataSetParam) + block->getGlobalID() * sizeofOneDataSet); + MPI_File_read_at(file_handler, read_offset, &dataSetArray[ic], 1, dataSetType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSet)), &doubleValuesArray[ic * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + ic++; + } + } + + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readDataSet time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readDataSet start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + size_t index = 0, vectorSize = 0; + std::vector<double> vectorsOfValues1, vectorsOfValues2, vectorsOfValues3; + + for (int n = 0; n < blocksCount; n++) + { + vectorSize = dataSetParamStr1.nx[0] * dataSetParamStr1.nx[1] * dataSetParamStr1.nx[2] * dataSetParamStr1.nx[3]; + vectorsOfValues1.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + vectorSize); + index += vectorSize; + + vectorSize = dataSetParamStr2.nx[0] * dataSetParamStr2.nx[1] * dataSetParamStr2.nx[2] * dataSetParamStr2.nx[3]; + vectorsOfValues2.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + vectorSize); + index += vectorSize; + + vectorSize = dataSetParamStr3.nx[0] * dataSetParamStr3.nx[1] * dataSetParamStr3.nx[2] * dataSetParamStr3.nx[3]; + vectorsOfValues3.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + vectorSize); + index += vectorSize; + + SPtr<DistributionArray3D> mFdistributions(new D3Q27EsoTwist3DSplittedVector()); + + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues1, dataSetParamStr1.nx[0], dataSetParamStr1.nx[1], dataSetParamStr1.nx[2], dataSetParamStr1.nx[3]))); + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues2, dataSetParamStr2.nx[0], dataSetParamStr2.nx[1], dataSetParamStr2.nx[2], dataSetParamStr2.nx[3]))); + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues3, dataSetParamStr3.nx[0], dataSetParamStr3.nx[1], dataSetParamStr3.nx[2]))); + + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(dataSetParamStr1.nx1); + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(dataSetParamStr1.nx2); + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(dataSetParamStr1.nx3); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetArray[n].globalID); + //std::cout << "rank="<<rank<<", dataSetArray[n].globalID=" << dataSetArray[n].globalID << std::endl; + + SPtr<LBMKernel> kernel = this->lbmKernel->clone(); + kernel->setGhostLayerWidth(dataSetArray[n].ghostLayerWidth); + kernel->setCollisionFactor(dataSetArray[n].collFactor); + kernel->setDeltaT(dataSetArray[n].deltaT); + kernel->setCompressible(dataSetArray[n].compressible); + kernel->setWithForcing(dataSetArray[n].withForcing); + SPtr<DataSet3D> dataSetPtr = SPtr<DataSet3D>(new DataSet3D()); + dataSetPtr->setFdistributions(mFdistributions); + kernel->setDataSet(dataSetPtr); + block->setKernel(kernel); + } + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readDataSet end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + delete[] dataSetArray; + + //------------------------------------------------------------- + + DSArraysPresence arrPresence; + MPI_File file_handler1; + std::string filename1 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpArrays.bin"; + rc = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler1); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename1); + MPI_File_read_at(file_handler1, (MPI_Offset)0, &arrPresence, 1, arrayPresenceType, MPI_STATUS_IGNORE); + MPI_File_close(&file_handler1); + + if (arrPresence.isAverageDensityArrayPresent) + readAverageDensityArray(step); + + if (arrPresence.isAverageVelocityArrayPresent) + readAverageVelocityArray(step); + + if (arrPresence.isAverageFluktuationsArrayPresent) + readAverageFluktuationsArray(step); + + if (arrPresence.isAverageTripleArrayPresent) + readAverageTripleArray(step); + + if (arrPresence.isShearStressValArrayPresent) + readShearStressValArray(step); + + if (arrPresence.isRelaxationFactorPresent) + readRelaxationFactor(step); + +} + +void MPIIOMigrationCoProcessor::readAverageDensityArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageDensityArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBlocks.bin"; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageDensityArray.bin"; int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); // read count of blocks int blocksCount = 0; - //MPI_File_read_at(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, 0, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); - Block3d* block3dArray = new Block3d[blocksCount]; - - GridParam* gridParameters = new GridParam; + dataSetParam dataSetParamStr; + memset(&dataSetParamStr, 0, sizeof(dataSetParam)); + + // read from the grid the blocks, that belong to this process + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + MPI_File_read_at(file_handler, (MPI_Offset)0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + int ic = 0; + MPI_Offset read_offset; + size_t sizeofOneDataSet = size_t(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + read_offset = (MPI_Offset)(sizeof(dataSetParam) + block->getGlobalID() * sizeofOneDataSet); + MPI_File_read_at(file_handler, read_offset, &dataSetSmallArray[ic], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSetSmall)), &doubleValuesArray[ic * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + ic++; + } + } + + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageDensityArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageDensityArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; + + // fill mAverageDensity arrays + SPtr<AverageValuesArray3D> mAverageDensity; + //if ((dataSetParamStr.nx[0]==0)&&(dataSetParamStr.nx[1]==0)&&(dataSetParamStr.nx[2]==0)&&(dataSetParamStr.nx[3]==0)) + // mAverageDensity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mAverageDensity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); + + //std::cout << "rank=" << rank << ", dataSetArray[n].globalID=" << dataSetSmallArray[n].globalID << std::endl; + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].globalID); + block->kernel->getDataSet()->setAverageDencity(mAverageDensity); + } + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageDensityArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + delete[] dataSetSmallArray; +} + +void MPIIOMigrationCoProcessor::readAverageVelocityArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageVelocityArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageVelocityArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr; + memset(&dataSetParamStr, 0, sizeof(dataSetParam)); + + // read from the grid the blocks, that belong to this process + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + MPI_File_read_at(file_handler, (MPI_Offset)0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + int ic = 0; + MPI_Offset read_offset; + size_t sizeofOneDataSet = size_t(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + read_offset = (MPI_Offset)(sizeof(dataSetParam) + block->getGlobalID() * sizeofOneDataSet); + MPI_File_read_at(file_handler, read_offset, &dataSetSmallArray[ic], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSetSmall)), &doubleValuesArray[ic * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + ic++; + } + } + + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageVelocityArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageVelocityArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; + + // fill mAverageVelocity array + SPtr<AverageValuesArray3D> mAverageVelocity; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0) && (dataSetParamStr.nx[3] == 0)) + // mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].globalID); + block->kernel->getDataSet()->setAverageVelocity(mAverageVelocity); + } + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageVelocityArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + delete[] dataSetSmallArray; +} + +void MPIIOMigrationCoProcessor::readAverageFluktuationsArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageFluktuationsArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageFluktuationsArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr; + memset(&dataSetParamStr, 0, sizeof(dataSetParam)); + + // read from the grid the blocks, that belong to this process + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + MPI_File_read_at(file_handler, (MPI_Offset)0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); - // calculate the read offset - MPI_Offset read_offset = (MPI_Offset)(size*sizeof(int)); + int ic = 0; + MPI_Offset read_offset; + size_t sizeofOneDataSet = size_t(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); - // read parameters of the grid - MPI_File_read_at(file_handler, read_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE); - // read all the blocks - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset+sizeof(GridParam)), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + read_offset = (MPI_Offset)(sizeof(dataSetParam) + block->getGlobalID() * sizeofOneDataSet); + MPI_File_read_at(file_handler, read_offset, &dataSetSmallArray[ic], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSetSmall)), &doubleValuesArray[ic * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + ic++; + } + } MPI_File_close(&file_handler); if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBlocks time: "<<finish-start<<" s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageFluktuationsArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageFluktuationsArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; + + // fill AverageFluktuations array + SPtr<AverageValuesArray3D> mAverageFluktuations; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0) && (dataSetParamStr.nx[3] == 0)) + // mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].globalID); + block->kernel->getDataSet()->setAverageFluctuations(mAverageFluktuations); } + MPI_Type_free(&dataSetDoubleType); + if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBlocks start of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageFluktuationsArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } - // clear the grid - std::vector<SPtr<Block3D>> blocksVector; - grid->getBlocks(0, blocksVector); - int del = 0; - for(SPtr<Block3D> block : blocksVector) + delete[] dataSetSmallArray; +} + +void MPIIOMigrationCoProcessor::readAverageTripleArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) { - grid->deleteBlock(block); - del++; + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageTripleArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); - // restore the grid - SPtr<CoordinateTransformation3D> trafo(new CoordinateTransformation3D()); - trafo->Tx1 = gridParameters->trafoParams[0]; - trafo->Tx2 = gridParameters->trafoParams[1]; - trafo->Tx3 = gridParameters->trafoParams[2]; - trafo->Sx1 = gridParameters->trafoParams[3]; - trafo->Sx2 = gridParameters->trafoParams[4]; - trafo->Sx3 = gridParameters->trafoParams[5]; - trafo->alpha = gridParameters->trafoParams[6]; - trafo->beta = gridParameters->trafoParams[7]; - trafo->gamma = gridParameters->trafoParams[8]; + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageTripleArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); - trafo->toX1factorX1 = gridParameters->trafoParams[9]; - trafo->toX1factorX2 = gridParameters->trafoParams[10]; - trafo->toX1factorX3 = gridParameters->trafoParams[11]; - trafo->toX1delta = gridParameters->trafoParams[12]; - trafo->toX2factorX1 = gridParameters->trafoParams[13]; - trafo->toX2factorX2 = gridParameters->trafoParams[14]; - trafo->toX2factorX3 = gridParameters->trafoParams[15]; - trafo->toX2delta = gridParameters->trafoParams[16]; - trafo->toX3factorX1 = gridParameters->trafoParams[17]; - trafo->toX3factorX2 = gridParameters->trafoParams[18]; - trafo->toX3factorX3 = gridParameters->trafoParams[19]; - trafo->toX3delta = gridParameters->trafoParams[20]; + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr; + memset(&dataSetParamStr, 0, sizeof(dataSetParam)); - trafo->fromX1factorX1 = gridParameters->trafoParams[21]; - trafo->fromX1factorX2 = gridParameters->trafoParams[22]; - trafo->fromX1factorX3 = gridParameters->trafoParams[23]; - trafo->fromX1delta = gridParameters->trafoParams[24]; - trafo->fromX2factorX1 = gridParameters->trafoParams[25]; - trafo->fromX2factorX2 = gridParameters->trafoParams[26]; - trafo->fromX2factorX3 = gridParameters->trafoParams[27]; - trafo->fromX2delta = gridParameters->trafoParams[28]; - trafo->fromX3factorX1 = gridParameters->trafoParams[29]; - trafo->fromX3factorX2 = gridParameters->trafoParams[30]; - trafo->fromX3factorX3 = gridParameters->trafoParams[31]; - trafo->fromX3delta = gridParameters->trafoParams[32]; + // read from the grid the blocks, that belong to this process + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } - trafo->active = gridParameters->active; - trafo->transformation = gridParameters->transformation; + MPI_File_read_at(file_handler, (MPI_Offset)0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); - grid->setCoordinateTransformator(trafo); + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks - grid->setDeltaX(gridParameters->deltaX); - grid->setBlockNX(gridParameters->blockNx1, gridParameters->blockNx2, gridParameters->blockNx3); - grid->setNX1(gridParameters->nx1); - grid->setNX2(gridParameters->nx2); - grid->setNX3(gridParameters->nx3); - grid->setPeriodicX1(gridParameters->periodicX1); - grid->setPeriodicX2(gridParameters->periodicX2); - grid->setPeriodicX3(gridParameters->periodicX3); + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); - // regenerate blocks - for (int n = 0; n<blocksCount; n++) + int ic = 0; + MPI_Offset read_offset; + size_t sizeofOneDataSet = size_t(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + + for (int level = minInitLevel; level <= maxInitLevel; level++) { - SPtr<Block3D> block(new Block3D(block3dArray[n].x1, block3dArray[n].x2, block3dArray[n].x3, block3dArray[n].level)); - block->setActive(block3dArray[n].active); - block->setBundle(block3dArray[n].bundle); - block->setRank(block3dArray[n].rank); - block->setLocalRank(block3dArray[n].lrank); - block->setGlobalID(block3dArray[n].globalID); - block->setLocalID(block3dArray[n].localID); - block->setPart(block3dArray[n].part); - block->setLevel(block3dArray[n].level); - block->interpolationFlagCF = block3dArray[n].interpolationFlagCF; - block->interpolationFlagFC = block3dArray[n].interpolationFlagFC; + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + read_offset = (MPI_Offset)(sizeof(dataSetParam) + block->getGlobalID() * sizeofOneDataSet); + MPI_File_read_at(file_handler, read_offset, &dataSetSmallArray[ic], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSetSmall)), &doubleValuesArray[ic * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + ic++; + } + } - grid->addBlock(block); + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageTripleArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageTripleArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } - delete gridParameters; - delete[] block3dArray; + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; + + // fill AverageTriplecorrelations array + SPtr<AverageValuesArray3D> mAverageTriplecorrelations; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0) && (dataSetParamStr.nx[3] == 0)) + // mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].globalID); + block->kernel->getDataSet()->setAverageTriplecorrelations(mAverageTriplecorrelations); + } + + MPI_Type_free(&dataSetDoubleType); if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBlocks end of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readAverageTripleArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } + + delete[] dataSetSmallArray; } -void MPIIOMigrationCoProcessor::readDataSet(int step) +void MPIIOMigrationCoProcessor::readShearStressValArray(int step) { int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); @@ -919,13 +2182,21 @@ void MPIIOMigrationCoProcessor::readDataSet(int step) if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readDataSet start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readShearStressValArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } double start, finish; if (comm->isRoot()) start = MPI_Wtime(); - int blocksCount = 0; // quantity of the blocks, that belong to this process + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpShearStressValArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr; + memset(&dataSetParamStr, 0, sizeof(dataSetParam)); // read from the grid the blocks, that belong to this process std::vector<SPtr<Block3D>> blocksVector[25]; @@ -937,32 +2208,27 @@ void MPIIOMigrationCoProcessor::readDataSet(int step) blocksCount += static_cast<int>(blocksVector[level].size()); } - DataSet* dataSetArray = new DataSet[blocksCount]; - - MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpDataSet.bin"; - int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); - MPI_File_read_at(file_handler, (MPI_Offset)0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); - - std::vector<double> doubleValuesArray(blocksCount * dataSetParamStr.doubleCountInBlock); // double-values in all blocks + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks // define MPI_types depending on the block-specific information - MPI_Type_contiguous(dataSetParamStr.doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); MPI_Type_commit(&dataSetDoubleType); - mpiTypeFreeFlag = true; int ic = 0; MPI_Offset read_offset; - size_t sizeofOneDataSet = size_t(sizeof(DataSet) + dataSetParamStr.doubleCountInBlock * sizeof(double)); + size_t sizeofOneDataSet = size_t(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + for (int level = minInitLevel; level <= maxInitLevel; level++) { - for(SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level { read_offset = (MPI_Offset)(sizeof(dataSetParam) + block->getGlobalID() * sizeofOneDataSet); - MPI_File_read_at(file_handler, read_offset, &dataSetArray[ic], 1, dataSetType, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSet)), &doubleValuesArray[ic * dataSetParamStr.doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, read_offset, &dataSetSmallArray[ic], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSetSmall)), &doubleValuesArray[ic * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); ic++; } } @@ -972,99 +2238,140 @@ void MPIIOMigrationCoProcessor::readDataSet(int step) if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readDataSet time: "<<finish-start<<" s"); - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readDataSet start of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readShearStressValArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readShearStressValArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } - - size_t index = 0, nextVectorSize = 0; - std::vector<double> vectorsOfValues[9]; - for (int n = 0; n<blocksCount; n++) + + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) { - for (int b = 0; b<9; b++) // assign approciate vectors to 9 dataSet arrays - { - nextVectorSize = dataSetParamStr.nx[b][0]* dataSetParamStr.nx[b][1]* dataSetParamStr.nx[b][2]* dataSetParamStr.nx[b][3]; - vectorsOfValues[b].assign(doubleValuesArray.data()+index, doubleValuesArray.data()+index+nextVectorSize); - index += nextVectorSize; - } + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; - // fill dataSet arrays - SPtr<AverageValuesArray3D> mAverageValues; - if ((dataSetParamStr.nx[0][0]==0)&&(dataSetParamStr.nx[0][1]==0)&&(dataSetParamStr.nx[0][2]==0)&&(dataSetParamStr.nx[0][3]==0)) - mAverageValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mAverageValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[0], dataSetParamStr.nx[0][0], dataSetParamStr.nx[0][1], dataSetParamStr.nx[0][2], dataSetParamStr.nx[0][3])); + // fill ShearStressValuesArray array + SPtr<ShearStressValuesArray3D> mShearStressValues; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0) && (dataSetParamStr.nx[3] == 0)) + // mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); - SPtr<AverageValuesArray3D> mAverageVelocity; - if ((dataSetParamStr.nx[1][0]==0)&&(dataSetParamStr.nx[1][1]==0)&&(dataSetParamStr.nx[1][2]==0)&&(dataSetParamStr.nx[1][3]==0)) - mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[1], dataSetParamStr.nx[1][0], dataSetParamStr.nx[1][1], dataSetParamStr.nx[1][2], dataSetParamStr.nx[1][3])); + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].globalID); + block->kernel->getDataSet()->setShearStressValues(mShearStressValues); + } - SPtr<AverageValuesArray3D> mAverageFluktuations; - if ((dataSetParamStr.nx[2][0]==0)&&(dataSetParamStr.nx[2][1]==0)&&(dataSetParamStr.nx[2][2]==0)&&(dataSetParamStr.nx[2][3]==0)) - mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[2], dataSetParamStr.nx[2][0], dataSetParamStr.nx[2][1], dataSetParamStr.nx[2][2], dataSetParamStr.nx[2][3])); + MPI_Type_free(&dataSetDoubleType); - SPtr<AverageValuesArray3D> mAverageTriplecorrelations; - if ((dataSetParamStr.nx[3][0]==0)&&(dataSetParamStr.nx[3][1]==0)&&(dataSetParamStr.nx[3][2]==0)&&(dataSetParamStr.nx[3][3]==0)) - mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[3], dataSetParamStr.nx[3][0], dataSetParamStr.nx[3][1], dataSetParamStr.nx[3][2], dataSetParamStr.nx[3][3])); + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readShearStressValArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } - SPtr<ShearStressValuesArray3D> mShearStressValues; - if ((dataSetParamStr.nx[4][0]==0)&&(dataSetParamStr.nx[4][1]==0)&&(dataSetParamStr.nx[4][2]==0)&&(dataSetParamStr.nx[4][3]==0)) - mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[4], dataSetParamStr.nx[4][0], dataSetParamStr.nx[4][1], dataSetParamStr.nx[4][2], dataSetParamStr.nx[4][3])); + delete[] dataSetSmallArray; +} - SPtr<RelaxationFactorArray3D> mRelaxationFactor; - if ((dataSetParamStr.nx[5][0]==0)&&(dataSetParamStr.nx[5][1]==0)&&(dataSetParamStr.nx[5][2]==0)) - mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(); - else - mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[5], dataSetParamStr.nx[5][0], dataSetParamStr.nx[5][1], dataSetParamStr.nx[5][2])); +void MPIIOMigrationCoProcessor::readRelaxationFactor(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); - SPtr<DistributionArray3D> mFdistributions(new D3Q27EsoTwist3DSplittedVector()); + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readRelaxationFactor start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[6], dataSetParamStr.nx[6][0], dataSetParamStr.nx[6][1], dataSetParamStr.nx[6][2], dataSetParamStr.nx[6][3]))); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[7], dataSetParamStr.nx[7][0], dataSetParamStr.nx[7][1], dataSetParamStr.nx[7][2], dataSetParamStr.nx[7][3]))); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[8], dataSetParamStr.nx[8][0], dataSetParamStr.nx[8][1], dataSetParamStr.nx[8][2]))); - - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(dataSetParamStr.nx1); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(dataSetParamStr.nx2); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(dataSetParamStr.nx3); + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpRelaxationFactor.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); - SPtr<DataSet3D> dataSetPtr = SPtr<DataSet3D>(new DataSet3D()); - dataSetPtr->setAverageValues(mAverageValues); - dataSetPtr->setAverageVelocity(mAverageVelocity); - dataSetPtr->setAverageFluctuations(mAverageFluktuations); - dataSetPtr->setAverageTriplecorrelations(mAverageTriplecorrelations); - dataSetPtr->setShearStressValues(mShearStressValues); - dataSetPtr->setRelaxationFactor(mRelaxationFactor); - dataSetPtr->setFdistributions(mFdistributions); + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr; + memset(&dataSetParamStr, 0, sizeof(dataSetParam)); + + // read from the grid the blocks, that belong to this process + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + MPI_File_read_at(file_handler, (MPI_Offset)0, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + int ic = 0; + MPI_Offset read_offset; + size_t sizeofOneDataSet = size_t(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + read_offset = (MPI_Offset)(sizeof(dataSetParam) + block->getGlobalID() * sizeofOneDataSet); + MPI_File_read_at(file_handler, read_offset, &dataSetSmallArray[ic], 1, dataSetSmallType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(DataSetSmall)), &doubleValuesArray[ic * doubleCountInBlock], 1, dataSetDoubleType, MPI_STATUS_IGNORE); + ic++; + } + } + + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readRelaxationFactor time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readRelaxationFactor start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; + + // fill RelaxationFactor array + SPtr<RelaxationFactorArray3D> mRelaxationFactor; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0)) + // mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(); + //else + mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2])); // find the nesessary block and fill it - SPtr<Block3D> block = grid->getBlock(dataSetArray[n].globalID); - UbTupleInt3 blockNX = grid->getBlockNX(); - this->lbmKernel->setNX(std::array<int, 3>{ {val<1>(blockNX), val<2>(blockNX), val<3>(blockNX)}}); - SPtr<LBMKernel> kernel = this->lbmKernel->clone(); - kernel->setGhostLayerWidth(dataSetArray[n].ghostLayerWidth); - kernel->setCollisionFactor(dataSetArray[n].collFactor); - kernel->setDeltaT(dataSetArray[n].deltaT); - kernel->setCompressible(dataSetArray[n].compressible); - kernel->setWithForcing(dataSetArray[n].withForcing); - kernel->setDataSet(dataSetPtr); - block->setKernel(kernel); + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].globalID); + block->kernel->getDataSet()->setRelaxationFactor(mRelaxationFactor); } - delete[] dataSetArray; + MPI_Type_free(&dataSetDoubleType); if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readDataSet end of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readRelaxationFactor end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } + + delete[] dataSetSmallArray; } void MPIIOMigrationCoProcessor::readBoundaryConds(int step) @@ -1075,20 +2382,20 @@ void MPIIOMigrationCoProcessor::readBoundaryConds(int step) if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBoundaryConds start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBoundaryConds start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } double start, finish; if (comm->isRoot()) start = MPI_Wtime(); MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBC.bin"; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin"; int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); int blocksCount = 0; // quantity of the blocks, that belong to this process - + // read from the grid the blocks, that belong to this process std::vector<SPtr<Block3D>> blocksVector[25]; int minInitLevel = this->grid->getCoarsestInitializedLevel(); @@ -1120,13 +2427,12 @@ void MPIIOMigrationCoProcessor::readBoundaryConds(int step) MPI_File_read_at(file_handler, (MPI_Offset)0, &boundCondParamStr, 1, boundCondParamType, MPI_STATUS_IGNORE); MPI_Type_contiguous(boundCondParamStr.bcindexmatrixCount, MPI_INT, &bcindexmatrixType); MPI_Type_commit(&bcindexmatrixType); - mpiTypeFreeFlag = true; int ic = 0; MPI_Offset read_offset1, read_offset2; for (int level = minInitLevel; level <= maxInitLevel; level++) { - for(SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level { read_offset1 = (MPI_Offset)(sizeof(boundCondParam) + block->getGlobalID() * sizeof(size_t)); @@ -1156,7 +2462,7 @@ void MPIIOMigrationCoProcessor::readBoundaryConds(int step) for (size_t ibc = 0; ibc<bcAddArray[ic].boundCond_count; ibc++) { SPtr<BoundaryConditions> bc; - if (memcmp(&bcArray[ibc], nullBouCond, sizeof(BoundaryCondition))==0) + if (memcmp(&bcArray[ibc], nullBouCond, sizeof(BoundaryCondition)) == 0) bc = SPtr<BoundaryConditions>(); else { @@ -1192,13 +2498,11 @@ void MPIIOMigrationCoProcessor::readBoundaryConds(int step) for (int b2 = 0; b2 < bcAddArray[ic].indexContainer_count; b2++) indexContainerV.push_back(intArray2[b2]); - + CbArray3D<int, IndexerX3X2X1> bcim(bcindexmatrixV, boundCondParamStr.nx1, boundCondParamStr.nx2, boundCondParamStr.nx3); SPtr<Block3D> block1 = grid->getBlock(bcAddArray[ic].globalID); - //SPtr<BCProcessor> bcProc(new BCProcessor()); SPtr<BCProcessor> bcProc = bcProcessor->clone(block1->getKernel()); - //SPtr<BCArray3D> bcArr = bcProc->getBCArray(); SPtr<BCArray3D> bcArr(new BCArray3D()); bcArr->bcindexmatrix = bcim; bcArr->bcvector = bcVector; @@ -1207,23 +2511,26 @@ void MPIIOMigrationCoProcessor::readBoundaryConds(int step) block1->getKernel()->setBCProcessor(bcProc); - delete bcArray; - delete intArray1; - delete intArray2; + delete bcArray; + delete intArray1; + delete intArray2; - ic++; + ic++; } } MPI_File_close(&file_handler); + MPI_Type_free(&bcindexmatrixType); + delete nullBouCond; if (comm->isRoot()) { - UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBoundaryConds end of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIOMigrationCoProcessor::readBoundaryConds end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } } + ////////////////////////////////////////////////////////////////////////// void MPIIOMigrationCoProcessor::setLBMKernel(SPtr<LBMKernel> kernel) { diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIOMigrationCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/MPIIOMigrationCoProcessor.h index e7d61504d..ad87d6ba4 100644 --- a/source/VirtualFluidsCore/CoProcessors/MPIIOMigrationCoProcessor.h +++ b/source/VirtualFluidsCore/CoProcessors/MPIIOMigrationCoProcessor.h @@ -1,5 +1,5 @@ -#ifndef _MPIIORestart21CoProcessor_H_ -#define _MPIIORestart21CoProcessor_H_ +#ifndef _MPIIOMigrationCoProcessor_H_ +#define _MPIIOMigrationCoProcessor_H_ #include <mpi.h> #include <PointerDefinitions.h> @@ -15,14 +15,13 @@ class LBMKernel; //! \class MPIWriteBlocksCoProcessor //! \brief Writes the grid each timestep into the files and reads the grip from the files before regenerating -//! \author Alena Karanchuk -class MPIIOMigrationCoProcessor: public CoProcessor +class MPIIOMigrationCoProcessor : public CoProcessor { //! \struct GridParam //! \brief Structure describes parameters of the grid //! \details The structure is nessasary to restore the grid correctly struct GridParam - { + { double trafoParams[33]; double deltaX; int blockNx1; @@ -36,47 +35,46 @@ class MPIIOMigrationCoProcessor: public CoProcessor bool periodicX3; bool active; bool transformation; - }; + }; //! \struct Block3d //! \brief Structure contains information of the block //! \details The structure is used to write the data describing the block in the grid when saving the grid //! and to read it when restoring the grid struct Block3d - { - int x1; - int x2; - int x3; + { + int x1; + int x2; + int x3; int bundle; - int rank; - int lrank; - int part; - int globalID; - int localID; - int level; - int interpolationFlagCF; - int interpolationFlagFC; - int counter; - bool active; - }; + int rank; + int lrank; + int part; + int globalID; + int localID; + int level; + int interpolationFlagCF; + int interpolationFlagFC; + int counter; + bool active; + }; //! \struct dataSetParam //! \brief Structure describes parameters of the dataSet that are equal in all blocks //! \details The structure used to store some parameters needed to restore dataSet arrays struct dataSetParam { - int nx1; + int nx1; int nx2; int nx3; - int nx[9][4]; // 9 arrays x (nx1, nx2, nx3, nx4) - int doubleCountInBlock; // how many double-values are in all arrays dataSet in one (any) block + int nx[4]; //nx1, nx2, nx3, nx4 }; //! \struct dataSet //! \brief Structure containes information identifying the block //! \details The structure is used to find the needed block in the grid when restoring a dataSet struct DataSet - { + { double collFactor; double deltaT; int globalID; @@ -84,32 +82,44 @@ class MPIIOMigrationCoProcessor: public CoProcessor bool compressible; bool withForcing; }; - + + //! \struct dataSetSmall + //! \brief Structure containes information identifying the block + //! \details The structure is used to find the needed block in the grid when restoring a dataSet arrays + struct DataSetSmall + { + int globalID; + //int x1; + //int x2; + //int x3; + //int level; + }; + //! \struct BoundaryCondition //! \brief Structure containes information about boundary conditions of the block //! \details The structure is used to write data describing boundary conditions of the blocks when saving the grid //! and to read it when restoring the grid struct BoundaryCondition - { - long long noslipBoundaryFlags; // MPI_LONG_LONG - long long slipBoundaryFlags; - long long velocityBoundaryFlags; - long long densityBoundaryFlags; - long long wallModelBoundaryFlags; - - float bcVelocityX1; - float bcVelocityX2; - float bcVelocityX3; - float bcDensity; - - float bcLodiDensity; - float bcLodiVelocityX1; - float bcLodiVelocityX2; - float bcLodiVelocityX3; - float bcLodiLentgh; - - float nx1,nx2,nx3; - float q[26]; // MPI_FLOAT + { + long long noslipBoundaryFlags; // MPI_LONG_LONG + long long slipBoundaryFlags; + long long velocityBoundaryFlags; + long long densityBoundaryFlags; + long long wallModelBoundaryFlags; + + float bcVelocityX1; + float bcVelocityX2; + float bcVelocityX3; + float bcDensity; + + float bcLodiDensity; + float bcLodiVelocityX1; + float bcLodiVelocityX2; + float bcLodiVelocityX3; + float bcLodiLentgh; + + float nx1, nx2, nx3; + float q[26]; // MPI_FLOAT char algorithmType; }; @@ -119,7 +129,7 @@ class MPIIOMigrationCoProcessor: public CoProcessor //! \details The structure used to store some parameters needed to restore boundaryConditions arrays struct boundCondParam { - int nx1; + int nx1; int nx2; int nx3; int bcindexmatrixCount; // how many bcindexmatrix-values in one (any) block @@ -131,16 +141,26 @@ class MPIIOMigrationCoProcessor: public CoProcessor //! \details The structure is used to find the needed block in the grid when restoring a dataSet //! and to set common parameters struct BCAdd - { + { int globalID; - //int x1; // to find the right block - //int x2; - //int x3; - //int level; + //int x1; // to find the right block + //int x2; + //int x3; + //int level; int boundCond_count; // how many BoundaryCondition-structures are in this block int indexContainer_count; // how many indexContainer-values are in this block }; + struct DSArraysPresence + { + bool isAverageDensityArrayPresent; + bool isAverageVelocityArrayPresent; + bool isAverageFluktuationsArrayPresent; + bool isAverageTripleArrayPresent; + bool isShearStressValArrayPresent; + bool isRelaxationFactorPresent; + }; + public: MPIIOMigrationCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s, const std::string& path, SPtr<Communicator> comm); virtual ~MPIIOMigrationCoProcessor(); @@ -148,17 +168,30 @@ public: void process(double step); //! Reads the grid from the files before grid reconstruction void restart(int step); - //! Writes the blocks of the grid into the file outputBlocks.bin + //! Writes the blocks of the grid into the file cpBlocks.bin void writeBlocks(int step); - //! Writes the datasets of the blocks into the file outputDataSet.bin + //! Writes the datasets of the blocks into the file cpDataSet.bin void writeDataSet(int step); - //! Writes the boundary conditions of the blocks into the file outputBoundCond.bin + void writeAverageDensityArray(int step); + void writeAverageVelocityArray(int step); + void writeAverageFluktuationsArray(int step); + void writeAverageTripleArray(int step); + void writeShearStressValArray(int step); + void writeRelaxationFactor(int step); + //! Writes the boundary conditions of the blocks into the file cpBC.bin void writeBoundaryConds(int step); - //! Reads the blocks of the grid from the file outputBlocks.bin + + //! Reads the blocks of the grid from the file cpBlocks.bin void readBlocks(int step); - //! Reads the datasets of the blocks from the file outputDataSet.bin + //! Reads the datasets of the blocks from the file cpDataSet.bin void readDataSet(int step); - //! Reads the boundary conditions of the blocks from the file outputBoundCond.bin + void readAverageDensityArray(int step); + void readAverageVelocityArray(int step); + void readAverageFluktuationsArray(int step); + void readAverageTripleArray(int step); + void readShearStressValArray(int step); + void readRelaxationFactor(int step); + //! Reads the boundary conditions of the blocks from the file cpBC.bin void readBoundaryConds(int step); //! The function sets LBMKernel void setLBMKernel(SPtr<LBMKernel> kernel); @@ -170,11 +203,12 @@ public: protected: std::string path; SPtr<Communicator> comm; - bool mpiTypeFreeFlag; private: - MPI_Datatype gridParamType, block3dType, dataSetParamType, dataSetType, dataSetDoubleType, boundCondParamType, boundCondType, boundCondTypeAdd, bcindexmatrixType; - dataSetParam dataSetParamStr; + MPI_Datatype gridParamType, block3dType, arrayPresenceType; + MPI_Datatype dataSetParamType, dataSetType, dataSetSmallType, dataSetDoubleType; + MPI_Datatype boundCondParamType, boundCondType, boundCondTypeAdd, bcindexmatrixType; + boundCondParam boundCondParamStr; SPtr<LBMKernel> lbmKernel; SPtr<BCProcessor> bcProcessor; diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.cpp index deb081cbe..0188db222 100644 --- a/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.cpp +++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.cpp @@ -26,12 +26,10 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(SPtr<Grid3D> grid, SPtr<UbSched SPtr<Communicator> comm) : CoProcessor(grid, s), path(path), - comm(comm), - mpiTypeFreeFlag(false) + comm(comm) { - UbSystem::makeDirectory(path+"/mpi_io_cp"); + UbSystem::makeDirectory(path + "/mpi_io_cp"); - memset(&dataSetParamStr, 0, sizeof(dataSetParamStr)); memset(&boundCondParamStr, 0, sizeof(boundCondParamStr)); //------------------------- define MPI types --------------------------------- @@ -42,12 +40,12 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(SPtr<Grid3D> grid, SPtr<UbSched offsetsGP[0] = 0; MPI_Type_get_extent(MPI_DOUBLE, &lbGP, &extentGP); - offsetsGP[1] = blocksGP[0]*extentGP; + offsetsGP[1] = blocksGP[0] * extentGP; MPI_Type_get_extent(MPI_INT, &lbGP, &extentGP); - offsetsGP[2] = offsetsGP[1]+blocksGP[1]*extentGP; + offsetsGP[2] = offsetsGP[1] + blocksGP[1] * extentGP; - MPI_Type_create_struct (3, blocksGP, offsetsGP, typesGP, &gridParamType); + MPI_Type_create_struct(3, blocksGP, offsetsGP, typesGP, &gridParamType); MPI_Type_commit(&gridParamType); //----------------------------------------------------------------------- @@ -58,14 +56,14 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(SPtr<Grid3D> grid, SPtr<UbSched offsetsBlock[0] = 0; MPI_Type_get_extent(MPI_INT, &lbBlock, &extentBlock); - offsetsBlock[1] = blocksBlock[0]*extentBlock; + offsetsBlock[1] = blocksBlock[0] * extentBlock; MPI_Type_create_struct(2, blocksBlock, offsetsBlock, typesBlock, &block3dType); MPI_Type_commit(&block3dType); //----------------------------------------------------------------------- - MPI_Type_contiguous(40, MPI_INT, &dataSetParamType); + MPI_Type_contiguous(7, MPI_INT, &dataSetParamType); MPI_Type_commit(&dataSetParamType); //----------------------------------------------------------------------- @@ -76,16 +74,21 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(SPtr<Grid3D> grid, SPtr<UbSched offsetsDatatSet[0] = 0; MPI_Type_get_extent(MPI_DOUBLE, &lbDataSet, &extentDataSet); - offsetsDatatSet[1] = blocksDataSet[0]*extentDataSet; + offsetsDatatSet[1] = blocksDataSet[0] * extentDataSet; MPI_Type_get_extent(MPI_INT, &lbDataSet, &extentDataSet); - offsetsDatatSet[2] = offsetsDatatSet[1]+blocksDataSet[1]*extentDataSet; + offsetsDatatSet[2] = offsetsDatatSet[1] + blocksDataSet[1] * extentDataSet; MPI_Type_create_struct(3, blocksDataSet, offsetsDatatSet, typesDataSet, &dataSetType); MPI_Type_commit(&dataSetType); //----------------------------------------------------------------------- + MPI_Type_contiguous(4, MPI_INT, &dataSetSmallType); + MPI_Type_commit(&dataSetSmallType); + + //----------------------------------------------------------------------- + MPI_Type_contiguous(4, MPI_INT, &boundCondParamType); MPI_Type_commit(&boundCondParamType); @@ -97,10 +100,10 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(SPtr<Grid3D> grid, SPtr<UbSched offsetsBC[0] = 0; MPI_Type_get_extent(MPI_LONG_LONG_INT, &lbBC, &extentBC); - offsetsBC[1] = blocksBC[0]*extentBC; + offsetsBC[1] = blocksBC[0] * extentBC; MPI_Type_get_extent(MPI_FLOAT, &lbBC, &extentBC); - offsetsBC[2] = offsetsBC[1]+blocksBC[1]*extentBC; + offsetsBC[2] = offsetsBC[1] + blocksBC[1] * extentBC; MPI_Type_create_struct(3, blocksBC, offsetsBC, typesBC, &boundCondType); MPI_Type_commit(&boundCondType); @@ -115,6 +118,11 @@ MPIIORestartCoProcessor::MPIIORestartCoProcessor(SPtr<Grid3D> grid, SPtr<UbSched MPI_Type_contiguous(6, MPI_INT, &boundCondTypeAdd); MPI_Type_commit(&boundCondTypeAdd); + //--------------------------------------- + + MPI_Type_contiguous(6, MPI_CHAR, &arrayPresenceType); + MPI_Type_commit(&arrayPresenceType); + } ////////////////////////////////////////////////////////////////////////// MPIIORestartCoProcessor::~MPIIORestartCoProcessor() @@ -123,16 +131,12 @@ MPIIORestartCoProcessor::~MPIIORestartCoProcessor() MPI_Type_free(&block3dType); MPI_Type_free(&dataSetParamType); MPI_Type_free(&dataSetType); + MPI_Type_free(&dataSetSmallType); MPI_Type_free(&boundCondParamType); MPI_Type_free(&boundCondType); MPI_Type_free(&boundCondType1000); MPI_Type_free(&boundCondTypeAdd); - - if (mpiTypeFreeFlag) - { - MPI_Type_free(&dataSetDoubleType); - MPI_Type_free(&bcindexmatrixType); - } + MPI_Type_free(&arrayPresenceType); } ////////////////////////////////////////////////////////////////////////// @@ -140,49 +144,91 @@ void MPIIORestartCoProcessor::process(double step) { if (scheduler->isDue(step)) { - if (comm->isRoot()) UBLOG(logINFO, "MPIIORestartCoProcessor save step: "<<step); + if (comm->isRoot()) UBLOG(logINFO, "MPIIORestartCoProcessor save step: " << step); if (comm->isRoot()) UBLOG(logINFO, "Save check point - start"); /*if (comm->isRoot())*/ clearAllFiles((int)step); + writeBlocks((int)step); writeDataSet((int)step); writeBoundaryConds((int)step); + if (comm->isRoot()) UBLOG(logINFO, "Save check point - end"); - - //readDataSet((int)step); - //readBoundaryConds((int)step); } } ////////////////////////////////////////////////////////////////////////// void MPIIORestartCoProcessor::clearAllFiles(int step) { - MPI_File file_handler1, file_handler2, file_handler3; + MPI_File file_handler; MPI_Info info = MPI_INFO_NULL; MPI_Offset new_size = 0; UbSystem::makeDirectory(path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step)); + std::string filename1 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin"; - //MPI_File_delete(filename1.c_str(), info); - int rc1 = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler1); + int rc1 = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &file_handler); if (rc1 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename1); - MPI_File_set_size(file_handler1, new_size); - //MPI_File_sync(file_handler1); - MPI_File_close(&file_handler1); + MPI_File_set_size(file_handler, new_size); + MPI_File_close(&file_handler); std::string filename2 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin"; - //MPI_File_delete(filename2.c_str(), info); - int rc2 = MPI_File_open(MPI_COMM_WORLD, filename2.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler2); + int rc2 = MPI_File_open(MPI_COMM_WORLD, filename2.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); if (rc2 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename2); - MPI_File_set_size(file_handler2, new_size); - //MPI_File_sync(file_handler2); - MPI_File_close(&file_handler2); + MPI_File_set_size(file_handler, new_size); + MPI_File_close(&file_handler); - std::string filename3 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin"; - //MPI_File_delete(filename3.c_str(), info); - int rc3 = MPI_File_open(MPI_COMM_WORLD, filename3.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler3); + std::string filename3 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpArrays.bin"; + int rc3 = MPI_File_open(MPI_COMM_WORLD, filename3.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); if (rc3 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename3); - MPI_File_set_size(file_handler3, new_size); - //MPI_File_sync(file_handler3); - MPI_File_close(&file_handler3); + MPI_File_set_size(file_handler, new_size); + MPI_File_close(&file_handler); + + std::string filename4 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageDensityArray.bin"; + MPI_File_delete(filename4.c_str(), info); + //int rc4 = MPI_File_open(MPI_COMM_WORLD, filename4.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc4 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename4); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename5 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageVelocityArray.bin"; + MPI_File_delete(filename5.c_str(), info); + //int rc5 = MPI_File_open(MPI_COMM_WORLD, filename5.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc5 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename5); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename6 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageFluktuationsArray.bin"; + MPI_File_delete(filename6.c_str(), info); + //int rc6 = MPI_File_open(MPI_COMM_WORLD, filename6.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc6 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename6); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename7 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageTripleArray.bin"; + MPI_File_delete(filename7.c_str(), info); + //int rc7 = MPI_File_open(MPI_COMM_WORLD, filename7.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc7 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename7); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename8 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpShearStressValArray.bin"; + MPI_File_delete(filename8.c_str(), info); + //int rc8 = MPI_File_open(MPI_COMM_WORLD, filename8.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc8 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename8); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename9 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpRelaxationFactor.bin"; + MPI_File_delete(filename9.c_str(), info); + //int rc9 = MPI_File_open(MPI_COMM_WORLD, filename9.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + //if (rc9 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename9); + //MPI_File_set_size(file_handler, new_size); + //MPI_File_close(&file_handler); + + std::string filename10 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin"; + int rc10 = MPI_File_open(MPI_COMM_WORLD, filename10.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc10 != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename10); + MPI_File_set_size(file_handler, new_size); + MPI_File_close(&file_handler); } ////////////////////////////////////////////////////////////////////////// void MPIIORestartCoProcessor::writeBlocks(int step) @@ -190,12 +236,12 @@ void MPIIORestartCoProcessor::writeBlocks(int step) int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); //MPI_Comm_size(MPI_COMM_WORLD, &size); - size=1; + size = 1; if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::writeBlocks start collect data rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeBlocks start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! @@ -203,7 +249,7 @@ void MPIIORestartCoProcessor::writeBlocks(int step) int maxInitLevel = this->grid->getFinestInitializedLevel(); std::vector<SPtr<Block3D>> blocksVector[25]; // max 25 levels - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { //grid->getBlocks(level, rank, blockVector[level]); grid->getBlocks(level, blocksVector[level]); @@ -266,9 +312,9 @@ void MPIIORestartCoProcessor::writeBlocks(int step) Block3d* block3dArray = new Block3d[blocksCount]; int ic = 0; - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { - for(SPtr<Block3D> block : blocksVector[level]) // all the blocks of the current level + for (SPtr<Block3D> block : blocksVector[level]) // all the blocks of the current level { // save data describing the block block3dArray[ic].x1 = block->getX1(); @@ -292,8 +338,8 @@ void MPIIORestartCoProcessor::writeBlocks(int step) if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::writeBlocks start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeBlocks start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } MPI_File file_handler; @@ -319,20 +365,20 @@ void MPIIORestartCoProcessor::writeBlocks(int step) start = MPI_Wtime(); // each process writes the quantity of it's blocks - MPI_File_write_at(file_handler, (MPI_Offset)(rank*sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); // each process writes parameters of the grid MPI_File_write_at(file_handler, write_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE); // each process writes it's blocks - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset +sizeof(GridParam)), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(GridParam)), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE); } MPI_File_sync(file_handler); MPI_File_close(&file_handler); - + if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIORestartCoProcessor::writeBlocks time: "<<finish-start<<" s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeBlocks time: " << finish - start << " s"); } delete[] block3dArray; @@ -350,201 +396,122 @@ void MPIIORestartCoProcessor::writeDataSet(int step) std::vector<SPtr<Block3D>> blocksVector[25]; int minInitLevel = this->grid->getCoarsestInitializedLevel(); int maxInitLevel = this->grid->getFinestInitializedLevel(); - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { grid->getBlocks(level, rank, blocksVector[level]); blocksCount += static_cast<int>(blocksVector[level].size()); } + dataSetParam dataSetParamStr1, dataSetParamStr2, dataSetParamStr3; DataSet* dataSetArray = new DataSet[blocksCount]; std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::writeDataSet start collect data rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeDataSet start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } + DSArraysPresence arrPresence; bool firstBlock = true; + int doubleCountInBlock = 0; int ic = 0; - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { - for(SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level { dataSetArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid dataSetArray[ic].x2 = block->getX2(); dataSetArray[ic].x3 = block->getX3(); dataSetArray[ic].level = block->getLevel(); - //if (block->getKernel()) - //{ dataSetArray[ic].ghostLayerWidth = block->getKernel()->getGhostLayerWidth(); dataSetArray[ic].collFactor = block->getKernel()->getCollisionFactor(); dataSetArray[ic].deltaT = block->getKernel()->getDeltaT(); dataSetArray[ic].compressible = block->getKernel()->getCompressible(); dataSetArray[ic].withForcing = block->getKernel()->getWithForcing(); - //} - //else - //{ - // dataSetArray[ic].ghostLayerWidth = 0; - // dataSetArray[ic].collFactor = 0.0; - // dataSetArray[ic].deltaT = 0.0; - // dataSetArray[ic].compressible = false; - // dataSetArray[ic].withForcing = false; - //} - //std::cout << "ic="<<ic<<"-"<<dataSetArray[ic].x1 << "," << dataSetArray[ic].x2 << "," << dataSetArray[ic].x3 << "," << dataSetArray[ic].level << "," << dataSetArray[ic].ghostLayerWidth; - //std::cout << dataSetArray[ic].collFactor<<","<<dataSetArray[ic].deltaT<<","<<dataSetArray[ic].compressible<<","<<dataSetArray[ic].withForcing<<std::endl; - //dataSetArrayGW[ic].x1 = dataSetArray[ic].x1; - //dataSetArrayGW[ic].x2 = dataSetArray[ic].x2; - //dataSetArrayGW[ic].x3 = dataSetArray[ic].x3; - //dataSetArrayGW[ic].level = dataSetArray[ic].level; - //dataSetArrayGW[ic].ghostLayerWidth = dataSetArray[ic].ghostLayerWidth; - //dataSetArrayGW[ic].collFactor = dataSetArray[ic].collFactor; - //dataSetArrayGW[ic].deltaT = dataSetArray[ic].deltaT; - //dataSetArrayGW[ic].compressible = dataSetArray[ic].compressible; - //dataSetArrayGW[ic].withForcing = dataSetArray[ic].withForcing; - - if (firstBlock /*&& block->getKernel()*/) // when first (any) valid block... - { - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageDensityArray = block->getKernel()->getDataSet()->getAverageDencity(); - if (averageDensityArray) - { - dataSetParamStr.nx[0][0] = static_cast<int>(averageDensityArray->getNX1()); - dataSetParamStr.nx[0][1] = static_cast<int>(averageDensityArray->getNX2()); - dataSetParamStr.nx[0][2] = static_cast<int>(averageDensityArray->getNX3()); - dataSetParamStr.nx[0][3] = static_cast<int>(averageDensityArray->getNX4()); - } - - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity(); - if (AverageVelocityArray3DPtr) - { - dataSetParamStr.nx[1][0] = static_cast<int>(AverageVelocityArray3DPtr->getNX1()); - dataSetParamStr.nx[1][1] = static_cast<int>(AverageVelocityArray3DPtr->getNX2()); - dataSetParamStr.nx[1][2] = static_cast<int>(AverageVelocityArray3DPtr->getNX3()); - dataSetParamStr.nx[1][3] = static_cast<int>(AverageVelocityArray3DPtr->getNX4()); - } - - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations(); - if (AverageFluctArray3DPtr) - { - dataSetParamStr.nx[2][0] = static_cast<int>(AverageFluctArray3DPtr->getNX1()); - dataSetParamStr.nx[2][1] = static_cast<int>(AverageFluctArray3DPtr->getNX2()); - dataSetParamStr.nx[2][2] = static_cast<int>(AverageFluctArray3DPtr->getNX3()); - dataSetParamStr.nx[2][3] = static_cast<int>(AverageFluctArray3DPtr->getNX4()); - } - - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations(); - if (AverageTripleArray3DPtr) - { - dataSetParamStr.nx[3][0] = static_cast<int>(AverageTripleArray3DPtr->getNX1()); - dataSetParamStr.nx[3][1] = static_cast<int>(AverageTripleArray3DPtr->getNX2()); - dataSetParamStr.nx[3][2] = static_cast<int>(AverageTripleArray3DPtr->getNX3()); - dataSetParamStr.nx[3][3] = static_cast<int>(AverageTripleArray3DPtr->getNX4()); - } - - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues(); - if (ShearStressValArray3DPtr) - { - dataSetParamStr.nx[4][0] = static_cast<int>(ShearStressValArray3DPtr->getNX1()); - dataSetParamStr.nx[4][1] = static_cast<int>(ShearStressValArray3DPtr->getNX2()); - dataSetParamStr.nx[4][2] = static_cast<int>(ShearStressValArray3DPtr->getNX3()); - dataSetParamStr.nx[4][3] = static_cast<int>(ShearStressValArray3DPtr->getNX4()); - } - SPtr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor(); - if (relaxationFactor3DPtr) - { - dataSetParamStr.nx[5][0] = static_cast<int>(relaxationFactor3DPtr->getNX1()); - dataSetParamStr.nx[5][1] = static_cast<int>(relaxationFactor3DPtr->getNX2()); - dataSetParamStr.nx[5][2] = static_cast<int>(relaxationFactor3DPtr->getNX3()); - dataSetParamStr.nx[5][3] = 1; - } + SPtr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions()); + CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions(); + CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions(); + CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions(); - SPtr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions()); - CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions(); + if (firstBlock) // when first (any) valid block... + { if (localDistributions) { - dataSetParamStr.nx[6][0] = static_cast<int>(localDistributions->getNX1()); - dataSetParamStr.nx[6][1] = static_cast<int>(localDistributions->getNX2()); - dataSetParamStr.nx[6][2] = static_cast<int>(localDistributions->getNX3()); - dataSetParamStr.nx[6][3] = static_cast<int>(localDistributions->getNX4()); + dataSetParamStr1.nx[0] = static_cast<int>(localDistributions->getNX1()); + dataSetParamStr1.nx[1] = static_cast<int>(localDistributions->getNX2()); + dataSetParamStr1.nx[2] = static_cast<int>(localDistributions->getNX3()); + dataSetParamStr1.nx[3] = static_cast<int>(localDistributions->getNX4()); } - - CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions(); if (nonLocalDistributions) { - dataSetParamStr.nx[7][0] = static_cast<int>(nonLocalDistributions->getNX1()); - dataSetParamStr.nx[7][1] = static_cast<int>(nonLocalDistributions->getNX2()); - dataSetParamStr.nx[7][2] = static_cast<int>(nonLocalDistributions->getNX3()); - dataSetParamStr.nx[7][3] = static_cast<int>(nonLocalDistributions->getNX4()); + dataSetParamStr2.nx[0] = static_cast<int>(nonLocalDistributions->getNX1()); + dataSetParamStr2.nx[1] = static_cast<int>(nonLocalDistributions->getNX2()); + dataSetParamStr2.nx[2] = static_cast<int>(nonLocalDistributions->getNX3()); + dataSetParamStr2.nx[3] = static_cast<int>(nonLocalDistributions->getNX4()); } - - CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions(); if (zeroDistributions) { - dataSetParamStr.nx[8][0] = static_cast<int>(zeroDistributions->getNX1()); - dataSetParamStr.nx[8][1] = static_cast<int>(zeroDistributions->getNX2()); - dataSetParamStr.nx[8][2] = static_cast<int>(zeroDistributions->getNX3()); - dataSetParamStr.nx[8][3] = 1; + dataSetParamStr3.nx[0] = static_cast<int>(zeroDistributions->getNX1()); + dataSetParamStr3.nx[1] = static_cast<int>(zeroDistributions->getNX2()); + dataSetParamStr3.nx[2] = static_cast<int>(zeroDistributions->getNX3()); + dataSetParamStr3.nx[3] = 1; } // ... than save some parameters that are equal in all dataSets - dataSetParamStr.nx1 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX1()); - dataSetParamStr.nx2 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX2()); - dataSetParamStr.nx3 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX3()); + dataSetParamStr1.nx1 = dataSetParamStr2.nx1 = dataSetParamStr3.nx1 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX1()); + dataSetParamStr1.nx2 = dataSetParamStr2.nx2 = dataSetParamStr3.nx2 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX2()); + dataSetParamStr1.nx3 = dataSetParamStr2.nx3 = dataSetParamStr3.nx3 = static_cast<int>(block->getKernel()->getDataSet()->getFdistributions()->getNX3()); - firstBlock = false; + doubleCountInBlock = dataSetParamStr1.nx[0] * dataSetParamStr1.nx[1] * dataSetParamStr1.nx[2] * dataSetParamStr1.nx[3] + + dataSetParamStr2.nx[0] * dataSetParamStr2.nx[1] * dataSetParamStr2.nx[2] * dataSetParamStr2.nx[3] + + dataSetParamStr3.nx[0] * dataSetParamStr3.nx[1] * dataSetParamStr3.nx[2] * dataSetParamStr3.nx[3]; - // how many elements are in all arrays of DataSet (equal in all blocks) - int doubleCount = 0, temp; - for (int i = 0; i<9; i++) // 9 arrays ( averageValues, averageVelocity, averageFluktuations, - { // averageTriplecorrelations, shearStressValues, relaxationFactor, 3 * fdistributions - temp = 1; - for (int ii = 0; ii < 4; ii++) - { - temp *= dataSetParamStr.nx[i][ii]; - //std::cout << ",dataSetParamStr.nx[" << i << "][" << ii << "]" << "=" << dataSetParamStr.nx[i][ii]; - } - doubleCount += temp; - } - dataSetParamStr.doubleCountInBlock = doubleCount; - } - //std::cout << ",doubleCountInBlock="<<dataSetParamStr.doubleCountInBlock<< "," << dataSetParamStr.nx1 << "," << dataSetParamStr.nx2 << "," << dataSetParamStr.nx3 << std::endl; + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageDensityArray = block->getKernel()->getDataSet()->getAverageDencity(); + if (averageDensityArray) + arrPresence.isAverageDensityArrayPresent = true; + else + arrPresence.isAverageDensityArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageValuesArray3D = block->getKernel()->getDataSet()->getAverageDencity(); - if (averageValuesArray3D &&(dataSetParamStr.nx[0][0]>0)&&(dataSetParamStr.nx[0][1]>0)&&(dataSetParamStr.nx[0][2]>0)&&(dataSetParamStr.nx[0][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), averageValuesArray3D->getDataVector().begin(), averageValuesArray3D->getDataVector().end()); + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity(); + if (AverageVelocityArray3DPtr) + arrPresence.isAverageVelocityArrayPresent = true; + else + arrPresence.isAverageVelocityArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity(); - if (AverageVelocityArray3DPtr&&(dataSetParamStr.nx[1][0]>0)&&(dataSetParamStr.nx[1][1]>0)&&(dataSetParamStr.nx[1][2]>0)&&(dataSetParamStr.nx[1][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), AverageVelocityArray3DPtr->getDataVector().begin(), AverageVelocityArray3DPtr->getDataVector().end()); + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations(); + if (AverageFluctArray3DPtr) + arrPresence.isAverageFluktuationsArrayPresent = true; + else + arrPresence.isAverageFluktuationsArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations(); - if (AverageFluctArray3DPtr&&(dataSetParamStr.nx[2][0]>0)&&(dataSetParamStr.nx[2][1]>0)&&(dataSetParamStr.nx[2][2]>0)&&(dataSetParamStr.nx[2][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), AverageFluctArray3DPtr->getDataVector().begin(), AverageFluctArray3DPtr->getDataVector().end()); + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations(); + if (AverageTripleArray3DPtr) + arrPresence.isAverageTripleArrayPresent = true; + else + arrPresence.isAverageTripleArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations(); - if (AverageTripleArray3DPtr&&(dataSetParamStr.nx[3][0]>0)&&(dataSetParamStr.nx[3][1]>0)&&(dataSetParamStr.nx[3][2]>0)&&(dataSetParamStr.nx[3][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), AverageTripleArray3DPtr->getDataVector().begin(), AverageTripleArray3DPtr->getDataVector().end()); + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues(); + if (ShearStressValArray3DPtr) + arrPresence.isShearStressValArrayPresent = true; + else + arrPresence.isShearStressValArrayPresent = false; - SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues(); - if (ShearStressValArray3DPtr&&(dataSetParamStr.nx[4][0]>0)&&(dataSetParamStr.nx[4][1]>0)&&(dataSetParamStr.nx[4][2]>0)&&(dataSetParamStr.nx[4][3]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), ShearStressValArray3DPtr->getDataVector().begin(), ShearStressValArray3DPtr->getDataVector().end()); + SPtr< CbArray3D<LBMReal, IndexerX3X2X1> > relaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor(); + if (relaxationFactor3DPtr) + arrPresence.isRelaxationFactorPresent = true; + else + arrPresence.isRelaxationFactorPresent = false; - SPtr< CbArray3D<LBMReal, IndexerX3X2X1> > RelaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor(); - if (RelaxationFactor3DPtr&&(dataSetParamStr.nx[5][0]>0)&&(dataSetParamStr.nx[5][1]>0)&&(dataSetParamStr.nx[5][2]>0)) - doubleValuesArray.insert(doubleValuesArray.end(), RelaxationFactor3DPtr->getDataVector().begin(), RelaxationFactor3DPtr->getDataVector().end()); + firstBlock = false; + } - SPtr< D3Q27EsoTwist3DSplittedVector > D3Q27EsoTwist3DSplittedVectorPtr = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(block->getKernel()->getDataSet()->getFdistributions()); - CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getLocalDistributions(); - if (localDistributions&&(dataSetParamStr.nx[6][0]>0)&&(dataSetParamStr.nx[6][1]>0)&&(dataSetParamStr.nx[6][2]>0)&&(dataSetParamStr.nx[6][3]>0)) + if (localDistributions && (dataSetParamStr1.nx[0]>0) && (dataSetParamStr1.nx[1]>0) && (dataSetParamStr1.nx[2]>0) && (dataSetParamStr1.nx[3]>0)) doubleValuesArray.insert(doubleValuesArray.end(), localDistributions->getDataVector().begin(), localDistributions->getDataVector().end()); - - CbArray4D <LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getNonLocalDistributions(); - if (nonLocalDistributions&&(dataSetParamStr.nx[7][0]>0)&&(dataSetParamStr.nx[7][1]>0)&&(dataSetParamStr.nx[7][2]>0)&&(dataSetParamStr.nx[7][3]>0)) + if (nonLocalDistributions && (dataSetParamStr2.nx[0]>0) && (dataSetParamStr2.nx[1]>0) && (dataSetParamStr2.nx[2]>0) && (dataSetParamStr2.nx[3]>0)) doubleValuesArray.insert(doubleValuesArray.end(), nonLocalDistributions->getDataVector().begin(), nonLocalDistributions->getDataVector().end()); - - CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr zeroDistributions = D3Q27EsoTwist3DSplittedVectorPtr->getZeroDistributions(); - if (zeroDistributions&&(dataSetParamStr.nx[8][0]>0)&&(dataSetParamStr.nx[8][1]>0)&&(dataSetParamStr.nx[8][2]>0)) + if (zeroDistributions && (dataSetParamStr3.nx[0]>0) && (dataSetParamStr3.nx[1]>0) && (dataSetParamStr3.nx[2]>0)) doubleValuesArray.insert(doubleValuesArray.end(), zeroDistributions->getDataVector().begin(), zeroDistributions->getDataVector().end()); ic++; @@ -552,16 +519,13 @@ void MPIIORestartCoProcessor::writeDataSet(int step) } // register new MPI-types depending on the block-specific information - MPI_Type_contiguous(dataSetParamStr.doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); MPI_Type_commit(&dataSetDoubleType); - mpiTypeFreeFlag = true; - //doubleValuesArrayGW.assign(doubleValuesArray.begin(), doubleValuesArray.end()); - if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::writeDataSet start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeDataSet start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } // write to the file @@ -572,17 +536,17 @@ void MPIIORestartCoProcessor::writeDataSet(int step) if (size>1) { - if (rank==0) + if (rank == 0) { - next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount * (sizeof(DataSet)+ dataSetParamStr.doubleCountInBlock*sizeof(double)); + next_write_offset = write_offset + 3 * sizeof(dataSetParam) + blocksCount * (sizeof(DataSet) + doubleCountInBlock * sizeof(double)); MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); } else { - MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank-1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount * (sizeof(DataSet)+ dataSetParamStr.doubleCountInBlock*sizeof(double)); - if (rank<size-1) - MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank+1, 5, MPI_COMM_WORLD); + MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_write_offset = write_offset + 3 * sizeof(dataSetParam) + blocksCount * (sizeof(DataSet) + doubleCountInBlock * sizeof(double)); + if (rank<size - 1) + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); } } @@ -591,198 +555,167 @@ void MPIIORestartCoProcessor::writeDataSet(int step) MPI_Info info = MPI_INFO_NULL; -#ifdef HLRN +#ifdef HLRN_LUSTRE MPI_Info_create(&info); MPI_Info_set(info, "striping_factor", "40"); MPI_Info_set(info, "striping_unit", "4M"); #endif MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpDataSet.bin"; - int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE| MPI_MODE_WRONLY, info, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); - - //std::cout << "writeDataSet rank=" << rank << ",blocksCount=" << blocksCount; - //std::cout << ", rank*sizeof(int)=" << (MPI_Offset)(rank * sizeof(int)) << ", write_offset=" << write_offset << std::endl; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); // each process writes the quantity of it's blocks - MPI_File_write_at(file_handler, (MPI_Offset)(rank*sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); // each process writes common parameters of a dataSet - MPI_File_write_at(file_handler, write_offset, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, write_offset, &dataSetParamStr1, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam)), &dataSetParamStr2, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + 2 * sizeof(dataSetParam)), &dataSetParamStr3, 1, dataSetParamType, MPI_STATUS_IGNORE); // each process writes data identifying blocks - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset+sizeof(dataSetParam)), dataSetArray, blocksCount, dataSetType, MPI_STATUS_IGNORE); + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + 3 * sizeof(dataSetParam)), dataSetArray, blocksCount, dataSetType, MPI_STATUS_IGNORE); // each process writes the dataSet arrays - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset+sizeof(dataSetParam)+blocksCount*sizeof(DataSet)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + if (doubleValuesArray.size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + 3 * sizeof(dataSetParam) + blocksCount * sizeof(DataSet)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + MPI_File_sync(file_handler); - - //int blockC; - //MPI_File_read_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blockC, 1, MPI_INT, MPI_STATUS_IGNORE); - //std::cout << "readDataSet rank=" << rank << ", blockC=" << blockC << std::endl; - MPI_File_close(&file_handler); + MPI_Type_free(&dataSetDoubleType); + + delete[] dataSetArray; + if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIORestartCoProcessor::writeDataSet time: "<<finish-start<<" s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeDataSet time: " << finish - start << " s"); } - delete[] dataSetArray; + MPI_File file_handler1; + std::string filename1 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpArrays.bin"; + rc = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler1); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename1); + MPI_File_write_at(file_handler1, (MPI_Offset)0, &arrPresence, 1, arrayPresenceType, MPI_STATUS_IGNORE); + MPI_File_sync(file_handler1); + MPI_File_close(&file_handler1); + + if (arrPresence.isAverageDensityArrayPresent) + writeAverageDensityArray(step); + + if (arrPresence.isAverageVelocityArrayPresent) + writeAverageVelocityArray(step); + + if (arrPresence.isAverageFluktuationsArrayPresent) + writeAverageFluktuationsArray(step); + + if (arrPresence.isAverageTripleArrayPresent) + writeAverageTripleArray(step); + + if (arrPresence.isShearStressValArrayPresent) + writeShearStressValArray(step); + + if (arrPresence.isRelaxationFactorPresent) + writeRelaxationFactor(step); + } -void MPIIORestartCoProcessor::writeBoundaryConds(int step) +void MPIIORestartCoProcessor::writeAverageDensityArray(int step) { int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); - if (comm->isRoot()) - { - UBLOG(logINFO, "MPIIORestartCoProcessor::writeBoundaryConds start collect data rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); - } - - int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! - size_t count_boundCond = 0; // how many BoundaryConditions in all blocks - int count_indexContainer = 0; // how many indexContainer-values in all blocks - size_t byteCount = 0; // how many bytes writes this process in the file + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! std::vector<SPtr<Block3D>> blocksVector[25]; int minInitLevel = this->grid->getCoarsestInitializedLevel(); int maxInitLevel = this->grid->getFinestInitializedLevel(); - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { grid->getBlocks(level, rank, blocksVector[level]); blocksCount += static_cast<int>(blocksVector[level].size()); } - BCAdd* bcAddArray = new BCAdd[blocksCount]; - std::vector<BoundaryCondition> bcVector; - std::vector<int> bcindexmatrixV; - std::vector<int> indexContainerV; - bool bcindexmatrixCountNotInit = true; + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values of the AverageDensityArray in all blocks + dataSetParam dataSetParamStr; + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageDensityArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; int ic = 0; - for (int level = minInitLevel; level<=maxInitLevel; level++) + for (int level = minInitLevel; level <= maxInitLevel; level++) { - for(SPtr<Block3D> block : blocksVector[level]) // all the blocks of the current level + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level { - SPtr<BCArray3D> bcArr = block->getKernel()->getBCProcessor()->getBCArray(); + dataSetSmallArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid + dataSetSmallArray[ic].x2 = block->getX2(); + dataSetSmallArray[ic].x3 = block->getX3(); + dataSetSmallArray[ic].level = block->getLevel(); - bcAddArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid - bcAddArray[ic].x2 = block->getX2(); - bcAddArray[ic].x3 = block->getX3(); - bcAddArray[ic].level = block->getLevel(); - bcAddArray[ic].boundCond_count = 0; // how many BoundaryConditions in this block - bcAddArray[ic].indexContainer_count = 0; // how many indexContainer-values in this block + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > averageDensityArray = block->getKernel()->getDataSet()->getAverageDencity(); - for (int bc = 0; bc<bcArr->getBCVectorSize(); bc++) + if (firstBlock) // when first (any) valid block... { - BoundaryCondition* bouCond = new BoundaryCondition(); - if (bcArr->bcvector[bc]==NULL) - { - memset(bouCond, 0, sizeof(BoundaryCondition)); - } - else - { - bouCond->noslipBoundaryFlags = bcArr->bcvector[bc]->getNoSlipBoundary(); - bouCond->slipBoundaryFlags = bcArr->bcvector[bc]->getSlipBoundary(); - bouCond->velocityBoundaryFlags = bcArr->bcvector[bc]->getVelocityBoundary(); - bouCond->densityBoundaryFlags = bcArr->bcvector[bc]->getDensityBoundary(); - bouCond->wallModelBoundaryFlags = bcArr->bcvector[bc]->getWallModelBoundary(); - bouCond->bcVelocityX1 = bcArr->bcvector[bc]->getBoundaryVelocityX1(); - bouCond->bcVelocityX2 = bcArr->bcvector[bc]->getBoundaryVelocityX2(); - bouCond->bcVelocityX3 = bcArr->bcvector[bc]->getBoundaryVelocityX3(); - bouCond->bcDensity = bcArr->bcvector[bc]->getBoundaryDensity(); - bouCond->bcLodiDensity = bcArr->bcvector[bc]->getDensityLodiDensity(); - bouCond->bcLodiVelocityX1 = bcArr->bcvector[bc]->getDensityLodiVelocityX1(); - bouCond->bcLodiVelocityX2 = bcArr->bcvector[bc]->getDensityLodiVelocityX2(); - bouCond->bcLodiVelocityX3 = bcArr->bcvector[bc]->getDensityLodiVelocityX3(); - bouCond->bcLodiLentgh = bcArr->bcvector[bc]->getDensityLodiLength(); - bouCond->nx1 = bcArr->bcvector[bc]->nx1; - bouCond->nx2 = bcArr->bcvector[bc]->nx2; - bouCond->nx3 = bcArr->bcvector[bc]->nx3; - for (int iq = 0; iq<26; iq++) - bouCond->q[iq] = bcArr->bcvector[bc]->getQ(iq); - bouCond->algorithmType = bcArr->bcvector[bc]->getBcAlgorithmType(); - } - //std::cout << "writeBoundaryConds noslipBoundaryFlags="<< bouCond->noslipBoundaryFlags << std::endl; - bcVector.push_back(*bouCond); - //bcVectorGW.push_back(*bouCond); - //if (bcVector[count_boundCond].noslipBoundaryFlags != bcVectorGW[count_boundCond].noslipBoundaryFlags) - // std::cout << "bcVector[count_boundCond].noslipBoundaryFlags != bcVectorGW[count_boundCond].noslipBoundaryFlags!!!" << std::endl; - bcAddArray[ic].boundCond_count++; - count_boundCond++; - } + //if (averageDensityArray) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(averageDensityArray->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(averageDensityArray->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(averageDensityArray->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(averageDensityArray->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; - // the quantity of elements in the bcindexmatrix array (CbArray3D<int, IndexerX3X2X1>) in bcArray(BCArray3D) is always equal, - // this will be the size of the "write-read-block" in MPI_write_.../MPI_read-functions when writing/reading BoundConds - if (bcindexmatrixCountNotInit) - { - boundCondParamStr.nx1 = static_cast<int>(bcArr->bcindexmatrix.getNX1()); - boundCondParamStr.nx2 = static_cast<int>(bcArr->bcindexmatrix.getNX2()); - boundCondParamStr.nx3 = static_cast<int>(bcArr->bcindexmatrix.getNX3()); - boundCondParamStr.bcindexmatrixCount = static_cast<int>(bcArr->bcindexmatrix.getDataVector().size()); - bcindexmatrixCountNotInit = false; + firstBlock = false; } - bcindexmatrixV.insert(bcindexmatrixV.end(), bcArr->bcindexmatrix.getDataVector().begin(), bcArr->bcindexmatrix.getDataVector().end()); - indexContainerV.insert(indexContainerV.end(), bcArr->indexContainer.begin(), bcArr->indexContainer.end()); - bcAddArray[ic].indexContainer_count = static_cast<int>(bcArr->indexContainer.size()); - count_indexContainer += bcAddArray[ic].indexContainer_count; + if (averageDensityArray && (dataSetParamStr.nx[0] > 0) && (dataSetParamStr.nx[1] > 0) && (dataSetParamStr.nx[2] > 0) && (dataSetParamStr.nx[3] > 0)) + doubleValuesArray.insert(doubleValuesArray.end(), averageDensityArray->getDataVector().begin(), averageDensityArray->getDataVector().end()); ic++; } } - //bcindexmatrixVGW.assign(bcindexmatrixV.begin(), bcindexmatrixV.end()); - //indexContainerVGW.assign(indexContainerV.begin(), indexContainerV.end()); - - MPI_Type_contiguous(boundCondParamStr.bcindexmatrixCount, MPI_INT, &bcindexmatrixType); - MPI_Type_commit(&bcindexmatrixType); - mpiTypeFreeFlag = true; + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); - //how many "big blocks" of BLOCK_SIZE size can by formed - int bcBlockCount = (int)(count_boundCond/BLOCK_SIZE); - if (bcBlockCount * BLOCK_SIZE<count_boundCond) - bcBlockCount += 1; - for (int i = (int)count_boundCond; i<bcBlockCount * BLOCK_SIZE; i++) + if (comm->isRoot()) { - BoundaryCondition* bouCond = new BoundaryCondition(); - memset(bouCond, 0, sizeof(BoundaryCondition)); - bcVector.push_back(*bouCond); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageDensityArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } - byteCount = bcBlockCount * BLOCK_SIZE * sizeof(BoundaryCondition) + blocksCount * sizeof(BCAdd) + sizeof(int) * (blocksCount * boundCondParamStr.bcindexmatrixCount + count_indexContainer); - // write to the file // all processes calculate their offsets (quantity of bytes that the process is going to write) // and notify the next process (with the rank = rank + 1) - MPI_Offset write_offset = (MPI_Offset)(size * (3 * sizeof(int) + sizeof(boundCondParam))); + MPI_Offset write_offset = (MPI_Offset)(size * sizeof(int)); size_t next_write_offset = 0; - if (size>1) + if (size > 1) { - if (rank==0) + if (rank == 0) { - next_write_offset = write_offset + byteCount; + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); } else { - MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank-1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - next_write_offset = write_offset + byteCount; - if (rank<size-1) - MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank+1, 5, MPI_COMM_WORLD); + MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank<size - 1) + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); } } - if (comm->isRoot()) - { - UBLOG(logINFO, "MPIIORestartCoProcessor::writeBoundaryConds start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); - } - double start, finish; if (comm->isRoot()) start = MPI_Wtime(); @@ -795,206 +728,1615 @@ void MPIIORestartCoProcessor::writeBoundaryConds(int step) #endif MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBC.bin"; - int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE|MPI_MODE_WRONLY, info, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); - - MPI_Offset write_offset1 = (MPI_Offset)(rank * (3 * sizeof(int) + sizeof(boundCondParam))); + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageDensityArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); // each process writes the quantity of it's blocks - MPI_File_write_at(file_handler, write_offset1, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); - // each process writes the quantity of "big blocks" of BLOCK_SIZE of boundary conditions - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset1+sizeof(int)), &bcBlockCount, 1, MPI_INT, MPI_STATUS_IGNORE); - // each process writes the quantity of indexContainer elements in all blocks - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset1+2*sizeof(int)), &count_indexContainer, 1, MPI_INT, MPI_STATUS_IGNORE); - // each process writes the quantity of bcindexmatrix elements in every block - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset1+3*sizeof(int)), &boundCondParamStr, 1, boundCondParamType, MPI_STATUS_IGNORE); - - //std::cout << "rank=" << rank << ",(rank*write_offset1)=" << rank*write_offset1<< ",blocksCount=" << blocksCount ; - //std::cout << ", " << rank*write_offset1 + sizeof(int) << ",bcBlockCount=" << bcBlockCount; - //std::cout << ", " << rank*write_offset1 + 2 * sizeof(int) << ",count_indexContainer=" << count_indexContainer; - //std::cout << ", " << rank*write_offset1 + 3 * sizeof(int) << ",boundCondParamStr=" << boundCondParamStr.bcindexmatrixCount << std::endl; + MPI_File_write_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, write_offset, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + // each process writes data identifying blocks + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + // each process writes the dataSet arrays + if (doubleValuesArray.size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); - // each process writes data identifying the blocks - MPI_File_write_at(file_handler, write_offset, bcAddArray, blocksCount, boundCondTypeAdd, MPI_STATUS_IGNORE); - // each process writes boundary conditions - if (bcVector.size()>0) - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset+blocksCount*sizeof(BCAdd)), &bcVector[0], bcBlockCount, boundCondType1000, MPI_STATUS_IGNORE); - // each process writes bcindexmatrix values - if (bcindexmatrixV.size()>0) - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset+blocksCount*sizeof(BCAdd)+bcBlockCount*BLOCK_SIZE*sizeof(BoundaryCondition)), &bcindexmatrixV[0], blocksCount, bcindexmatrixType, MPI_STATUS_IGNORE); - // each process writes indexContainer values - if (indexContainerV.size()>0) - MPI_File_write_at(file_handler, (MPI_Offset)(write_offset+blocksCount*sizeof(BCAdd)+bcBlockCount*BLOCK_SIZE*sizeof(BoundaryCondition)+blocksCount*boundCondParamStr.bcindexmatrixCount*sizeof(int)), &indexContainerV[0], count_indexContainer, MPI_INT, MPI_STATUS_IGNORE); MPI_File_sync(file_handler); - - //std::cout <<"rank="<<rank<<",blocksCount="<< blocksCount<<", "<< bcBlockCount<<", "<< count_indexContainer<<", "<< bcindexmatrixCount << std::endl; - //std::cout <<"rank="<<rank<<",write_offset="<< write_offset <<", "<< write_offset + blocksCount * sizeof(BCAdd) <<", "<< write_offset + blocksCount * sizeof(BCAdd) + bcBlockCount*BLOCK_SIZE * sizeof(BoundaryCondition) <<", "<< write_offset + blocksCount * sizeof(BCAdd) + bcBlockCount*BLOCK_SIZE * sizeof(BoundaryCondition) + blocksCount*bcindexmatrixCount * sizeof(int)<< std::endl; - MPI_File_close(&file_handler); + MPI_Type_free(&dataSetDoubleType); + if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIORestartCoProcessor::writeBoundaryConds time: "<<finish-start<<" s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageDensityArray time: " << finish - start << " s"); } - delete[] bcAddArray; -} - -//------------------------------------------- READ ----------------------------------------------- -void MPIIORestartCoProcessor::restart(int step) -{ - if (comm->isRoot()) UBLOG(logINFO, "MPIIORestartCoProcessor restart step: "<<step); - if (comm->isRoot()) UBLOG(logINFO, "Load check point - start"); - readBlocks(step); - readDataSet(step); - readBoundaryConds(step); - if (comm->isRoot()) UBLOG(logINFO, "Load check point - end"); + delete[] dataSetSmallArray; } -void MPIIORestartCoProcessor::readBlocks(int step) +void MPIIORestartCoProcessor::writeAverageVelocityArray(int step) { int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - //MPI_Comm_size(MPI_COMM_WORLD, &size); - size = 1; + MPI_Comm_size(MPI_COMM_WORLD, &size); - if (comm->isRoot()) + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) { - UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); } - double start, finish; + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageVelocityArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid + dataSetSmallArray[ic].x2 = block->getX2(); + dataSetSmallArray[ic].x3 = block->getX3(); + dataSetSmallArray[ic].level = block->getLevel(); + + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageVelocityArray3DPtr = block->getKernel()->getDataSet()->getAverageVelocity(); + + if (firstBlock) // when first (any) valid block... + { + //if (AverageVelocityArray3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(AverageVelocityArray3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(AverageVelocityArray3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(AverageVelocityArray3DPtr->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(AverageVelocityArray3DPtr->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (AverageVelocityArray3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0) && (dataSetParamStr.nx[3]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), AverageVelocityArray3DPtr->getDataVector().begin(), AverageVelocityArray3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageVelocityArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + // write to the file + // all processes calculate their offsets (quantity of bytes that the process is going to write) + // and notify the next process (with the rank = rank + 1) + MPI_Offset write_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_write_offset = 0; + + if (size > 1) + { + if (rank == 0) + { + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank<size - 1) + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageVelocityArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes the quantity of it's blocks + MPI_File_write_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, write_offset, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + // each process writes data identifying blocks + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + // each process writes the dataSet arrays + if (doubleValuesArray.size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageVelocityArray time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIORestartCoProcessor::writeAverageFluktuationsArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageFluktuationsArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid + dataSetSmallArray[ic].x2 = block->getX2(); + dataSetSmallArray[ic].x3 = block->getX3(); + dataSetSmallArray[ic].level = block->getLevel(); + + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageFluctArray3DPtr = block->getKernel()->getDataSet()->getAverageFluctuations(); + + if (firstBlock) // when first (any) valid block... + { + //if (AverageFluctArray3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(AverageFluctArray3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(AverageFluctArray3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(AverageFluctArray3DPtr->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(AverageFluctArray3DPtr->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (AverageFluctArray3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0) && (dataSetParamStr.nx[3]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), AverageFluctArray3DPtr->getDataVector().begin(), AverageFluctArray3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageFluktuationsArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + // write to the file + // all processes calculate their offsets (quantity of bytes that the process is going to write) + // and notify the next process (with the rank = rank + 1) + MPI_Offset write_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_write_offset = 0; + + if (size > 1) + { + if (rank == 0) + { + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank<size - 1) + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageFluktuationsArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes the quantity of it's blocks + MPI_File_write_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, write_offset, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + // each process writes data identifying blocks + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + // each process writes the dataSet arrays + if (doubleValuesArray.size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageFluktuationsArray time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIORestartCoProcessor::writeAverageTripleArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageTripleArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid + dataSetSmallArray[ic].x2 = block->getX2(); + dataSetSmallArray[ic].x3 = block->getX3(); + dataSetSmallArray[ic].level = block->getLevel(); + + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > AverageTripleArray3DPtr = block->getKernel()->getDataSet()->getAverageTriplecorrelations(); + + if (firstBlock) // when first (any) valid block... + { + //if (AverageTripleArray3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(AverageTripleArray3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(AverageTripleArray3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(AverageTripleArray3DPtr->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(AverageTripleArray3DPtr->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (AverageTripleArray3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0) && (dataSetParamStr.nx[3]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), AverageTripleArray3DPtr->getDataVector().begin(), AverageTripleArray3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageTripleArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + // write to the file + // all processes calculate their offsets (quantity of bytes that the process is going to write) + // and notify the next process (with the rank = rank + 1) + MPI_Offset write_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_write_offset = 0; + + if (size > 1) + { + if (rank == 0) + { + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank<size - 1) + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageTripleArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes the quantity of it's blocks + MPI_File_write_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, write_offset, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + // each process writes data identifying blocks + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + // each process writes the dataSet arrays + if (doubleValuesArray.size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeAverageTripleArray time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIORestartCoProcessor::writeShearStressValArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeShearStressValArray start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid + dataSetSmallArray[ic].x2 = block->getX2(); + dataSetSmallArray[ic].x3 = block->getX3(); + dataSetSmallArray[ic].level = block->getLevel(); + + SPtr< CbArray4D<LBMReal, IndexerX4X3X2X1> > ShearStressValArray3DPtr = block->getKernel()->getDataSet()->getShearStressValues(); + + if (firstBlock) // when first (any) valid block... + { + //if (ShearStressValArray3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(ShearStressValArray3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(ShearStressValArray3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(ShearStressValArray3DPtr->getNX3()); + dataSetParamStr.nx[3] = static_cast<int>(ShearStressValArray3DPtr->getNX4()); + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (ShearStressValArray3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0) && (dataSetParamStr.nx[3]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), ShearStressValArray3DPtr->getDataVector().begin(), ShearStressValArray3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeShearStressValArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + // write to the file + // all processes calculate their offsets (quantity of bytes that the process is going to write) + // and notify the next process (with the rank = rank + 1) + MPI_Offset write_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_write_offset = 0; + + if (size > 1) + { + if (rank == 0) + { + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank<size - 1) + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpShearStressValArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes the quantity of it's blocks + MPI_File_write_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, write_offset, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + // each process writes data identifying blocks + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + // each process writes the dataSet arrays + if (doubleValuesArray.size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeShearStressValArray time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIORestartCoProcessor::writeRelaxationFactor(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + std::vector<double> doubleValuesArray; // double-values (arrays of f's) in all blocks + dataSetParam dataSetParamStr; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeRelaxationFactor start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + bool firstBlock = true; + int doubleCountInBlock = 0; + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // blocks of the current level + { + dataSetSmallArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid + dataSetSmallArray[ic].x2 = block->getX2(); + dataSetSmallArray[ic].x3 = block->getX3(); + dataSetSmallArray[ic].level = block->getLevel(); + + SPtr< CbArray3D<LBMReal, IndexerX3X2X1> > RelaxationFactor3DPtr = block->getKernel()->getDataSet()->getRelaxationFactor(); + + if (firstBlock) // when first (any) valid block... + { + //if (relaxationFactor3DPtr) + //{ + dataSetParamStr.nx1 = dataSetParamStr.nx2 = dataSetParamStr.nx3 = 0; + dataSetParamStr.nx[0] = static_cast<int>(RelaxationFactor3DPtr->getNX1()); + dataSetParamStr.nx[1] = static_cast<int>(RelaxationFactor3DPtr->getNX2()); + dataSetParamStr.nx[2] = static_cast<int>(RelaxationFactor3DPtr->getNX3()); + dataSetParamStr.nx[3] = 1; + doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + //} + //else + // break; + + firstBlock = false; + } + + if (RelaxationFactor3DPtr && (dataSetParamStr.nx[0]>0) && (dataSetParamStr.nx[1]>0) && (dataSetParamStr.nx[2]>0)) + doubleValuesArray.insert(doubleValuesArray.end(), RelaxationFactor3DPtr->getDataVector().begin(), RelaxationFactor3DPtr->getDataVector().end()); + + ic++; + } + } + + // register new MPI-types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeRelaxationFactor start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + // write to the file + // all processes calculate their offsets (quantity of bytes that the process is going to write) + // and notify the next process (with the rank = rank + 1) + MPI_Offset write_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_write_offset = 0; + + if (size > 1) + { + if (rank == 0) + { + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_write_offset = write_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank<size - 1) + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpRelaxationFactor.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // each process writes the quantity of it's blocks + MPI_File_write_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + // each process writes common parameters of a dataSet + MPI_File_write_at(file_handler, write_offset, &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + // each process writes data identifying blocks + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + // each process writes the dataSet arrays + if (doubleValuesArray.size() > 0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeRelaxationFactor time: " << finish - start << " s"); + } + + delete[] dataSetSmallArray; +} + +void MPIIORestartCoProcessor::writeBoundaryConds(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeBoundaryConds start collect data rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + int blocksCount = 0; // quantity of blocks in the grid, max 2147483648 blocks! + size_t count_boundCond = 0; // how many BoundaryConditions in all blocks + int count_indexContainer = 0; // how many indexContainer-values in all blocks + size_t byteCount = 0; // how many bytes writes this process in the file + + std::vector<SPtr<Block3D>> blocksVector[25]; + int minInitLevel = this->grid->getCoarsestInitializedLevel(); + int maxInitLevel = this->grid->getFinestInitializedLevel(); + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + grid->getBlocks(level, rank, blocksVector[level]); + blocksCount += static_cast<int>(blocksVector[level].size()); + } + + BCAdd* bcAddArray = new BCAdd[blocksCount]; + std::vector<BoundaryCondition> bcVector; + std::vector<int> bcindexmatrixV; + std::vector<int> indexContainerV; + bool bcindexmatrixCountNotInit = true; + + int ic = 0; + for (int level = minInitLevel; level <= maxInitLevel; level++) + { + for (SPtr<Block3D> block : blocksVector[level]) // all the blocks of the current level + { + SPtr<BCArray3D> bcArr = block->getKernel()->getBCProcessor()->getBCArray(); + + bcAddArray[ic].x1 = block->getX1(); // coordinates of the block needed to find it while regenerating the grid + bcAddArray[ic].x2 = block->getX2(); + bcAddArray[ic].x3 = block->getX3(); + bcAddArray[ic].level = block->getLevel(); + bcAddArray[ic].boundCond_count = 0; // how many BoundaryConditions in this block + bcAddArray[ic].indexContainer_count = 0; // how many indexContainer-values in this block + + for (int bc = 0; bc<bcArr->getBCVectorSize(); bc++) + { + BoundaryCondition* bouCond = new BoundaryCondition(); + if (bcArr->bcvector[bc] == NULL) + { + memset(bouCond, 0, sizeof(BoundaryCondition)); + } + else + { + bouCond->noslipBoundaryFlags = bcArr->bcvector[bc]->getNoSlipBoundary(); + bouCond->slipBoundaryFlags = bcArr->bcvector[bc]->getSlipBoundary(); + bouCond->velocityBoundaryFlags = bcArr->bcvector[bc]->getVelocityBoundary(); + bouCond->densityBoundaryFlags = bcArr->bcvector[bc]->getDensityBoundary(); + bouCond->wallModelBoundaryFlags = bcArr->bcvector[bc]->getWallModelBoundary(); + bouCond->bcVelocityX1 = bcArr->bcvector[bc]->getBoundaryVelocityX1(); + bouCond->bcVelocityX2 = bcArr->bcvector[bc]->getBoundaryVelocityX2(); + bouCond->bcVelocityX3 = bcArr->bcvector[bc]->getBoundaryVelocityX3(); + bouCond->bcDensity = bcArr->bcvector[bc]->getBoundaryDensity(); + bouCond->bcLodiDensity = bcArr->bcvector[bc]->getDensityLodiDensity(); + bouCond->bcLodiVelocityX1 = bcArr->bcvector[bc]->getDensityLodiVelocityX1(); + bouCond->bcLodiVelocityX2 = bcArr->bcvector[bc]->getDensityLodiVelocityX2(); + bouCond->bcLodiVelocityX3 = bcArr->bcvector[bc]->getDensityLodiVelocityX3(); + bouCond->bcLodiLentgh = bcArr->bcvector[bc]->getDensityLodiLength(); + bouCond->nx1 = bcArr->bcvector[bc]->nx1; + bouCond->nx2 = bcArr->bcvector[bc]->nx2; + bouCond->nx3 = bcArr->bcvector[bc]->nx3; + for (int iq = 0; iq<26; iq++) + bouCond->q[iq] = bcArr->bcvector[bc]->getQ(iq); + bouCond->algorithmType = bcArr->bcvector[bc]->getBcAlgorithmType(); + } + + bcVector.push_back(*bouCond); + bcAddArray[ic].boundCond_count++; + count_boundCond++; + } + + // the quantity of elements in the bcindexmatrix array (CbArray3D<int, IndexerX3X2X1>) in bcArray(BCArray3D) is always equal, + // this will be the size of the "write-read-block" in MPI_write_.../MPI_read-functions when writing/reading BoundConds + if (bcindexmatrixCountNotInit) + { + boundCondParamStr.nx1 = static_cast<int>(bcArr->bcindexmatrix.getNX1()); + boundCondParamStr.nx2 = static_cast<int>(bcArr->bcindexmatrix.getNX2()); + boundCondParamStr.nx3 = static_cast<int>(bcArr->bcindexmatrix.getNX3()); + boundCondParamStr.bcindexmatrixCount = static_cast<int>(bcArr->bcindexmatrix.getDataVector().size()); + bcindexmatrixCountNotInit = false; + } + bcindexmatrixV.insert(bcindexmatrixV.end(), bcArr->bcindexmatrix.getDataVector().begin(), bcArr->bcindexmatrix.getDataVector().end()); + + indexContainerV.insert(indexContainerV.end(), bcArr->indexContainer.begin(), bcArr->indexContainer.end()); + bcAddArray[ic].indexContainer_count = static_cast<int>(bcArr->indexContainer.size()); + count_indexContainer += bcAddArray[ic].indexContainer_count; + + ic++; + } + } + + + MPI_Type_contiguous(boundCondParamStr.bcindexmatrixCount, MPI_INT, &bcindexmatrixType); + MPI_Type_commit(&bcindexmatrixType); + + //how many "big blocks" of BLOCK_SIZE size can by formed + int bcBlockCount = (int)(count_boundCond / BLOCK_SIZE); + if (bcBlockCount * BLOCK_SIZE<count_boundCond) + bcBlockCount += 1; + for (int i = (int)count_boundCond; i<bcBlockCount * BLOCK_SIZE; i++) + { + BoundaryCondition* bouCond = new BoundaryCondition(); + memset(bouCond, 0, sizeof(BoundaryCondition)); + bcVector.push_back(*bouCond); + } + + byteCount = bcBlockCount * BLOCK_SIZE * sizeof(BoundaryCondition) + blocksCount * sizeof(BCAdd) + sizeof(int) * (blocksCount * boundCondParamStr.bcindexmatrixCount + count_indexContainer); + + // write to the file + // all processes calculate their offsets (quantity of bytes that the process is going to write) + // and notify the next process (with the rank = rank + 1) + MPI_Offset write_offset = (MPI_Offset)(size * (3 * sizeof(int) + sizeof(boundCondParam))); + size_t next_write_offset = 0; + + if (size>1) + { + if (rank == 0) + { + next_write_offset = write_offset + byteCount; + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&write_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_write_offset = write_offset + byteCount; + if (rank<size - 1) + MPI_Send(&next_write_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::writeBoundaryConds start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_Info info = MPI_INFO_NULL; + +#ifdef HLRN_LUSTRE + MPI_Info_create(&info); + MPI_Info_set(info, "striping_factor", "40"); + MPI_Info_set(info, "striping_unit", "4M"); +#endif + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_CREATE | MPI_MODE_WRONLY, info, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + MPI_Offset write_offset1 = (MPI_Offset)(rank * (3 * sizeof(int) + sizeof(boundCondParam))); + + // each process writes the quantity of it's blocks + MPI_File_write_at(file_handler, write_offset1, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + // each process writes the quantity of "big blocks" of BLOCK_SIZE of boundary conditions + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset1 + sizeof(int)), &bcBlockCount, 1, MPI_INT, MPI_STATUS_IGNORE); + // each process writes the quantity of indexContainer elements in all blocks + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset1 + 2 * sizeof(int)), &count_indexContainer, 1, MPI_INT, MPI_STATUS_IGNORE); + // each process writes the quantity of bcindexmatrix elements in every block + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset1 + 3 * sizeof(int)), &boundCondParamStr, 1, boundCondParamType, MPI_STATUS_IGNORE); + + // each process writes data identifying the blocks + MPI_File_write_at(file_handler, write_offset, bcAddArray, blocksCount, boundCondTypeAdd, MPI_STATUS_IGNORE); + // each process writes boundary conditions + if (bcVector.size()>0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + blocksCount * sizeof(BCAdd)), &bcVector[0], bcBlockCount, boundCondType1000, MPI_STATUS_IGNORE); + // each process writes bcindexmatrix values + if (bcindexmatrixV.size()>0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + blocksCount * sizeof(BCAdd) + bcBlockCount*BLOCK_SIZE * sizeof(BoundaryCondition)), &bcindexmatrixV[0], blocksCount, bcindexmatrixType, MPI_STATUS_IGNORE); + // each process writes indexContainer values + if (indexContainerV.size()>0) + MPI_File_write_at(file_handler, (MPI_Offset)(write_offset + blocksCount * sizeof(BCAdd) + bcBlockCount*BLOCK_SIZE * sizeof(BoundaryCondition) + blocksCount*boundCondParamStr.bcindexmatrixCount * sizeof(int)), &indexContainerV[0], count_indexContainer, MPI_INT, MPI_STATUS_IGNORE); + + MPI_File_sync(file_handler); + MPI_File_close(&file_handler); + + MPI_Type_free(&bcindexmatrixType); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::writeBoundaryConds time: " << finish - start << " s"); + } + + delete[] bcAddArray; +} + +//------------------------------------------- READ ----------------------------------------------- +void MPIIORestartCoProcessor::restart(int step) +{ + if (comm->isRoot()) UBLOG(logINFO, "MPIIORestartCoProcessor restart step: " << step); + if (comm->isRoot()) UBLOG(logINFO, "Load check point - start"); + + readBlocks(step); + readDataSet(step); + readBoundaryConds(step); + + if (comm->isRoot()) UBLOG(logINFO, "Load check point - end"); +} + +void MPIIORestartCoProcessor::readBlocks(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + //MPI_Comm_size(MPI_COMM_WORLD, &size); + size = 1; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBlocks.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // read count of blocks + int blocksCount = 0; + //MPI_File_read_at(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, 0, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + Block3d* block3dArray = new Block3d[blocksCount]; + + // calculate the read offset + MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int)); + + GridParam* gridParameters = new GridParam; + + // read parameters of the grid + MPI_File_read_at(file_handler, read_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE); + // read all the blocks + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(GridParam)), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE); + + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks time: " << finish - start << " s"); + } + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + // clear the grid + std::vector<SPtr<Block3D>> blocksVector; + grid->getBlocks(0, blocksVector); + int del = 0; + for (SPtr<Block3D> block : blocksVector) + { + grid->deleteBlock(block); + del++; + } + + // restore the grid + SPtr<CoordinateTransformation3D> trafo(new CoordinateTransformation3D()); + trafo->Tx1 = gridParameters->trafoParams[0]; + trafo->Tx2 = gridParameters->trafoParams[1]; + trafo->Tx3 = gridParameters->trafoParams[2]; + trafo->Sx1 = gridParameters->trafoParams[3]; + trafo->Sx2 = gridParameters->trafoParams[4]; + trafo->Sx3 = gridParameters->trafoParams[5]; + trafo->alpha = gridParameters->trafoParams[6]; + trafo->beta = gridParameters->trafoParams[7]; + trafo->gamma = gridParameters->trafoParams[8]; + + trafo->toX1factorX1 = gridParameters->trafoParams[9]; + trafo->toX1factorX2 = gridParameters->trafoParams[10]; + trafo->toX1factorX3 = gridParameters->trafoParams[11]; + trafo->toX1delta = gridParameters->trafoParams[12]; + trafo->toX2factorX1 = gridParameters->trafoParams[13]; + trafo->toX2factorX2 = gridParameters->trafoParams[14]; + trafo->toX2factorX3 = gridParameters->trafoParams[15]; + trafo->toX2delta = gridParameters->trafoParams[16]; + trafo->toX3factorX1 = gridParameters->trafoParams[17]; + trafo->toX3factorX2 = gridParameters->trafoParams[18]; + trafo->toX3factorX3 = gridParameters->trafoParams[19]; + trafo->toX3delta = gridParameters->trafoParams[20]; + + trafo->fromX1factorX1 = gridParameters->trafoParams[21]; + trafo->fromX1factorX2 = gridParameters->trafoParams[22]; + trafo->fromX1factorX3 = gridParameters->trafoParams[23]; + trafo->fromX1delta = gridParameters->trafoParams[24]; + trafo->fromX2factorX1 = gridParameters->trafoParams[25]; + trafo->fromX2factorX2 = gridParameters->trafoParams[26]; + trafo->fromX2factorX3 = gridParameters->trafoParams[27]; + trafo->fromX2delta = gridParameters->trafoParams[28]; + trafo->fromX3factorX1 = gridParameters->trafoParams[29]; + trafo->fromX3factorX2 = gridParameters->trafoParams[30]; + trafo->fromX3factorX3 = gridParameters->trafoParams[31]; + trafo->fromX3delta = gridParameters->trafoParams[32]; + + trafo->active = gridParameters->active; + trafo->transformation = gridParameters->transformation; + + grid->setCoordinateTransformator(trafo); + + grid->setDeltaX(gridParameters->deltaX); + grid->setBlockNX(gridParameters->blockNx1, gridParameters->blockNx2, gridParameters->blockNx3); + grid->setNX1(gridParameters->nx1); + grid->setNX2(gridParameters->nx2); + grid->setNX3(gridParameters->nx3); + grid->setPeriodicX1(gridParameters->periodicX1); + grid->setPeriodicX2(gridParameters->periodicX2); + grid->setPeriodicX3(gridParameters->periodicX3); + + // regenerate blocks + for (int n = 0; n<blocksCount; n++) + { + SPtr<Block3D> block(new Block3D(block3dArray[n].x1, block3dArray[n].x2, block3dArray[n].x3, block3dArray[n].level)); + block->setActive(block3dArray[n].active); + block->setBundle(block3dArray[n].bundle); + block->setRank(block3dArray[n].rank); + block->setLocalRank(block3dArray[n].lrank); + block->setGlobalID(block3dArray[n].globalID); + block->setLocalID(block3dArray[n].localID); + block->setPart(block3dArray[n].part); + block->setLevel(block3dArray[n].level); + block->interpolationFlagCF = block3dArray[n].interpolationFlagCF; + block->interpolationFlagFC = block3dArray[n].interpolationFlagFC; + + grid->addBlock(block); + } + + delete gridParameters; + delete[] block3dArray; + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } +} + +void MPIIORestartCoProcessor::readDataSet(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpDataSet.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // calculate the read offset + MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_read_offset = 0; + + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr1, dataSetParamStr2, dataSetParamStr3; + + MPI_File_read_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, read_offset, &dataSetParamStr1, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam)), &dataSetParamStr2, 1, dataSetParamType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + 2 * sizeof(dataSetParam)), &dataSetParamStr3, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSet* dataSetArray = new DataSet[blocksCount]; + double doubleCountInBlock = dataSetParamStr1.nx[0] * dataSetParamStr1.nx[1] * dataSetParamStr1.nx[2] * dataSetParamStr1.nx[3] + + dataSetParamStr2.nx[0] * dataSetParamStr2.nx[1] * dataSetParamStr2.nx[2] * dataSetParamStr2.nx[3] + + dataSetParamStr3.nx[0] * dataSetParamStr3.nx[1] * dataSetParamStr3.nx[2] * dataSetParamStr3.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + if (size > 1) + { + if (rank == 0) + { + next_read_offset = read_offset + 3 * sizeof(dataSetParam) + blocksCount * (sizeof(DataSet) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_read_offset = read_offset + 3 * sizeof(dataSetParam) + blocksCount * (sizeof(DataSet) + doubleCountInBlock * sizeof(double)); + if (rank < size - 1) + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + 3 * sizeof(dataSetParam)), dataSetArray, blocksCount, dataSetType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + 3 * sizeof(dataSetParam) + blocksCount * sizeof(DataSet)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + size_t index = 0, vectorSize = 0; + std::vector<double> vectorsOfValues1, vectorsOfValues2, vectorsOfValues3; + + for (int n = 0; n < blocksCount; n++) + { + vectorSize = dataSetParamStr1.nx[0] * dataSetParamStr1.nx[1] * dataSetParamStr1.nx[2] * dataSetParamStr1.nx[3]; + vectorsOfValues1.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + vectorSize); + index += vectorSize; + + vectorSize = dataSetParamStr2.nx[0] * dataSetParamStr2.nx[1] * dataSetParamStr2.nx[2] * dataSetParamStr2.nx[3]; + vectorsOfValues2.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + vectorSize); + index += vectorSize; + + vectorSize = dataSetParamStr3.nx[0] * dataSetParamStr3.nx[1] * dataSetParamStr3.nx[2] * dataSetParamStr3.nx[3]; + vectorsOfValues3.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + vectorSize); + index += vectorSize; + + SPtr<DistributionArray3D> mFdistributions(new D3Q27EsoTwist3DSplittedVector()); + + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues1, dataSetParamStr1.nx[0], dataSetParamStr1.nx[1], dataSetParamStr1.nx[2], dataSetParamStr1.nx[3]))); + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues2, dataSetParamStr2.nx[0], dataSetParamStr2.nx[1], dataSetParamStr2.nx[2], dataSetParamStr2.nx[3]))); + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues3, dataSetParamStr3.nx[0], dataSetParamStr3.nx[1], dataSetParamStr3.nx[2]))); + + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(dataSetParamStr1.nx1); + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(dataSetParamStr1.nx2); + dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(dataSetParamStr1.nx3); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetArray[n].x1, dataSetArray[n].x2, dataSetArray[n].x3, dataSetArray[n].level); + SPtr<LBMKernel> kernel = this->lbmKernel->clone(); + kernel->setGhostLayerWidth(dataSetArray[n].ghostLayerWidth); + kernel->setCollisionFactor(dataSetArray[n].collFactor); + kernel->setDeltaT(dataSetArray[n].deltaT); + kernel->setCompressible(dataSetArray[n].compressible); + kernel->setWithForcing(dataSetArray[n].withForcing); + SPtr<DataSet3D> dataSetPtr = SPtr<DataSet3D>(new DataSet3D()); + dataSetPtr->setFdistributions(mFdistributions); + kernel->setDataSet(dataSetPtr); + block->setKernel(kernel); + } + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + delete[] dataSetArray; + + //------------------------------------------------------------- + + DSArraysPresence arrPresence; + MPI_File file_handler1; + std::string filename1 = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpArrays.bin"; + rc = MPI_File_open(MPI_COMM_WORLD, filename1.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler1); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename1); + MPI_File_read_at(file_handler1, (MPI_Offset)0, &arrPresence, 1, arrayPresenceType, MPI_STATUS_IGNORE); + MPI_File_close(&file_handler1); + + if (arrPresence.isAverageDensityArrayPresent) + readAverageDensityArray(step); + + if (arrPresence.isAverageVelocityArrayPresent) + readAverageVelocityArray(step); + + if (arrPresence.isAverageFluktuationsArrayPresent) + readAverageFluktuationsArray(step); + + if (arrPresence.isAverageTripleArrayPresent) + readAverageTripleArray(step); + + if (arrPresence.isShearStressValArrayPresent) + readShearStressValArray(step); + + if (arrPresence.isRelaxationFactorPresent) + readRelaxationFactor(step); + +} + +void MPIIORestartCoProcessor::readAverageDensityArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageDensityArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageDensityArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr; + memset(&dataSetParamStr, 0, sizeof(dataSetParam)); + + MPI_File_read_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(size * sizeof(int)), &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + // calculate the read offset + MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_read_offset = 0; + + if (size > 1) + { + if (rank == 0) + { + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank < size - 1) + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + if (doubleCountInBlock > 0) + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageDensityArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageDensityArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; + + // fill mAverageDensity arrays + SPtr<AverageValuesArray3D> mAverageDensity; + //if ((dataSetParamStr.nx[0]==0)&&(dataSetParamStr.nx[1]==0)&&(dataSetParamStr.nx[2]==0)&&(dataSetParamStr.nx[3]==0)) + // mAverageDensity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mAverageDensity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].x1, dataSetSmallArray[n].x2, dataSetSmallArray[n].x3, dataSetSmallArray[n].level); + block->kernel->getDataSet()->setAverageDencity(mAverageDensity); + } + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageDensityArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + delete[] dataSetSmallArray; +} + +void MPIIORestartCoProcessor::readAverageVelocityArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageVelocityArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); + + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageVelocityArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); + + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr; + MPI_File_read_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(size * sizeof(int)), &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); + + // calculate the read offset + MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_read_offset = 0; + + if (size > 1) + { + if (rank == 0) + { + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank < size - 1) + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + if (doubleCountInBlock > 0) + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + MPI_File_close(&file_handler); + + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageVelocityArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageVelocityArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; + + // fill mAverageVelocity array + SPtr<AverageValuesArray3D> mAverageVelocity; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0) && (dataSetParamStr.nx[3] == 0)) + // mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].x1, dataSetSmallArray[n].x2, dataSetSmallArray[n].x3, dataSetSmallArray[n].level); + block->kernel->getDataSet()->setAverageVelocity(mAverageVelocity); + } + + MPI_Type_free(&dataSetDoubleType); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageVelocityArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + delete[] dataSetSmallArray; +} + +void MPIIORestartCoProcessor::readAverageFluktuationsArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageFluktuationsArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; if (comm->isRoot()) start = MPI_Wtime(); MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBlocks.bin"; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageFluktuationsArray.bin"; int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); // read count of blocks int blocksCount = 0; - //MPI_File_read_at(file_handler, rank*sizeof(int), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, 0, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); - Block3d* block3dArray = new Block3d[blocksCount]; + dataSetParam dataSetParamStr; + MPI_File_read_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(size * sizeof(int)), &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); // calculate the read offset MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_read_offset = 0; - GridParam* gridParameters = new GridParam; - - // read parameters of the grid - MPI_File_read_at(file_handler, read_offset, gridParameters, 1, gridParamType, MPI_STATUS_IGNORE); - // read all the blocks - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset+sizeof(GridParam)), &block3dArray[0], blocksCount, block3dType, MPI_STATUS_IGNORE); + if (size > 1) + { + if (rank == 0) + { + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank < size - 1) + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + if (doubleCountInBlock > 0) + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); MPI_File_close(&file_handler); if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks time: "<<finish-start<<" s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageFluktuationsArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageFluktuationsArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; + + // fill AverageFluktuations array + SPtr<AverageValuesArray3D> mAverageFluktuations; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0) && (dataSetParamStr.nx[3] == 0)) + // mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].x1, dataSetSmallArray[n].x2, dataSetSmallArray[n].x3, dataSetSmallArray[n].level); + block->kernel->getDataSet()->setAverageFluctuations(mAverageFluktuations); } + MPI_Type_free(&dataSetDoubleType); + if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks start of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageFluktuationsArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } - // clear the grid - std::vector<SPtr<Block3D>> blocksVector; - grid->getBlocks(0, blocksVector); - int del = 0; - for(SPtr<Block3D> block : blocksVector) + delete[] dataSetSmallArray; +} + +void MPIIORestartCoProcessor::readAverageTripleArray(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + + if (comm->isRoot()) { - grid->deleteBlock(block); - del++; + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageTripleArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); - // restore the grid - SPtr<CoordinateTransformation3D> trafo(new CoordinateTransformation3D()); - trafo->Tx1 = gridParameters->trafoParams[0]; - trafo->Tx2 = gridParameters->trafoParams[1]; - trafo->Tx3 = gridParameters->trafoParams[2]; - trafo->Sx1 = gridParameters->trafoParams[3]; - trafo->Sx2 = gridParameters->trafoParams[4]; - trafo->Sx3 = gridParameters->trafoParams[5]; - trafo->alpha = gridParameters->trafoParams[6]; - trafo->beta = gridParameters->trafoParams[7]; - trafo->gamma = gridParameters->trafoParams[8]; + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpAverageTripleArray.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); - trafo->toX1factorX1 = gridParameters->trafoParams[9]; - trafo->toX1factorX2 = gridParameters->trafoParams[10]; - trafo->toX1factorX3 = gridParameters->trafoParams[11]; - trafo->toX1delta = gridParameters->trafoParams[12]; - trafo->toX2factorX1 = gridParameters->trafoParams[13]; - trafo->toX2factorX2 = gridParameters->trafoParams[14]; - trafo->toX2factorX3 = gridParameters->trafoParams[15]; - trafo->toX2delta = gridParameters->trafoParams[16]; - trafo->toX3factorX1 = gridParameters->trafoParams[17]; - trafo->toX3factorX2 = gridParameters->trafoParams[18]; - trafo->toX3factorX3 = gridParameters->trafoParams[19]; - trafo->toX3delta = gridParameters->trafoParams[20]; + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr; + MPI_File_read_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(size * sizeof(int)), &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); - trafo->fromX1factorX1 = gridParameters->trafoParams[21]; - trafo->fromX1factorX2 = gridParameters->trafoParams[22]; - trafo->fromX1factorX3 = gridParameters->trafoParams[23]; - trafo->fromX1delta = gridParameters->trafoParams[24]; - trafo->fromX2factorX1 = gridParameters->trafoParams[25]; - trafo->fromX2factorX2 = gridParameters->trafoParams[26]; - trafo->fromX2factorX3 = gridParameters->trafoParams[27]; - trafo->fromX2delta = gridParameters->trafoParams[28]; - trafo->fromX3factorX1 = gridParameters->trafoParams[29]; - trafo->fromX3factorX2 = gridParameters->trafoParams[30]; - trafo->fromX3factorX3 = gridParameters->trafoParams[31]; - trafo->fromX3delta = gridParameters->trafoParams[32]; + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks - trafo->active = gridParameters->active; - trafo->transformation = gridParameters->transformation; + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); - grid->setCoordinateTransformator(trafo); + // calculate the read offset + MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_read_offset = 0; - grid->setDeltaX(gridParameters->deltaX); - grid->setBlockNX(gridParameters->blockNx1, gridParameters->blockNx2, gridParameters->blockNx3); - grid->setNX1(gridParameters->nx1); - grid->setNX2(gridParameters->nx2); - grid->setNX3(gridParameters->nx3); - grid->setPeriodicX1(gridParameters->periodicX1); - grid->setPeriodicX2(gridParameters->periodicX2); - grid->setPeriodicX3(gridParameters->periodicX3); + if (size > 1) + { + if (rank == 0) + { + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank < size - 1) + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } - // regenerate blocks - for (int n = 0; n<blocksCount; n++) + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + if (doubleCountInBlock > 0) + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + MPI_File_close(&file_handler); + + if (comm->isRoot()) { - SPtr<Block3D> block(new Block3D(block3dArray[n].x1, block3dArray[n].x2, block3dArray[n].x3, block3dArray[n].level)); - block->setActive(block3dArray[n].active); - block->setBundle(block3dArray[n].bundle); - block->setRank(block3dArray[n].rank); - block->setLocalRank(block3dArray[n].lrank); - block->setGlobalID(block3dArray[n].globalID); - block->setLocalID(block3dArray[n].localID); - block->setPart(block3dArray[n].part); - block->setLevel(block3dArray[n].level); - block->interpolationFlagCF = block3dArray[n].interpolationFlagCF; - block->interpolationFlagFC = block3dArray[n].interpolationFlagFC; + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageTripleArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageTripleArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } - grid->addBlock(block); + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; + + // fill AverageTriplecorrelations array + SPtr<AverageValuesArray3D> mAverageTriplecorrelations; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0) && (dataSetParamStr.nx[3] == 0)) + // mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].x1, dataSetSmallArray[n].x2, dataSetSmallArray[n].x3, dataSetSmallArray[n].level); + block->kernel->getDataSet()->setAverageTriplecorrelations(mAverageTriplecorrelations); } - delete gridParameters; - delete[] block3dArray; + MPI_Type_free(&dataSetDoubleType); if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::readBlocks end of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readAverageTripleArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } + + delete[] dataSetSmallArray; } -void MPIIORestartCoProcessor::readDataSet(int step) +void MPIIORestartCoProcessor::readShearStressValArray(int step) { int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); @@ -1002,209 +2344,190 @@ void MPIIORestartCoProcessor::readDataSet(int step) if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readShearStressValArray start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } double start, finish; if (comm->isRoot()) start = MPI_Wtime(); MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpDataSet.bin"; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpShearStressValArray.bin"; int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); // read count of blocks int blocksCount = 0; - MPI_File_read_at(file_handler, (MPI_Offset)(rank*sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, (MPI_Offset)(size*sizeof(int)), &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); - //std::cout <<"MPIIORestartCoProcessor::readDataSet rank=" << rank <<", dataSetParamStr.doubleCountInBlock="<< dataSetParamStr.doubleCountInBlock << std::endl; - //std::cout << ",dataSetParamStr.nx[6][0]" << "=" << dataSetParamStr.nx[6][0] << "," << dataSetParamStr.nx[6][1] << "," << dataSetParamStr.nx[6][2] << "," << dataSetParamStr.nx[6][3]; - //std::cout << ",doubleCountInBlock=" << dataSetParamStr.doubleCountInBlock << "," << dataSetParamStr.nx1 << "," << dataSetParamStr.nx2 << "," << dataSetParamStr.nx3 << std::endl; + dataSetParam dataSetParamStr; + MPI_File_read_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(size * sizeof(int)), &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks - DataSet* dataSetArray = new DataSet[blocksCount]; - std::vector<double> doubleValuesArray(blocksCount * dataSetParamStr.doubleCountInBlock); // double-values in all blocks - // define MPI_types depending on the block-specific information - MPI_Type_contiguous(dataSetParamStr.doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); MPI_Type_commit(&dataSetDoubleType); - mpiTypeFreeFlag = true; - //std::cout << "MPIIORestartCoProcessor::readDataSet rank=" << rank << " 123=" << dataSetParamStr.doubleCountInBlock << std::endl; // calculate the read offset MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int)); size_t next_read_offset = 0; - if(size > 1) + if (size > 1) { - if(rank == 0) - { - next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount * (sizeof(DataSet) + dataSetParamStr.doubleCountInBlock * sizeof(double)); - MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); - } - else - { - MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount * (sizeof(DataSet) + dataSetParamStr.doubleCountInBlock * sizeof(double)); - if(rank < size - 1) - MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); - } + if (rank == 0) + { + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } + else + { + MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank < size - 1) + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } } - /*int chunkFlag = 0; + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + if (doubleCountInBlock > 0) + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + MPI_File_close(&file_handler); - if (rank == 0) + if (comm->isRoot()) { - MPI_File_read_at(file_handler, read_offset, dataSetArray, blocksCount, dataSetType, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset+blocksCount*sizeof(DataSet)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); - - for (int i=1; i<size; i+=chunk) - { - for (int j=i; j<i+chunk; j++) - { - if (j < size) - { - MPI_Send(&chunkFlag, 1, MPI_INT, j, 77, MPI_COMM_WORLD); - //UBLOG(logINFO, "j= "<<j); - } - } - for (int j=i; j<i+chunk; j++) - { - if (j < size) - { - MPI_Recv(&chunkFlag, 1, MPI_INT, j, 77, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } - } - } + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::readShearStressValArray time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readShearStressValArray start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } - else + + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) { - MPI_Recv(&chunkFlag, 1, MPI_INT, 0, 77, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, read_offset, dataSetArray, blocksCount, dataSetType, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset+blocksCount*sizeof(DataSet)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); - MPI_Send(&chunkFlag, 1, MPI_INT, 0, 77, MPI_COMM_WORLD); - //UBLOG(logINFO, "read rank= "<<rank); - }*/ + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset+sizeof(dataSetParam)), dataSetArray, blocksCount, dataSetType, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset+sizeof(dataSetParam)+blocksCount*sizeof(DataSet)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); - MPI_File_close(&file_handler); + // fill ShearStressValuesArray array + SPtr<ShearStressValuesArray3D> mShearStressValues; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0) && (dataSetParamStr.nx[3] == 0)) + // mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); + //else + mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2], dataSetParamStr.nx[3])); + + // find the nesessary block and fill it + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].x1, dataSetSmallArray[n].x2, dataSetSmallArray[n].x3, dataSetSmallArray[n].level); + block->kernel->getDataSet()->setShearStressValues(mShearStressValues); + } - //for (int ch = 0; ch < blocksCount; ch++) - //{ - // if ((dataSetArrayGW[ch].x1 != dataSetArray[ch].x1) || - // (dataSetArrayGW[ch].x2 != dataSetArray[ch].x2) || - // (dataSetArrayGW[ch].x3 != dataSetArray[ch].x3) || - // (dataSetArrayGW[ch].level != dataSetArray[ch].level) || - // (dataSetArrayGW[ch].ghostLayerWidth != dataSetArray[ch].ghostLayerWidth) || - // (dataSetArrayGW[ch].collFactor != dataSetArray[ch].collFactor) || - // (dataSetArrayGW[ch].deltaT != dataSetArray[ch].deltaT) || - // (dataSetArrayGW[ch].compressible != dataSetArray[ch].compressible) || - // (dataSetArrayGW[ch].withForcing != dataSetArray[ch].withForcing)) - // std::cout << "dataSetArrayGW != rank" << rank << ", !!!!!====="<< std::endl; - //} - //std::cout << "doubleValuesArrayGW.size" << doubleValuesArrayGW.size() << ", " << doubleValuesArray.size() << std::endl; - //for (int vl = 0; vl < doubleValuesArrayGW.size(); vl++) - // if(doubleValuesArrayGW[vl] != doubleValuesArray[vl]) - // std::cout << "doubleValuesArrayGW != rank" << rank << ", !!!!!====="<< std::endl; + MPI_Type_free(&dataSetDoubleType); if (comm->isRoot()) { - finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet time: "<<finish-start<<" s"); - UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet start of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readShearStressValArray end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } - size_t index = 0, nextVectorSize = 0; - std::vector<double> vectorsOfValues[9]; - for (int n = 0; n<blocksCount; n++) - { - for (int b = 0; b<9; b++) // assign approciate vectors for 9 dataSet arrays - { - nextVectorSize = dataSetParamStr.nx[b][0]* dataSetParamStr.nx[b][1]* dataSetParamStr.nx[b][2]* dataSetParamStr.nx[b][3]; - vectorsOfValues[b].assign(doubleValuesArray.data()+index, doubleValuesArray.data()+index+nextVectorSize); - index += nextVectorSize; - } + delete[] dataSetSmallArray; +} - // fill dataSet arrays - SPtr<AverageValuesArray3D> mAverageDensity; - if ((dataSetParamStr.nx[0][0]==0)&&(dataSetParamStr.nx[0][1]==0)&&(dataSetParamStr.nx[0][2]==0)&&(dataSetParamStr.nx[0][3]==0)) - mAverageDensity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mAverageDensity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[0], dataSetParamStr.nx[0][0], dataSetParamStr.nx[0][1], dataSetParamStr.nx[0][2], dataSetParamStr.nx[0][3])); +void MPIIORestartCoProcessor::readRelaxationFactor(int step) +{ + int rank, size; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); - SPtr<AverageValuesArray3D> mAverageVelocity; - if ((dataSetParamStr.nx[1][0]==0)&&(dataSetParamStr.nx[1][1]==0)&&(dataSetParamStr.nx[1][2]==0)&&(dataSetParamStr.nx[1][3]==0)) - mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mAverageVelocity = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[1], dataSetParamStr.nx[1][0], dataSetParamStr.nx[1][1], dataSetParamStr.nx[1][2], dataSetParamStr.nx[1][3])); + if (comm->isRoot()) + { + UBLOG(logINFO, "MPIIORestartCoProcessor::readRelaxationFactor start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } + double start, finish; + if (comm->isRoot()) start = MPI_Wtime(); - SPtr<AverageValuesArray3D> mAverageFluktuations; - if ((dataSetParamStr.nx[2][0]==0)&&(dataSetParamStr.nx[2][1]==0)&&(dataSetParamStr.nx[2][2]==0)&&(dataSetParamStr.nx[2][3]==0)) - mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mAverageFluktuations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[2], dataSetParamStr.nx[2][0], dataSetParamStr.nx[2][1], dataSetParamStr.nx[2][2], dataSetParamStr.nx[2][3])); + MPI_File file_handler; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpRelaxationFactor.bin"; + int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); - SPtr<AverageValuesArray3D> mAverageTriplecorrelations; - if ((dataSetParamStr.nx[3][0]==0)&&(dataSetParamStr.nx[3][1]==0)&&(dataSetParamStr.nx[3][2]==0)&&(dataSetParamStr.nx[3][3]==0)) - mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mAverageTriplecorrelations = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[3], dataSetParamStr.nx[3][0], dataSetParamStr.nx[3][1], dataSetParamStr.nx[3][2], dataSetParamStr.nx[3][3])); + // read count of blocks + int blocksCount = 0; + dataSetParam dataSetParamStr; + MPI_File_read_at(file_handler, (MPI_Offset)(rank * sizeof(int)), &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(size * sizeof(int)), &dataSetParamStr, 1, dataSetParamType, MPI_STATUS_IGNORE); + + DataSetSmall* dataSetSmallArray = new DataSetSmall[blocksCount]; + int doubleCountInBlock = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> doubleValuesArray(blocksCount * doubleCountInBlock); // double-values in all blocks + + // define MPI_types depending on the block-specific information + MPI_Type_contiguous(doubleCountInBlock, MPI_DOUBLE, &dataSetDoubleType); + MPI_Type_commit(&dataSetDoubleType); - SPtr<ShearStressValuesArray3D> mShearStressValues; - if ((dataSetParamStr.nx[4][0]==0)&&(dataSetParamStr.nx[4][1]==0)&&(dataSetParamStr.nx[4][2]==0)&&(dataSetParamStr.nx[4][3]==0)) - mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(); - else - mShearStressValues = CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[4], dataSetParamStr.nx[4][0], dataSetParamStr.nx[4][1], dataSetParamStr.nx[4][2], dataSetParamStr.nx[4][3])); + // calculate the read offset + MPI_Offset read_offset = (MPI_Offset)(size * sizeof(int)); + size_t next_read_offset = 0; - SPtr<RelaxationFactorArray3D> mRelaxationFactor; - if ((dataSetParamStr.nx[5][0]==0)&&(dataSetParamStr.nx[5][1]==0)&&(dataSetParamStr.nx[5][2]==0)) - mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(); + if (size > 1) + { + if (rank == 0) + { + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); + } else - mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[5], dataSetParamStr.nx[5][0], dataSetParamStr.nx[5][1], dataSetParamStr.nx[5][2])); + { + MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_read_offset = read_offset + sizeof(dataSetParam) + blocksCount*(sizeof(DataSetSmall) + doubleCountInBlock * sizeof(double)); + if (rank < size - 1) + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); + } + } - //SPtr<DistributionArray3D> mFdistributions(new D3Q27EsoTwist3DSplittedVector(dataSetParamStr.nx1, dataSetParamStr.nx2, dataSetParamStr.nx3, -999.0)); - SPtr<DistributionArray3D> mFdistributions(new D3Q27EsoTwist3DSplittedVector()); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam)), dataSetSmallArray, blocksCount, dataSetSmallType, MPI_STATUS_IGNORE); + if (doubleCountInBlock > 0) + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + sizeof(dataSetParam) + blocksCount * sizeof(DataSetSmall)), &doubleValuesArray[0], blocksCount, dataSetDoubleType, MPI_STATUS_IGNORE); + MPI_File_close(&file_handler); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[6], dataSetParamStr.nx[6][0], dataSetParamStr.nx[6][1], dataSetParamStr.nx[6][2], dataSetParamStr.nx[6][3]))); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNonLocalDistributions(CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr(new CbArray4D<LBMReal, IndexerX4X3X2X1>(vectorsOfValues[7], dataSetParamStr.nx[7][0], dataSetParamStr.nx[7][1], dataSetParamStr.nx[7][2], dataSetParamStr.nx[7][3]))); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setZeroDistributions(CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues[8], dataSetParamStr.nx[8][0], dataSetParamStr.nx[8][1], dataSetParamStr.nx[8][2]))); + if (comm->isRoot()) + { + finish = MPI_Wtime(); + UBLOG(logINFO, "MPIIORestartCoProcessor::readRelaxationFactor time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readRelaxationFactor start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); + } - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX1(dataSetParamStr.nx1); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX2(dataSetParamStr.nx2); - dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(mFdistributions)->setNX3(dataSetParamStr.nx3); + size_t index = 0; + size_t nextVectorSize = dataSetParamStr.nx[0] * dataSetParamStr.nx[1] * dataSetParamStr.nx[2] * dataSetParamStr.nx[3]; + std::vector<double> vectorsOfValues; + for (int n = 0; n < blocksCount; n++) + { + vectorsOfValues.assign(doubleValuesArray.data() + index, doubleValuesArray.data() + index + nextVectorSize); + index += nextVectorSize; - SPtr<DataSet3D> dataSetPtr = SPtr<DataSet3D>(new DataSet3D()); - dataSetPtr->setAverageDencity(mAverageDensity); - dataSetPtr->setAverageVelocity(mAverageVelocity); - dataSetPtr->setAverageFluctuations(mAverageFluktuations); - dataSetPtr->setAverageTriplecorrelations(mAverageTriplecorrelations); - dataSetPtr->setShearStressValues(mShearStressValues); - dataSetPtr->setRelaxationFactor(mRelaxationFactor); - dataSetPtr->setFdistributions(mFdistributions); + // fill RelaxationFactor array + SPtr<RelaxationFactorArray3D> mRelaxationFactor; + //if ((dataSetParamStr.nx[0] == 0) && (dataSetParamStr.nx[1] == 0) && (dataSetParamStr.nx[2] == 0)) + // mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(); + //else + mRelaxationFactor = CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<LBMReal, IndexerX3X2X1>(vectorsOfValues, dataSetParamStr.nx[0], dataSetParamStr.nx[1], dataSetParamStr.nx[2])); // find the nesessary block and fill it - SPtr<Block3D> block = grid->getBlock(dataSetArray[n].x1, dataSetArray[n].x2, dataSetArray[n].x3, dataSetArray[n].level); - UbTupleInt3 blockNX = grid->getBlockNX(); - this->lbmKernel->setNX(std::array<int, 3>{ {val<1>(blockNX), val<2>(blockNX), val<3>(blockNX)}}); - SPtr<LBMKernel> kernel = this->lbmKernel->clone(); - kernel->setGhostLayerWidth(dataSetArray[n].ghostLayerWidth); - kernel->setCollisionFactor(dataSetArray[n].collFactor); - kernel->setDeltaT(dataSetArray[n].deltaT); - kernel->setCompressible(dataSetArray[n].compressible); - kernel->setWithForcing(dataSetArray[n].withForcing); - kernel->setDataSet(dataSetPtr); - block->setKernel(kernel); - //block->getKernel()->setDataSet(dataSetPtr); + SPtr<Block3D> block = grid->getBlock(dataSetSmallArray[n].x1, dataSetSmallArray[n].x2, dataSetSmallArray[n].x3, dataSetSmallArray[n].level); + block->kernel->getDataSet()->setRelaxationFactor(mRelaxationFactor); } - delete[] dataSetArray; + MPI_Type_free(&dataSetDoubleType); if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::readDataSet end of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readRelaxationFactor end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } + + delete[] dataSetSmallArray; } void MPIIORestartCoProcessor::readBoundaryConds(int step) @@ -1215,16 +2538,16 @@ void MPIIORestartCoProcessor::readBoundaryConds(int step) if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds start MPI IO rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds start MPI IO rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } double start, finish; if (comm->isRoot()) start = MPI_Wtime(); MPI_File file_handler; - std::string filename = path+"/mpi_io_cp/mpi_io_cp_"+UbSystem::toString(step)+"/cpBC.bin"; + std::string filename = path + "/mpi_io_cp/mpi_io_cp_" + UbSystem::toString(step) + "/cpBC.bin"; int rc = MPI_File_open(MPI_COMM_WORLD, filename.c_str(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file_handler); - if (rc!=MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file "+filename); + if (rc != MPI_SUCCESS) throw UbException(UB_EXARGS, "couldn't open file " + filename); int blocksCount = 0; int dataCount1000 = 0; @@ -1234,21 +2557,14 @@ void MPIIORestartCoProcessor::readBoundaryConds(int step) // read count of blocks MPI_File_read_at(file_handler, read_offset1, &blocksCount, 1, MPI_INT, MPI_STATUS_IGNORE); // read count of big BoundaryCondition blocks - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset1+sizeof(int)), &dataCount1000, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset1 + sizeof(int)), &dataCount1000, 1, MPI_INT, MPI_STATUS_IGNORE); // read count of indexContainer values in all blocks - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset1+2*sizeof(int)), &dataCount2, 1, MPI_INT, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset1 + 2 * sizeof(int)), &dataCount2, 1, MPI_INT, MPI_STATUS_IGNORE); // read count of bcindexmatrix values in every block - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset1+3*sizeof(int)), &boundCondParamStr, 1, boundCondParamType, MPI_STATUS_IGNORE); - - //std::cout << "rank=" << rank << ",(rank*read_offset1)=" << rank*read_offset1 << ",blocksCount=" << blocksCount; - //std::cout << ", " << rank*read_offset1 + sizeof(int) << ",bcBlockCount=" << dataCount1000; - //std::cout << ", " << rank*read_offset1 + 2 * sizeof(int) << ",count_indexContainer=" << dataCount2; - //std::cout << ", " << rank*read_offset1 + 3 * sizeof(int) << ",boundCondParamStr=" << boundCondParamStr.bcindexmatrixCount << std::endl; - //std::cout << "readrank=" << rank << ",blocksCount=" << blocksCount << ", " << dataCount1000 << ", " << dataCount2 << ", " << boundCondParamStr.bcindexmatrixCount << std::endl; + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset1 + 3 * sizeof(int)), &boundCondParamStr, 1, boundCondParamType, MPI_STATUS_IGNORE); MPI_Type_contiguous(boundCondParamStr.bcindexmatrixCount, MPI_INT, &bcindexmatrixType); MPI_Type_commit(&bcindexmatrixType); - mpiTypeFreeFlag = true; size_t dataCount = dataCount1000 * BLOCK_SIZE; BCAdd* bcAddArray = new BCAdd[blocksCount]; @@ -1263,35 +2579,33 @@ void MPIIORestartCoProcessor::readBoundaryConds(int step) if (size>1) { - if (rank==0) + if (rank == 0) { - next_read_offset = read_offset+blocksCount*sizeof(BCAdd)+dataCount*sizeof(BoundaryCondition)+(blocksCount * boundCondParamStr.bcindexmatrixCount + dataCount2)*sizeof(int); + next_read_offset = read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition) + (blocksCount * boundCondParamStr.bcindexmatrixCount + dataCount2) * sizeof(int); MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, 1, 5, MPI_COMM_WORLD); } else { - MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank-1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - next_read_offset = read_offset+blocksCount*sizeof(BCAdd)+dataCount*sizeof(BoundaryCondition)+(blocksCount * boundCondParamStr.bcindexmatrixCount + dataCount2)*sizeof(int); - if (rank<size-1) - MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank+1, 5, MPI_COMM_WORLD); + MPI_Recv(&read_offset, 1, MPI_LONG_LONG_INT, rank - 1, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + next_read_offset = read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition) + (blocksCount * boundCondParamStr.bcindexmatrixCount + dataCount2) * sizeof(int); + if (rank<size - 1) + MPI_Send(&next_read_offset, 1, MPI_LONG_LONG_INT, rank + 1, 5, MPI_COMM_WORLD); } } - //std::cout << "readrank=" << rank << ",read_offset=" << read_offset << ", " << read_offset + blocksCount * sizeof(BCAdd) << ", " << read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition) << ", " << read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition) + blocksCount * bcindexmatrixCount * sizeof(int) << std::endl; MPI_File_read_at(file_handler, read_offset, bcAddArray, blocksCount, boundCondTypeAdd, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset+blocksCount*sizeof(BCAdd)), &bcArray[0], dataCount1000, boundCondType1000, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset+blocksCount*sizeof(BCAdd)+dataCount*sizeof(BoundaryCondition)), &intArray1[0], blocksCount, bcindexmatrixType, MPI_STATUS_IGNORE); - MPI_File_read_at(file_handler, (MPI_Offset)(read_offset+blocksCount*sizeof(BCAdd)+dataCount*sizeof(BoundaryCondition)+blocksCount * boundCondParamStr.bcindexmatrixCount*sizeof(int)), &intArray2[0], dataCount2, MPI_INT, MPI_STATUS_IGNORE); - //MPI_File_sync(file_handler); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + blocksCount * sizeof(BCAdd)), &bcArray[0], dataCount1000, boundCondType1000, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition)), &intArray1[0], blocksCount, bcindexmatrixType, MPI_STATUS_IGNORE); + MPI_File_read_at(file_handler, (MPI_Offset)(read_offset + blocksCount * sizeof(BCAdd) + dataCount * sizeof(BoundaryCondition) + blocksCount * boundCondParamStr.bcindexmatrixCount * sizeof(int)), &intArray2[0], dataCount2, MPI_INT, MPI_STATUS_IGNORE); MPI_File_close(&file_handler); if (comm->isRoot()) { finish = MPI_Wtime(); - UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds time: "<<finish-start<<" s"); - UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds start of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds time: " << finish - start << " s"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds start of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } int index = 0, index1 = 0, index2 = 0; @@ -1308,7 +2622,7 @@ void MPIIORestartCoProcessor::readBoundaryConds(int step) for (size_t ibc = 0; ibc<bcAddArray[n].boundCond_count; ibc++) { SPtr<BoundaryConditions> bc; - if (memcmp(&bcArray[index], nullBouCond, sizeof(BoundaryCondition))==0) + if (memcmp(&bcArray[index], nullBouCond, sizeof(BoundaryCondition)) == 0) bc = SPtr<BoundaryConditions>(); else { @@ -1334,20 +2648,6 @@ void MPIIORestartCoProcessor::readBoundaryConds(int step) for (int iq = 0; iq<26; iq++) bc->setQ(bcArray[index].q[iq], iq); bc->setBcAlgorithmType(bcArray[index].algorithmType); - - //if (bcVectorGW[index].nx1 != bc->nx1) - // std::cout << "readBoundaryConds nx1 !!!!===" << bcVectorGW[index].nx1 << " ---- " << bc->nx1 << std::endl; - //if (bcVectorGW[index].nx2 != bc->nx2) - // std::cout << "readBoundaryConds nx2 !!!!===" << bcVectorGW[index].nx2 << " ---- " << bc->nx2 << std::endl; - //if (bcVectorGW[index].nx3 != bc->nx3) - // std::cout << "readBoundaryConds nx3 !!!!===" << bcVectorGW[index].nx3 << " ---- " << bc->nx3 << std::endl; - //if (bcVectorGW[index].algorithmType != bc->algorithmType) - // std::cout << "readBoundaryConds algorithmType !!!!===" << bcVectorGW[index].algorithmType << " ---- " << bc->algorithmType << std::endl; - //for (int iq = 0; iq<26; iq++) - // if (bcVectorGW[index].q[iq] != bc->q[iq]) - // std::cout << "readBoundaryConds q !!!!===" /*<< bcVectorGW[index].q << " ---- " << bc->q*/ << std::endl; - //std::cout << "readBoundaryConds SPtr<BoundaryConditions> !!!!===" <<std::endl; - } bcVector.push_back(bc); @@ -1355,32 +2655,21 @@ void MPIIORestartCoProcessor::readBoundaryConds(int step) } for (int b1 = 0; b1 < boundCondParamStr.bcindexmatrixCount; b1++) - { - //if (bcindexmatrixVGW[index1] != intArray1[index1]) - // std::cout << "readBoundaryConds bcindexmatrixVGW !!!!===" << std::endl; bcindexmatrixV.push_back(intArray1[index1++]); - } + for (int b2 = 0; b2 < bcAddArray[n].indexContainer_count; b2++) - { - //if (indexContainerVGW[index2] != intArray2[index2]) - // std::cout << "readBoundaryConds indexContainerVGW !!!!===" << std::endl; indexContainerV.push_back(intArray2[index2++]); - } CbArray3D<int, IndexerX3X2X1> bcim(bcindexmatrixV, boundCondParamStr.nx1, boundCondParamStr.nx2, boundCondParamStr.nx3); SPtr<Block3D> block = grid->getBlock(bcAddArray[n].x1, bcAddArray[n].x2, bcAddArray[n].x3, bcAddArray[n].level); - //if(!block) std::cout << "readBoundaryConds can't find the block!!!" << std::endl; SPtr<BCProcessor> bcProc = bcProcessor->clone(block->getKernel()); - //if(!bcProc) std::cout << "readBoundaryConds can't find the bcProc!!!" << std::endl; SPtr<BCArray3D> bcArr(new BCArray3D()); bcArr->bcindexmatrix = bcim; bcArr->bcvector = bcVector; bcArr->indexContainer = indexContainerV; bcProc->setBCArray(bcArr); - - //if (!(block->getKernel())) - // std::cout << "readBoundaryConds kernel=" << block->getKernel() <<" "<< bcAddArray[n].x1 << " " << bcAddArray[n].x2 << " " << bcAddArray[n].x3 << std::endl; + block->getKernel()->setBCProcessor(bcProc); } @@ -1389,11 +2678,13 @@ void MPIIORestartCoProcessor::readBoundaryConds(int step) delete[] bcAddArray; delete[] intArray1; delete[] intArray2; - + + MPI_Type_free(&bcindexmatrixType); + if (comm->isRoot()) { - UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds end of restore of data, rank = "<<rank); - UBLOG(logINFO, "Physical Memory currently used by current process: "<<Utilities::getPhysMemUsedByMe()/1073741824.0<<" GB"); + UBLOG(logINFO, "MPIIORestartCoProcessor::readBoundaryConds end of restore of data, rank = " << rank); + UBLOG(logINFO, "Physical Memory currently used by current process: " << Utilities::getPhysMemUsedByMe() / 1073741824.0 << " GB"); } } ////////////////////////////////////////////////////////////////////////// diff --git a/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.h index f6758f9d8..fa95bed83 100644 --- a/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.h +++ b/source/VirtualFluidsCore/CoProcessors/MPIIORestartCoProcessor.h @@ -1,5 +1,5 @@ -#ifndef _MPIIORestart11CoProcessor_H_ -#define _MPIIORestart11CoProcessor_H_ +#ifndef _MPIIORestartCoProcessor_H_ +#define _MPIIORestartCoProcessor_H_ #include <mpi.h> #include <PointerDefinitions.h> @@ -15,14 +15,13 @@ class LBMKernel; //! \class MPIWriteBlocksCoProcessor //! \brief Writes the grid each timestep into the files and reads the grip from the files before regenerating -//! \author Alena Karanchuk -class MPIIORestartCoProcessor: public CoProcessor +class MPIIORestartCoProcessor : public CoProcessor { //! \struct GridParam //! \brief Structure describes parameters of the grid //! \details The structure is nessasary to restore the grid correctly struct GridParam - { + { double trafoParams[33]; double deltaX; int blockNx1; @@ -36,83 +35,93 @@ class MPIIORestartCoProcessor: public CoProcessor bool periodicX3; bool active; bool transformation; - }; + }; //! \struct Block3d //! \brief Structure contains information of the block //! \details The structure is used to write the data describing the block in the grid when saving the grid //! and to read it when restoring the grid struct Block3d - { - int x1; - int x2; - int x3; - int bundle; - int rank; - int lrank; - int part; - int globalID; - int localID; - int level; - int interpolationFlagCF; - int interpolationFlagFC; - int counter; - bool active; - }; + { + int x1; + int x2; + int x3; + int bundle; + int rank; + int lrank; + int part; + int globalID; + int localID; + int level; + int interpolationFlagCF; + int interpolationFlagFC; + int counter; + bool active; + }; //! \struct dataSetParam - //! \brief Structure describes parameters of the dataSet that are equal in all blocks + //! \brief Structure describes parameters of one array of the dataSet that are equal in all blocks //! \details The structure used to store some parameters needed to restore dataSet arrays struct dataSetParam { - int nx1; + int nx1; int nx2; int nx3; - int nx[9][4]; // 9 arrays x (nx1, nx2, nx3, nx4) - int doubleCountInBlock; // how many double-values are in all arrays dataSet in one (any) block + int nx[4]; // nx1, nx2, nx3, nx4 }; //! \struct dataSet //! \brief Structure containes information identifying the block //! \details The structure is used to find the needed block in the grid when restoring a dataSet struct DataSet - { + { double collFactor; double deltaT; - int x1; // to find the right block - int x2; - int x3; - int level; + int x1; + int x2; + int x3; + int level; int ghostLayerWidth; bool compressible; bool withForcing; }; - + + //! \struct dataSetSmall + //! \brief Structure containes information identifying the block + //! \details The structure is used to find the needed block in the grid when restoring a dataSet arrays + struct DataSetSmall + { + int x1; + int x2; + int x3; + int level; + }; + //! \struct BoundaryCondition //! \brief Structure containes information about boundary conditions of the block //! \details The structure is used to write data describing boundary conditions of the blocks when saving the grid //! and to read it when restoring the grid struct BoundaryCondition - { - long long noslipBoundaryFlags; // MPI_LONG_LONG - long long slipBoundaryFlags; - long long velocityBoundaryFlags; - long long densityBoundaryFlags; - long long wallModelBoundaryFlags; - - float bcVelocityX1; - float bcVelocityX2; - float bcVelocityX3; - float bcDensity; - - float bcLodiDensity; - float bcLodiVelocityX1; - float bcLodiVelocityX2; - float bcLodiVelocityX3; - float bcLodiLentgh; - - float nx1,nx2,nx3; - float q[26]; // MPI_FLOAT + { + long long noslipBoundaryFlags; // MPI_LONG_LONG + long long slipBoundaryFlags; + long long velocityBoundaryFlags; + long long densityBoundaryFlags; + long long wallModelBoundaryFlags; + + float bcVelocityX1; + float bcVelocityX2; + float bcVelocityX3; + float bcDensity; + + float bcLodiDensity; + float bcLodiVelocityX1; + float bcLodiVelocityX2; + float bcLodiVelocityX3; + float bcLodiLentgh; + + float nx1, nx2, nx3; + float q[26]; // MPI_FLOAT char algorithmType; }; @@ -127,22 +136,32 @@ class MPIIORestartCoProcessor: public CoProcessor int nx3; int bcindexmatrixCount; // how many bcindexmatrix-values in one (any) block }; - + //! \struct BCAdd //! \brief Structure containes information identifying the block //! and some parameters of the arrays of boundary conditions that are equal in all blocks //! \details The structure is used to find the needed block in the grid when restoring a dataSet //! and to set common parameters struct BCAdd - { - int x1; // to find the right block - int x2; - int x3; - int level; + { + int x1; // to find the right block + int x2; + int x3; + int level; int boundCond_count; // how many BoundaryCondition-structures are in this block int indexContainer_count; // how many indexContainer-values are in this block }; + struct DSArraysPresence + { + bool isAverageDensityArrayPresent; + bool isAverageVelocityArrayPresent; + bool isAverageFluktuationsArrayPresent; + bool isAverageTripleArrayPresent; + bool isShearStressValArrayPresent; + bool isRelaxationFactorPresent; + }; + public: MPIIORestartCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s, const std::string& path, SPtr<Communicator> comm); virtual ~MPIIORestartCoProcessor(); @@ -150,17 +169,30 @@ public: void process(double step); //! Reads the grid from the files before grid reconstruction void restart(int step); - //! Writes the blocks of the grid into the file outputBlocks.bin + //! Writes the blocks of the grid into the file cpBlocks.bin void writeBlocks(int step); - //! Writes the datasets of the blocks into the file outputDataSet.bin + //! Writes the datasets of the blocks into the file cpDataSet.bin void writeDataSet(int step); - //! Writes the boundary conditions of the blocks into the file outputBoundCond.bin + void writeAverageDensityArray(int step); + void writeAverageVelocityArray(int step); + void writeAverageFluktuationsArray(int step); + void writeAverageTripleArray(int step); + void writeShearStressValArray(int step); + void writeRelaxationFactor(int step); + //! Writes the boundary conditions of the blocks into the file cpBC.bin void writeBoundaryConds(int step); - //! Reads the blocks of the grid from the file outputBlocks.bin + + //! Reads the blocks of the grid from the file cpBlocks.bin void readBlocks(int step); - //! Reads the datasets of the blocks from the file outputDataSet.bin + //! Reads the datasets of the blocks from the file cpDataSet.bin void readDataSet(int step); - //! Reads the boundary conditions of the blocks from the file outputBoundCond.bin + void readAverageDensityArray(int step); + void readAverageVelocityArray(int step); + void readAverageFluktuationsArray(int step); + void readAverageTripleArray(int step); + void readShearStressValArray(int step); + void readRelaxationFactor(int step); + //! Reads the boundary conditions of the blocks from the file cpBC.bin void readBoundaryConds(int step); //! The function sets LBMKernel void setLBMKernel(SPtr<LBMKernel> kernel); @@ -172,11 +204,12 @@ public: protected: std::string path; SPtr<Communicator> comm; - bool mpiTypeFreeFlag; private: - MPI_Datatype gridParamType, block3dType, dataSetParamType, dataSetType, dataSetDoubleType, boundCondParamType, boundCondType, boundCondType1000, boundCondTypeAdd, bcindexmatrixType; - dataSetParam dataSetParamStr; + MPI_Datatype gridParamType, block3dType, arrayPresenceType; + MPI_Datatype dataSetParamType, dataSetType, dataSetSmallType, dataSetDoubleType; + MPI_Datatype boundCondParamType, boundCondType, boundCondType1000, boundCondTypeAdd, bcindexmatrixType; + boundCondParam boundCondParamStr; SPtr<LBMKernel> lbmKernel; SPtr<BCProcessor> bcProcessor; diff --git a/source/VirtualFluidsCore/CoProcessors/WriteMQFromSelectionCoProcessor.cpp b/source/VirtualFluidsCore/CoProcessors/WriteMQFromSelectionCoProcessor.cpp new file mode 100644 index 000000000..1d3221ddf --- /dev/null +++ b/source/VirtualFluidsCore/CoProcessors/WriteMQFromSelectionCoProcessor.cpp @@ -0,0 +1,237 @@ +#include "WriteMQFromSelectionCoProcessor.h" +#include "LBMKernel.h" +#include "BCProcessor.h" +#include <vector> +#include <string> + +#include "basics/writer/WbWriterVtkXmlASCII.h" +#include "DataSet3D.h" +#include "UbScheduler.h" +#include "Grid3D.h" +#include "Communicator.h" +#include "LBMUnitConverter.h" +#include "Block3D.h" +#include "BCArray3D.h" +#include "GbObject3D.h" + +WriteMQFromSelectionCoProcessor::WriteMQFromSelectionCoProcessor() +{ + +} +////////////////////////////////////////////////////////////////////////// +WriteMQFromSelectionCoProcessor::WriteMQFromSelectionCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s, + SPtr<GbObject3D> gbObject, + const std::string& path, WbWriter* const writer, + SPtr<LBMUnitConverter> conv, + SPtr<Communicator> comm) + : CoProcessor(grid, s), + gbObject(gbObject), + path(path), + writer(writer), + conv(conv), + comm(comm) +{ + gridRank = comm->getProcessID(); + minInitLevel = this->grid->getCoarsestInitializedLevel(); + maxInitLevel = this->grid->getFinestInitializedLevel(); + + blockVector.resize(maxInitLevel+1); + + for (int level = minInitLevel; level<=maxInitLevel; level++) + { + grid->getBlocks(level, gridRank, true, blockVector[level]); + } +} +////////////////////////////////////////////////////////////////////////// +void WriteMQFromSelectionCoProcessor::init() +{ + +} +////////////////////////////////////////////////////////////////////////// +void WriteMQFromSelectionCoProcessor::process(double step) +{ + if(scheduler->isDue(step) ) + collectData(step); + + UBLOG(logDEBUG3, "WriteMQFromSelectionCoProcessor::update:" << step); +} +////////////////////////////////////////////////////////////////////////// +void WriteMQFromSelectionCoProcessor::collectData(double step) +{ + int istep = static_cast<int>(step); + + for(int level = minInitLevel; level<=maxInitLevel;level++) + { + for(SPtr<Block3D> block : blockVector[level]) + { + if (block) + { + UbTupleDouble3 org = grid->getBlockWorldCoordinates(block); + UbTupleDouble3 blockLengths = grid->getBlockLengths(block); + + double minX1 = val<1>(org); + double minX2 = val<2>(org); + double minX3 = val<3>(org); + double maxX1 = val<1>(org)+val<1>(blockLengths); + double maxX2 = val<2>(org)+val<2>(blockLengths); + double maxX3 = val<3>(org)+val<3>(blockLengths); + + if (gbObject->isCellInsideOrCuttingGbObject3D(minX1, minX2, minX3, maxX1, maxX2, maxX3)) + { + addDataMQ(block); + } + } + } + } + + std::string pfilePath, partPath, subfolder, cfilePath; + + subfolder = "mqSelect"+UbSystem::toString(istep); + pfilePath = path+"/mqSelect/"+subfolder; + cfilePath = path+"/mqSelect/mq_collection"; + partPath = pfilePath+"/mqSelect"+UbSystem::toString(gridRank)+ "_" + UbSystem::toString(istep); + + + std::string partName = writer->writeNodesWithNodeData(partPath,nodes,datanames,data); + size_t found=partName.find_last_of("/"); + std::string piece = partName.substr(found+1); + piece = subfolder + "/" + piece; + + std::vector<std::string> cellDataNames; + SPtr<Communicator> comm = Communicator::getInstance(); + std::vector<std::string> pieces = comm->gather(piece); + if (comm->getProcessID() == comm->getRoot()) + { + std::string pname = WbWriterVtkXmlASCII::getInstance()->writeParallelFile(pfilePath,pieces,datanames,cellDataNames); + found=pname.find_last_of("/"); + piece = pname.substr(found+1); + + std::vector<std::string> filenames; + filenames.push_back(piece); + if (step == CoProcessor::scheduler->getMinBegin()) + { + WbWriterVtkXmlASCII::getInstance()->writeCollection(cfilePath,filenames,istep,false); + } + else + { + WbWriterVtkXmlASCII::getInstance()->addFilesToCollection(cfilePath,filenames,istep,false); + } + UBLOG(logINFO,"WriteMQFromSelectionCoProcessor step: " << istep); + } + + clearData(); +} +////////////////////////////////////////////////////////////////////////// +void WriteMQFromSelectionCoProcessor::clearData() +{ + nodes.clear(); + datanames.clear(); + data.clear(); +} +////////////////////////////////////////////////////////////////////////// +void WriteMQFromSelectionCoProcessor::addDataMQ(SPtr<Block3D> block) +{ + double level = (double)block->getLevel(); + double blockID = (double)block->getGlobalID(); + + //Diese Daten werden geschrieben: + datanames.resize(0); + datanames.push_back("Rho"); + datanames.push_back("Vx"); + datanames.push_back("Vy"); + datanames.push_back("Vz"); + //datanames.push_back("Press"); + datanames.push_back("Level"); + //datanames.push_back("BlockID"); + + + + data.resize(datanames.size()); + + SPtr<ILBMKernel> kernel = block->getKernel(); + SPtr<BCArray3D> bcArray = kernel->getBCProcessor()->getBCArray(); + SPtr<DistributionArray3D> distributions = kernel->getDataSet()->getFdistributions(); + LBMReal f[D3Q27System::ENDF+1]; + LBMReal vx1,vx2,vx3,rho; + + if(block->getKernel()->getCompressible()) + { + calcMacros = &D3Q27System::calcCompMacroscopicValues; + } + else + { + calcMacros = &D3Q27System::calcIncompMacroscopicValues; + } + + int minX1 = 0; + int minX2 = 0; + int minX3 = 0; + + int maxX1 = (int)(distributions->getNX1()); + int maxX2 = (int)(distributions->getNX2()); + int maxX3 = (int)(distributions->getNX3()); + + //int minX1 = 1; + //int minX2 = 1; + //int minX3 = 1; + + //int maxX1 = (int)(distributions->getNX1()); + //int maxX2 = (int)(distributions->getNX2()); + //int maxX3 = (int)(distributions->getNX3()); + + //nummern vergeben und node vector erstellen + daten sammeln + CbArray3D<int> nodeNumbers((int)maxX1, (int)maxX2, (int)maxX3,-1); + maxX1 -= 2; + maxX2 -= 2; + maxX3 -= 2; + + //D3Q27BoundaryConditionPtr bcPtr; + int nr = (int)nodes.size(); + + for(int ix3=minX3; ix3<=maxX3; ix3++) + { + for(int ix2=minX2; ix2<=maxX2; ix2++) + { + for(int ix1=minX1; ix1<=maxX1; ix1++) + { + if(!bcArray->isUndefined(ix1,ix2,ix3) && !bcArray->isSolid(ix1,ix2,ix3)) + { + Vector3D worldCoordinates = grid->getNodeCoordinates(block, ix1, ix2, ix3); + if (gbObject->isPointInGbObject3D(worldCoordinates[0], worldCoordinates[1], worldCoordinates[2])) + { + int index = 0; + nodeNumbers(ix1, ix2, ix3) = nr++; + + nodes.push_back(UbTupleFloat3(float(worldCoordinates[0]), + float(worldCoordinates[1]), + float(worldCoordinates[2]))); + + distributions->getDistribution(f, ix1, ix2, ix3); + calcMacros(f, rho, vx1, vx2, vx3); + + if (UbMath::isNaN(rho) || UbMath::isInfinity(rho)) + UB_THROW(UbException(UB_EXARGS, "rho is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+ + ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3))); + if (UbMath::isNaN(vx1) || UbMath::isInfinity(vx1)) + UB_THROW(UbException(UB_EXARGS, "vx1 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+ + ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3))); + //vx1=999.0; + if (UbMath::isNaN(vx2) || UbMath::isInfinity(vx2)) + UB_THROW(UbException(UB_EXARGS, "vx2 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+ + ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3))); + //vx2=999.0; + if (UbMath::isNaN(vx3) || UbMath::isInfinity(vx3)) + UB_THROW(UbException(UB_EXARGS, "vx3 is not a number (nan or -1.#IND) or infinity number -1.#INF in block="+block->toString()+ + ", node="+UbSystem::toString(ix1)+","+UbSystem::toString(ix2)+","+UbSystem::toString(ix3))); + + data[index++].push_back(rho); + data[index++].push_back(vx1); + data[index++].push_back(vx2); + data[index++].push_back(vx3); + data[index++].push_back(level); + } + } + } + } + } +} diff --git a/source/VirtualFluidsCore/CoProcessors/WriteMQFromSelectionCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/WriteMQFromSelectionCoProcessor.h new file mode 100644 index 000000000..886fed0f8 --- /dev/null +++ b/source/VirtualFluidsCore/CoProcessors/WriteMQFromSelectionCoProcessor.h @@ -0,0 +1,57 @@ +#ifndef WriteMQFromSelectionCoProcessor_H +#define WriteMQFromSelectionCoProcessor_H + +#include <PointerDefinitions.h> +#include <string> +#include <vector> + +#include "CoProcessor.h" + +#include "LBMSystem.h" + +class Communicator; +class Grid3D; +class UbScheduler; +class LBMUnitConverter; +class WbWriter; +class Block3D; +class GbObject3D; + +class WriteMQFromSelectionCoProcessor : public CoProcessor +{ +public: + WriteMQFromSelectionCoProcessor(); + WriteMQFromSelectionCoProcessor(SPtr<Grid3D> grid, SPtr<UbScheduler> s, + SPtr<GbObject3D> gbObject, + const std::string& path, WbWriter* const writer, + SPtr<LBMUnitConverter> conv, SPtr<Communicator> comm); + ~WriteMQFromSelectionCoProcessor(){} + + void process(double step) override; + +protected: + void collectData(double step); + void addDataMQ(SPtr<Block3D> block); + void clearData(); + +private: + void init(); + std::vector<UbTupleFloat3> nodes; + std::vector<std::string> datanames; + std::vector<std::vector<double> > data; + std::string path; + WbWriter* writer; + SPtr<LBMUnitConverter> conv; + bool bcInformation; + std::vector<std::vector<SPtr<Block3D> > > blockVector; + int minInitLevel; + int maxInitLevel; + int gridRank; + SPtr<Communicator> comm; + SPtr<GbObject3D> gbObject; + + typedef void(*CalcMacrosFct)(const LBMReal* const& /*feq[27]*/, LBMReal& /*(d)rho*/, LBMReal& /*vx1*/, LBMReal& /*vx2*/, LBMReal& /*vx3*/); + CalcMacrosFct calcMacros; +}; + +#endif diff --git a/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h b/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h index 6618468bf..ca6e2fcb4 100644 --- a/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h +++ b/source/VirtualFluidsCore/CoProcessors/WriteMacroscopicQuantitiesCoProcessor.h @@ -1,5 +1,5 @@ -#ifndef D3Q27MACROSCOPICQUANTITIESCoProcessor_H -#define D3Q27MACROSCOPICQUANTITIESCoProcessor_H +#ifndef WriteMacroscopicQuantitiesCoProcessor_H +#define WriteMacroscopicQuantitiesCoProcessor_H #include <PointerDefinitions.h> #include <string> @@ -30,7 +30,6 @@ public: protected: void collectData(double step); void addDataMQ(SPtr<Block3D> block); - void addDataGeo(SPtr<Block3D> block); void clearData(); private: diff --git a/source/VirtualFluidsCore/Interactors/Interactor3D.cpp b/source/VirtualFluidsCore/Interactors/Interactor3D.cpp index b8b17262c..d4380b076 100644 --- a/source/VirtualFluidsCore/Interactors/Interactor3D.cpp +++ b/source/VirtualFluidsCore/Interactors/Interactor3D.cpp @@ -218,12 +218,12 @@ void Interactor3D::setSolidBlock(SPtr<Block3D> block) UbTupleDouble3 nodeOffset = grid.lock()->getNodeOffset(block); //coordinates of block without ghost layer - minX1 = val<1>(org) - val<1>(nodeOffset); - minX2 = val<2>(org) - val<2>(nodeOffset); - minX3 = val<3>(org) - val<3>(nodeOffset); - maxX1 = val<1>(org) + val<1>(blockLengths) + val<1>(nodeOffset); - maxX2 = val<2>(org) + val<2>(blockLengths) + val<2>(nodeOffset); - maxX3 = val<3>(org) + val<3>(blockLengths) + val<3>(nodeOffset); + minX1 = val<1>(org) + val<1>(nodeOffset); + minX2 = val<2>(org) + val<2>(nodeOffset); + minX3 = val<3>(org) + val<3>(nodeOffset); + maxX1 = val<1>(org) + val<1>(blockLengths) - val<1>(nodeOffset); + maxX2 = val<2>(org) + val<2>(blockLengths) - val<2>(nodeOffset); + maxX3 = val<3>(org) + val<3>(blockLengths) - val<3>(nodeOffset); if(this->isInverseSolid()) { diff --git a/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp b/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp index 2ad82c218..1d3f09c94 100644 --- a/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp +++ b/source/VirtualFluidsCore/Visitors/GenBlocksGridVisitor.cpp @@ -55,12 +55,20 @@ void GenBlocksGridVisitor::genBlocks(SPtr<Grid3D> grid) double geoMaxX3 = boundingBox->getX3Maximum(); maxInd = grid->getBlockIndexes(geoMaxX1, geoMaxX2, geoMaxX3); UbTupleDouble3 blockCoord = grid->getBlockWorldCoordinates(static_cast<int>(val<1>(maxInd)), static_cast<int>(val<2>(maxInd)), static_cast<int>(val<3>(maxInd)), 0); - if (geoMaxX1 > val<1>(blockCoord)) - val<1>(maxInd) += 1; - if (geoMaxX2 > val<2>(blockCoord)) - val<2>(maxInd) += 1; - if (geoMaxX3 > val<3>(blockCoord)) - val<3>(maxInd) += 1; + //if (geoMaxX1 > val<1>(blockCoord)) + // val<1>(maxInd) += 1; + //if (geoMaxX2 > val<2>(blockCoord)) + // val<2>(maxInd) += 1; + //if (geoMaxX3 > val<3>(blockCoord)) + // val<3>(maxInd) += 1; + + double dx = grid->getDeltaX(0); + if (fabs(geoMaxX1-val<1>(blockCoord)) > dx) + val<1>(maxInd) += 1; + if (fabs(geoMaxX2-val<2>(blockCoord)) > dx) + val<2>(maxInd) += 1; + if (fabs(geoMaxX3-val<3>(blockCoord)) > dx) + val<3>(maxInd) += 1; this->fillExtentWithBlocks(grid); diff --git a/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp b/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp index c9cd16c09..0db46d74d 100644 --- a/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp +++ b/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp @@ -4,16 +4,18 @@ #include "Grid3D.h" #include "Block3D.h" -#include "ILBMKernel.h" +#include "LBMKernel.h" #include "UbException.h" - -#include "CompressibleCumulant4thOrderViscosityLBMKernel.h" - +#include "D3Q27System.h" #include <numerics/geometry3d/GbCuboid3D.h> using namespace std; -SpongeLayerBlockVisitor::SpongeLayerBlockVisitor() : Block3DVisitor(0, Grid3DSystem::MAXLEVEL) +SpongeLayerBlockVisitor::SpongeLayerBlockVisitor(SPtr<GbCuboid3D> boundingBox, SPtr<LBMKernel> kernel, int dir) : + Block3DVisitor(0, Grid3DSystem::MAXLEVEL), + boundingBox(boundingBox), + kernel(kernel), + dir(dir) { } @@ -71,15 +73,41 @@ void SpongeLayerBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block) double oldCollFactor = newKernel->getCollisionFactor(); - int ibX1 = block->getX1(); - + UbTupleInt3 ixMin = grid->getBlockIndexes(boundingBox->getX1Minimum(),boundingBox->getX2Minimum(),boundingBox->getX3Minimum()); UbTupleInt3 ixMax = grid->getBlockIndexes(boundingBox->getX1Maximum(),boundingBox->getX2Maximum(),boundingBox->getX3Maximum()); - int ibMax = val<1>(ixMax)-val<1>(ixMin)+1; - double index = (double)(ibX1-val<1>(ixMin)+1); + double newCollFactor; + + if (dir == D3Q27System::E) + { + int ibX1 = block->getX1(); + int ibMax = val<1>(ixMax)-val<1>(ixMin)+1; + double index = (double)(ibX1-val<1>(ixMin)+1); + newCollFactor = oldCollFactor - (oldCollFactor-1.0)/(double)(ibMax)*index; + } + else if (dir == D3Q27System::W) + { + int ibX1 = block->getX1(); + int ibMax = val<1>(ixMax)-val<1>(ixMin)+1; + double index = (double)(ibX1-val<1>(ixMin)+1); + newCollFactor = (oldCollFactor-1.0)/(double)(ibMax)*index; + } + else if (dir == D3Q27System::T) + { + int ibX3 = block->getX3(); + int ibMax = val<3>(ixMax)-val<3>(ixMin)+1; + double index = (double)(ibX3-val<3>(ixMin)+1); + newCollFactor = oldCollFactor - (oldCollFactor-1.0)/(double)(ibMax)*index; + } + else if (dir == D3Q27System::B) + { + int ibX3 = block->getX3(); + int ibMax = val<3>(ixMax)-val<3>(ixMin)+1; + double index = (double)(ibX3-val<3>(ixMin)+1); + newCollFactor = (oldCollFactor-1.0)/(double)(ibMax)*index; + } - double newCollFactor = oldCollFactor - (oldCollFactor-1.0)/(double)(ibMax)*index; newKernel->setCollisionFactor(newCollFactor); block->setKernel(newKernel); @@ -87,14 +115,6 @@ void SpongeLayerBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block) } } ////////////////////////////////////////////////////////////////////////// -void SpongeLayerBlockVisitor::setBoundingBox(SPtr<GbCuboid3D> bb) -{ - boundingBox = bb; -} -////////////////////////////////////////////////////////////////////////// -void SpongeLayerBlockVisitor::setKernel(SPtr<LBMKernel> k) -{ - kernel = k; -} + diff --git a/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.h b/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.h index 9e4adc570..8518ab22b 100644 --- a/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.h +++ b/source/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.h @@ -15,18 +15,15 @@ class LBMKernel; class SpongeLayerBlockVisitor : public Block3DVisitor { public: - SpongeLayerBlockVisitor(); + SpongeLayerBlockVisitor(SPtr<GbCuboid3D> boundingBox, SPtr<LBMKernel> kernel, int dir); virtual ~SpongeLayerBlockVisitor(); void visit(SPtr<Grid3D> grid, SPtr<Block3D> block) override; - void setBoundingBox(SPtr<GbCuboid3D> boundingBox); - void setKernel(SPtr<LBMKernel> k); - private: SPtr<GbCuboid3D> boundingBox; SPtr<LBMKernel> kernel; - LBMReal viscosity; + int dir; }; #endif // SetSpongeLayerBlockVisitor_h__ -- GitLab