// Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced // at the Lawrence Livermore National Laboratory. All Rights reserved. See files // LICENSE and NOTICE for details. LLNL-CODE-806117. // // This file is part of the MFEM library. For more information and source code // availability visit https://mfem.org. // // MFEM is free software; you can redistribute it and/or modify it under the // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. #include "mfem.hpp" #include "unit_tests.hpp" #include using namespace mfem; template bool InArray(const T* begin, size_t sz, T i) { const T *end = begin + sz; return std::find(begin, end, i) != end; } bool IndicesAreConnected(const Table &t, int i, int j) { return InArray(t.GetRow(i), t.RowSize(i), j) && InArray(t.GetRow(j), t.RowSize(j), i); } TEST_CASE("Periodic mesh", "[Mesh]") { int n = 3; SECTION("1D periodic mesh") { Mesh orig_mesh = Mesh::MakeCartesian1D(n); std::vector translations = {Vector({1.0})}; Mesh mesh = Mesh::MakePeriodic( orig_mesh, orig_mesh.CreatePeriodicVertexMapping(translations)); REQUIRE(mesh.GetNV() == n); const Table &e2e = mesh.ElementToElementTable(); REQUIRE(IndicesAreConnected(e2e, 0, 2)); REQUIRE(IndicesAreConnected(e2e, 0, 1)); REQUIRE(IndicesAreConnected(e2e, 1, 2)); } SECTION("2D periodic mesh") { auto el = GENERATE(Element::TRIANGLE, Element::QUADRILATERAL); bool sfc = false; // <-- Lexicographic instead of SFC ordering Mesh orig_mesh = Mesh::MakeCartesian2D(n, n, el, false, 1.0, 1.0, sfc); std::vector translations = {Vector({1.0,0.0}), Vector({0.0,1.0})}; Mesh mesh = Mesh::MakePeriodic( orig_mesh, orig_mesh.CreatePeriodicVertexMapping(translations)); REQUIRE(mesh.GetNV() == pow(n-1,2) + 2*(n-1) + 1); if (el == Element::QUADRILATERAL) { const Table &e2e = mesh.ElementToElementTable(); for (int i=0; i translations = { Vector({1.0, 0.0, 0.0}), Vector({0.0, 1.0, 0.0}), Vector({0.0, 0.0, 1.0}) }; Mesh mesh = Mesh::MakePeriodic( orig_mesh, orig_mesh.CreatePeriodicVertexMapping(translations)); REQUIRE(mesh.GetNV() == pow(n-1,3) + 3*pow(n-1,2) + 3*(n-1) + 1); if (el == Element::HEXAHEDRON) { const Table &e2e = mesh.ElementToElementTable(); int n2 = n*n; for (int j=0; j