From cb997965ef878ee39179c8837d1771121e579de5 Mon Sep 17 00:00:00 2001
From: Anna Wellmann <a.wellmann@tu-braunschweig.de>
Date: Fri, 11 Mar 2022 17:47:53 +0100
Subject: [PATCH] Add tests for
 IndexRearrangementForStreams::getGridInterfaceIndicesBorderBulkCF()

---
 src/gpu/GridGenerator/grid/GridImp.h          |   2 +-
 .../IndexRearrangementForStreams.cpp          |   8 +-
 .../IndexRearrangementForStreams.h            |   4 +
 .../IndexRearrangementForStreamsTest.cfg      |   3 +
 .../IndexRearrangementForStreamsTest.cpp      | 238 ++++++++++++++++++
 5 files changed, 250 insertions(+), 5 deletions(-)
 create mode 100644 src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cfg

diff --git a/src/gpu/GridGenerator/grid/GridImp.h b/src/gpu/GridGenerator/grid/GridImp.h
index 4ae18181f..08c4f795b 100644
--- a/src/gpu/GridGenerator/grid/GridImp.h
+++ b/src/gpu/GridGenerator/grid/GridImp.h
@@ -39,7 +39,7 @@ extern CONSTANT int DIRECTIONS[DIR_END_MAX][DIMENSION];
 
 class GRIDGENERATOR_EXPORT GridImp : public enableSharedFromThis<GridImp>, public Grid
 {
-private:
+protected:
     CUDA_HOST GridImp();
     CUDA_HOST GridImp(Object* object, real startX, real startY, real startZ, real endX, real endY, real endZ, real delta, SPtr<GridStrategy> gridStrategy, Distribution d, uint level);
 
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreams.cpp b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreams.cpp
index 961805467..d1c4ac53f 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreams.cpp
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreams.cpp
@@ -488,7 +488,7 @@ void IndexRearrangementForStreams::splitCoarseToFineIntoBorderAndBulk(const uint
 
 void IndexRearrangementForStreams::getGridInterfaceIndicesBorderBulkCF(int level) 
 { 
-    // this function reorders the arrays of CFC/CFF indices and sets pointers and sizes of the new subarrays
+    // this function reorders the arrays of CFC/CFF indices and sets the pointers and sizes of the new subarrays
      
     // create some local variables for better readability
     uint *iCellCfcAll    = para->getParH(level)->intCF.ICellCFC;
@@ -559,8 +559,8 @@ void IndexRearrangementForStreams::getGridInterfaceIndicesBorderBulkCF(int level
     for (uint i = 0; i < (uint)iCellCfcBulkVector.size(); i++) {
         para->getParH(level)->intCFBulk.ICellCFC[i]                       = iCellCfcBulkVector[i];
         para->getParH(level)->intCFBulk.ICellCFF[i]                       = iCellCffBulkVector[i];
-        para->getParH(level)->offCF.xOffCF[i + xOffCFBorderVector.size()] = xOffCFBulkVector[i];
-        para->getParH(level)->offCF.yOffCF[i + yOffCFBorderVector.size()] = yOffCFBulkVector[i];
-        para->getParH(level)->offCF.zOffCF[i + zOffCFBorderVector.size()] = zOffCFBulkVector[i];
+        para->getParH(level)->offCFBulk.xOffCF[i]                         = xOffCFBulkVector[i];
+        para->getParH(level)->offCFBulk.yOffCF[i]                         = yOffCFBulkVector[i];
+        para->getParH(level)->offCFBulk.zOffCF[i]                         = zOffCFBulkVector[i];
     }
 }
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreams.h b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreams.h
index 1ea5e6f1d..56914feda 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreams.h
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreams.h
@@ -77,6 +77,10 @@ private:
     // split interpolation cells
     void getGridInterfaceIndicesBorderBulkCF(int level);
     void getGridInterfaceIndicesBorderBulkFC(int level);
+
+
+
+    friend class IndexRearrangementForStreamsTest;
 };
 
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cfg b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cfg
new file mode 100644
index 000000000..e414d4f31
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cfg
@@ -0,0 +1,3 @@
+# these two parameters need to be defined in each config file
+Path = /output/path
+GridPath = /path/to/grid
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cpp b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cpp
index b6d2984da..048ae98b3 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cpp
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cpp
@@ -20,3 +20,241 @@ auto RealEq = [](auto value) {
 #endif
 };
 
+
+class GridBuilderDouble : public LevelGridBuilder
+{
+private:
+    SPtr<Grid> grid;
+    GridBuilderDouble()=default;
+
+public:
+    GridBuilderDouble(SPtr<Grid> grid) : LevelGridBuilder(Device(), ""), grid(grid){};
+    SPtr<Grid> getGrid(uint level) override{ return grid; };
+};
+
+
+class GridImpDouble : public GridImp
+{
+private:
+    std::vector<uint> fluidNodeIndicesBorder;
+
+public:
+    GridImpDouble(Object *object, real startX, real startY, real startZ, real endX, real endY, real endZ, real delta,
+                   SPtr<GridStrategy> gridStrategy, Distribution d, uint level)
+        : GridImp(object, startX, startY, startZ, endX, endY, endZ, delta, gridStrategy, d, level)
+    {
+    }
+
+    static SPtr<GridImpDouble> makeShared(Object *object, real startX, real startY, real startZ, real endX, real endY,
+                                           real endZ, real delta, SPtr<GridStrategy> gridStrategy, Distribution d,
+                                          uint level)
+    {
+        SPtr<GridImpDouble> grid(
+            new GridImpDouble(object, startX, startY, startZ, endX, endY, endZ, delta, gridStrategy, d, level));
+        return grid;
+    }
+
+    void setFluidNodeIndicesBorder(std::vector<uint> fluidNodeIndicesBorder)
+    {
+        this->fluidNodeIndicesBorder = fluidNodeIndicesBorder;
+    }
+
+    bool isSparseIndexInFluidNodeIndicesBorder(uint& sparseIndex) const override { 
+        return std::find(this->fluidNodeIndicesBorder.begin(), this->fluidNodeIndicesBorder.end(), sparseIndex)!=this->fluidNodeIndicesBorder.end();
+    }
+};
+
+struct CFBorderBulk {
+    // data to work on
+    std::vector<uint> fluidNodeIndicesBorder = { 10, 11, 12, 13, 14, 15, 16 };
+    std::vector<uint> iCellCFC               = { 1, 11, 3, 13, 5, 15, 7 };
+    std::vector<uint> iCellCFF               = { 2, 12, 4, 14, 6, 16, 8 };
+    uint sizeOfICellCf                       = iCellCFC.size();
+    uint neighborX_SP[17]                    = { 0u };
+    uint neighborY_SP[17]                    = { 0u };
+    uint neighborZ_SP[17]                    = { 0u };
+    int level                                = 0;
+    std::vector<real> offsetCFx              = { 1, 11, 3, 13, 5, 15, 7 };
+    std::vector<real> offsetCFy              = { 101, 111, 103, 113, 105, 115, 107 };
+    std::vector<real> offsetCFz              = { 1001, 1011, 1003, 1013, 1005, 1015, 1007 };
+
+    // expected data
+    std::vector<uint> iCellCfcBorder_expected = { 11, 13, 15 };
+    std::vector<uint> iCellCfcBulk_expected   = { 1, 3, 5, 7 };
+    std::vector<uint> iCellCffBorder_expected = { 12, 14, 16 };
+    std::vector<uint> iCellCffBulk_expected   = { 2, 4, 6, 8 };
+    std::vector<uint> offsetCFx_Border_expected = { 11, 13, 15 };
+    std::vector<uint> offsetCFx_Bulk_expected   = { 1, 3, 5, 7 };
+    std::vector<uint> offsetCFy_Border_expected = { 111, 113, 115 };
+    std::vector<uint> offsetCFy_Bulk_expected   = { 101, 103, 105, 107 };
+    std::vector<uint> offsetCFz_Border_expected = { 1011, 1013, 1015 };
+    std::vector<uint> offsetCFz_Bulk_expected   = { 1001, 1003, 1005, 1007 };
+};
+
+
+static void initParameterClass(std::shared_ptr<Parameter> &para);
+
+class IndexRearrangementForStreamsTest
+{
+public:
+    static void setUpAndRun_getGridInterfaceIndicesBorderBulkCF(CFBorderBulk &cf, std::shared_ptr<Parameter> para)
+    {
+        SPtr<GridImpDouble> grid =
+            GridImpDouble::makeShared(nullptr, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, nullptr, Distribution(), 1);
+        grid->setFluidNodeIndicesBorder(cf.fluidNodeIndicesBorder);
+        std::shared_ptr<GridBuilderDouble> builder = std::make_shared<GridBuilderDouble>(grid);
+
+        para->setMaxLevel(cf.level + 1);
+        para->parH[cf.level]                    = std::make_shared<LBMSimulationParameter>();
+        para->parD[cf.level]                    = std::make_shared<LBMSimulationParameter>();
+        para->getParH(cf.level)->intCF.ICellCFC = &(cf.iCellCFC.front());
+        para->getParH(cf.level)->intCF.ICellCFF = &(cf.iCellCFF.front());
+        para->getParH(cf.level)->neighborX_SP   = cf.neighborX_SP;
+        para->getParH(cf.level)->neighborY_SP   = cf.neighborY_SP;
+        para->getParH(cf.level)->neighborZ_SP   = cf.neighborZ_SP;
+        para->getParH(cf.level)->intCF.kCF      = cf.sizeOfICellCf;
+        para->getParH(cf.level)->offCF.xOffCF   = &(cf.offsetCFx.front());
+        para->getParH(cf.level)->offCF.yOffCF   = &(cf.offsetCFy.front());
+        para->getParH(cf.level)->offCF.zOffCF   = &(cf.offsetCFz.front());
+
+        IndexRearrangementForStreams testSubject = IndexRearrangementForStreams(para, builder);
+
+        testSubject.getGridInterfaceIndicesBorderBulkCF(cf.level);
+    };
+};
+
+void initParameterClass(std::shared_ptr<Parameter> &para)
+{
+    std::filesystem::path filePath = __FILE__; //  assuming that the config file is stored parallel to this file.
+    filePath.replace_filename("IndexRearrangementForStreamsTest.cfg");
+    vf::basics::ConfigurationFile config;
+    config.load(filePath.string());
+    para = std::make_shared<Parameter>(config, 1, 0);
+}
+
+bool vectorsAreEqual(std::vector<uint> vector1, std::vector<uint> vectorExpected)
+{
+    for (uint i = 0; i < (uint)vectorExpected.size(); i++) {
+        if (vector1[i] != vectorExpected[i])
+            return false;
+    }
+    return true;
+}
+
+bool vectorsAreEqual(uint *vector1, std::vector<uint> vectorExpected)
+{
+    for (uint i = 0; i < vectorExpected.size(); i++) {
+        if (vector1[i] != vectorExpected[i])
+            return false;
+    }
+    return true;
+}
+
+bool vectorsAreEqual(real *vector1, std::vector<uint> vectorExpected)
+{
+    for (uint i = 0; i < vectorExpected.size(); i++) {
+        if (vector1[i] != vectorExpected[i])
+            return false;
+    }
+    return true;
+}
+
+
+
+
+
+TEST(GridImpTest_IndicesCFBorderBulk, sizeIsConstant)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+    EXPECT_TRUE(para->getParH(cf.level)->intCFBorder.kCF + para->getParH(cf.level)->intCFBulk.kCF == cf.sizeOfICellCf);
+}
+
+TEST(GridImpTest_IndicesCFBorderBulk, borderSizeCFC)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+    EXPECT_EQ(para->getParH(cf.level)->intCFBorder.kCF, (uint)cf.iCellCfcBorder_expected.size());
+}
+
+TEST(GridImpTest_IndicesCFBorderBulk, borderVectorCFC)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->intCFBorder.ICellCFC, cf.iCellCfcBorder_expected));
+}
+
+TEST(GridImpTest_IndicesCFBorderBulk, bulkSizeCFC)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+    EXPECT_EQ(para->getParH(cf.level)->intCFBulk.kCF, (uint)cf.iCellCfcBulk_expected.size());
+}
+
+TEST(GridImpTest_IndicesCFBorderBulk, bulkVectorCFC)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->intCFBulk.ICellCFC, cf.iCellCfcBulk_expected));
+}
+
+TEST(GridImpTest_IndicesCFBorderBulk, borderSizeCFF)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+    EXPECT_EQ(para->getParH(cf.level)->intCFBorder.kCF, (uint)cf.iCellCffBorder_expected.size());
+}
+
+TEST(GridImpTest_IndicesCFBorderBulk, borderVectorCFF)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->intCFBorder.ICellCFF, cf.iCellCffBorder_expected));
+}
+
+TEST(GridImpTest_IndicesCFBorderBulk, bulkSizeCFF)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+    EXPECT_EQ(para->getParH(cf.level)->intCFBulk.kCF, (uint)cf.iCellCffBulk_expected.size());
+}
+
+TEST(GridImpTest_IndicesCFBorderBulk, bulkVectorCFF)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->intCFBulk.ICellCFF, cf.iCellCffBulk_expected));
+}
+
+TEST(GridImpTest_IndicesCFBorderBulk, offsetsVectorsCFC)
+{
+    CFBorderBulk cf;
+    SPtr<Parameter> para;
+    initParameterClass(para);
+    IndexRearrangementForStreamsTest::setUpAndRun_getGridInterfaceIndicesBorderBulkCF(cf, para);
+
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->offCF.xOffCF, cf.offsetCFx_Border_expected));
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->offCFBulk.xOffCF, cf.offsetCFx_Bulk_expected));
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->offCF.yOffCF, cf.offsetCFy_Border_expected));
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->offCFBulk.yOffCF, cf.offsetCFy_Bulk_expected));
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->offCF.zOffCF, cf.offsetCFz_Border_expected));
+    EXPECT_TRUE(vectorsAreEqual(para->getParH(cf.level)->offCFBulk.zOffCF, cf.offsetCFz_Bulk_expected));
+}
\ No newline at end of file
-- 
GitLab