diff --git a/Tests/MeshLib/TestAddLayerToMesh.cpp b/Tests/MeshLib/TestAddLayerToMesh.cpp new file mode 100644 index 0000000000000000000000000000000000000000..00012d80cd4d0e0f1f831746cece8570df8d5012 --- /dev/null +++ b/Tests/MeshLib/TestAddLayerToMesh.cpp @@ -0,0 +1,246 @@ +/** + * @copyright + * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/LICENSE.txt + */ + +#include <memory> + +#include "gtest/gtest.h" + +#include "MeshLib/Mesh.h" +#include "MeshLib/Node.h" +#include "MeshLib/Elements/Element.h" +#include "MeshLib/MeshInformation.h" +#include "MeshLib/MeshSurfaceExtraction.h" +#include "MeshLib/MeshGenerators/MeshGenerator.h" +#include "MeshLib/MeshEditing/AddLayerToMesh.h" +#include "MeshLib/MeshQuality/MeshValidation.h" + +namespace AddLayerValidation +{ + // validates mesh. for line meshes, node order tests will fail because vertical elements are + // created during the extrusion. Therefore node order tests are switched off for line meshes. + void validate(MeshLib::Mesh const& mesh, bool testNodeOrder) + { + int const reduce_tests = (testNodeOrder) ? 0 : 1; + + std::size_t const nErrorFlags (static_cast<std::size_t>(ElementErrorFlag::MaxValue)); + ElementErrorFlag const flags[nErrorFlags] = {ElementErrorFlag::ZeroVolume, + ElementErrorFlag::NonCoplanar, ElementErrorFlag::NonConvex, ElementErrorFlag::NodeOrder}; + std::vector<ElementErrorCode> const codes (MeshLib::MeshValidation::testElementGeometry(mesh)); + for (std::size_t i=0; i<codes.size(); ++i) + for (std::size_t j=0; j<nErrorFlags-reduce_tests; ++j) + ASSERT_EQ(false, codes[i][flags[j]]); + } + + void testZCoords2D(MeshLib::Mesh const& input, MeshLib::Mesh const& output, double height) + { + std::size_t const nNodes (input.getNNodes()); + for (std::size_t i=0; i<nNodes; ++i) + { + ASSERT_EQ((*input.getNode(i))[2], (*output.getNode(i))[2]); + ASSERT_EQ((*input.getNode(i))[2] + height, (*output.getNode(nNodes+i))[2]); + } + } + + void testZCoords3D(MeshLib::Mesh const& input, MeshLib::Mesh const& output, double height) + { + std::size_t const nNodes (input.getNNodes()); + for (std::size_t i=0; i<nNodes; ++i) + ASSERT_EQ((*input.getNode(i))[2] + height, (*output.getNode(i))[2]); + } +}; + +TEST(MeshLib, AddTopLayerToLineMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateLineMesh(1.0, 5)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh, height, "mesh", true)); + + ASSERT_EQ(2*mesh->getNNodes(), result->getNNodes()); + ASSERT_EQ(2*mesh->getNElements(), result->getNElements()); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(5, n_elems[0]); // tests if 5 lines are present + ASSERT_EQ(5, n_elems[2]); // tests if 5 quads are present + + AddLayerValidation::testZCoords2D(*mesh, *result, height); + AddLayerValidation::validate(*result, false); +} + +TEST(MeshLib, AddBottomLayerToLineMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateLineMesh(1.0, 5)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh, height, "mesh", false)); + + ASSERT_EQ(2*mesh->getNNodes(), result->getNNodes()); + ASSERT_EQ(2*mesh->getNElements(), result->getNElements()); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(5, n_elems[0]); // tests if 5 lines are present + ASSERT_EQ(5, n_elems[2]); // tests if 5 quads are present + + AddLayerValidation::testZCoords2D(*mesh, *result, -1 * height); + AddLayerValidation::validate(*result, false); +} + +TEST(MeshLib, AddTopLayerToTriMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateRegularTriMesh(5, 5)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh, height, "mesh", true)); + + ASSERT_EQ(2*mesh->getNNodes(), result->getNNodes()); + ASSERT_EQ(2*mesh->getNElements(), result->getNElements()); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(50, n_elems[1]); // tests if 50 tris are present + ASSERT_EQ(50, n_elems[6]); // tests if 50 prisms are present + + AddLayerValidation::testZCoords2D(*mesh, *result, height); + AddLayerValidation::validate(*result, true); +} + +TEST(MeshLib, AddBottomLayerToTriMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateRegularTriMesh(5, 5)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh, height, "mesh", false)); + + ASSERT_EQ(2*mesh->getNNodes(), result->getNNodes()); + ASSERT_EQ(2*mesh->getNElements(), result->getNElements()); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(50, n_elems[1]); // tests if 50 tris are present + ASSERT_EQ(50, n_elems[6]); // tests if 50 prisms are present + + AddLayerValidation::testZCoords2D(*mesh, *result, -1 * height); + AddLayerValidation::validate(*result, true); +} + +TEST(MeshLib, AddTopLayerToQuadMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateRegularQuadMesh(5, 5)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh, height, "mesh", true)); + + ASSERT_EQ(2*mesh->getNNodes(), result->getNNodes()); + ASSERT_EQ(2*mesh->getNElements(), result->getNElements()); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(25, n_elems[2]); // tests if 25 quads are present + ASSERT_EQ(25, n_elems[4]); // tests if 25 hexes are present + + AddLayerValidation::testZCoords2D(*mesh, *result, height); + AddLayerValidation::validate(*result, true); +} + +TEST(MeshLib, AddBottomLayerToQuadMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateRegularQuadMesh(5, 5)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh, height, "mesh", false)); + + ASSERT_EQ(2*mesh->getNNodes(), result->getNNodes()); + ASSERT_EQ(2*mesh->getNElements(), result->getNElements()); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(25, n_elems[2]); // tests if 25 quads are present + ASSERT_EQ(25, n_elems[4]); // tests if 25 hexes are present + + AddLayerValidation::testZCoords2D(*mesh, *result, -1 * height); + AddLayerValidation::validate(*result, true); +} + +TEST(MeshLib, AddTopLayerToHexMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateRegularHexMesh(5, 5)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh, height, "mesh", true)); + + ASSERT_EQ(mesh->getNNodes(), result->getNNodes()-36); + ASSERT_EQ(mesh->getNElements(), result->getNElements()-25); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(150, n_elems[4]); // tests if 150 hexes are present + + MathLib::Vector3 const dir(0, 0, -1); + std::unique_ptr<MeshLib::Mesh> const test_input ( + MeshLib::MeshSurfaceExtraction::getMeshSurface(*mesh, dir, 90)); + std::unique_ptr<MeshLib::Mesh> const test_output ( + MeshLib::MeshSurfaceExtraction::getMeshSurface(*result, dir, 90)); + AddLayerValidation::testZCoords3D(*test_input, *test_output, height); + AddLayerValidation::validate(*result, true); + +} + +TEST(MeshLib, AddBottomLayerToHexMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateRegularHexMesh(5, 5)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh, height, "mesh", false)); + + ASSERT_EQ(mesh->getNNodes(), result->getNNodes()-36); + ASSERT_EQ(mesh->getNElements(), result->getNElements()-25); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(150, n_elems[4]); // tests if 150 hexes are present + + MathLib::Vector3 const dir(0, 0, 1); + std::unique_ptr<MeshLib::Mesh> const test_input ( + MeshLib::MeshSurfaceExtraction::getMeshSurface(*mesh, dir, 90)); + std::unique_ptr<MeshLib::Mesh> const test_output ( + MeshLib::MeshSurfaceExtraction::getMeshSurface(*result, dir, 90)); + AddLayerValidation::testZCoords3D(*test_input, *test_output, -1 * height); + AddLayerValidation::validate(*result, true); +} + +TEST(MeshLib, AddTopLayerToPrismMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateRegularTriMesh(5, 5)); + std::unique_ptr<MeshLib::Mesh> const mesh2 (MeshLib::addLayerToMesh(*mesh, 5, "mesh", true)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh2, height, "mesh", true)); + + ASSERT_EQ(mesh2->getNNodes()/2.0 * 3, result->getNNodes()); + ASSERT_EQ(mesh2->getNElements()/2.0 * 3, result->getNElements()); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(50, n_elems[1]); // tests if 50 tris are present + ASSERT_EQ(100, n_elems[6]); // tests if 50 prisms are present + + MathLib::Vector3 const dir(0, 0, -1); + std::unique_ptr<MeshLib::Mesh> test_input ( + MeshLib::MeshSurfaceExtraction::getMeshSurface(*mesh2, dir, 90)); + std::unique_ptr<MeshLib::Mesh> test_output ( + MeshLib::MeshSurfaceExtraction::getMeshSurface(*result, dir, 90)); + AddLayerValidation::testZCoords3D(*test_input, *test_output, height); + AddLayerValidation::validate(*result, true); +} + +TEST(MeshLib, AddBottomLayerToPrismMesh) +{ + std::unique_ptr<MeshLib::Mesh> const mesh (MeshLib::MeshGenerator::generateRegularTriMesh(5, 5)); + std::unique_ptr<MeshLib::Mesh> const mesh2 (MeshLib::addLayerToMesh(*mesh, 5, "mesh", true)); + double const height (1); + std::unique_ptr<MeshLib::Mesh> const result (MeshLib::addLayerToMesh(*mesh2, height, "mesh", false)); + + ASSERT_EQ(mesh2->getNNodes()/2.0 * 3, result->getNNodes()); + ASSERT_EQ(mesh2->getNElements()/2.0 * 3, result->getNElements()); + + std::array<unsigned, 7> const n_elems (MeshLib::MeshInformation::getNumberOfElementTypes(*result)); + ASSERT_EQ(50, n_elems[1]); // tests if 50 tris are present + ASSERT_EQ(100, n_elems[6]); // tests if 50 prisms are present + + MathLib::Vector3 const dir(0, 0, 1); + std::unique_ptr<MeshLib::Mesh> test_input ( + MeshLib::MeshSurfaceExtraction::getMeshSurface(*mesh2, dir, 90)); + std::unique_ptr<MeshLib::Mesh> test_output ( + MeshLib::MeshSurfaceExtraction::getMeshSurface(*result, dir, 90)); + AddLayerValidation::testZCoords3D(*test_input, *test_output, -1 * height); + AddLayerValidation::validate(*result, true); +}