// Copyright (c) 2010-2025, 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 "catch.hpp" using namespace mfem; namespace doftrans { TEST_CASE("DoF Transformation Classes", "[DofTransformation]" "[ND_TetDofTransformation]") { int p = 4; int vdim = 3; int seed = 123; double tol = 1e-13; SECTION("Nedelec Tetrahedral Transformations") { ND_TetDofTransformation Tnd(p); Array ori(4); ori[0] = 1; ori[1] = 3; ori[2] = 5; ori[3] = 1; SECTION("VDim == 1") { DofTransformation T(Tnd); T.SetFaceOrientations(ori); Vector u(T.Width()); Vector v(T.Width()); Vector f(T.Width()); Vector ut; Vector vt; Vector ft; u.Randomize(seed); v.Randomize(seed+1); f.Randomize(seed+2); SECTION("Inverse DoF transformation") { Vector w; ut = u; T.TransformPrimal(ut); w = ut; T.InvTransformPrimal(w); w -= u; REQUIRE(w.Norml2() < tol * u.Norml2()); } SECTION("Inverse Dual DoF transformation") { Vector w; ut = u; T.TransformDual(ut); w = ut; T.InvTransformDual(w); w -= u; REQUIRE(w.Norml2() < tol * u.Norml2()); } SECTION("Inner product with linear form f(v)") { vt = v; T.TransformPrimal(vt); ft = f; T.TransformDual(ft); double fv = f * v; REQUIRE(fabs(fv - ft * vt) < tol * fabs(fv)); } DenseMatrix A(T.Width()); { Vector Ac; for (int i=0; i 1") { Vector v(vdim * Tnd.Width()); Vector f(vdim * Tnd.Width()); Vector vt; Vector ft; v.Randomize(seed); f.Randomize(seed+1); SECTION("Ordering == byNODES") { DofTransformation T(Tnd, vdim, Ordering::byNODES); T.SetFaceOrientations(ori); SECTION("Inverse DoF transformation") { Vector w; vt = v; T.TransformPrimal(vt); w = vt; T.InvTransformPrimal(w); w -= v; REQUIRE(w.Norml2() < tol * v.Norml2()); } SECTION("Inverse Dual DoF transformation") { Vector w; vt = v; T.TransformDual(vt); w = vt; T.InvTransformDual(w); w -= v; REQUIRE(w.Norml2() < tol * v.Norml2()); } SECTION("Inner product with linear form f(v)") { vt = v; T.TransformPrimal(vt); ft = f; T.TransformDual(ft); double fv = f * v; REQUIRE(fabs(fv - ft * vt) < tol * fabs(fv)); } } SECTION("Ordering == byVDIM") { DofTransformation T(Tnd, vdim, Ordering::byVDIM); T.SetFaceOrientations(ori); SECTION("Inverse DoF transformation") { Vector w; vt = v; T.TransformPrimal(vt); w = vt; T.InvTransformPrimal(w); w -= v; REQUIRE(w.Norml2() < tol * v.Norml2()); } SECTION("Inverse Dual DoF transformation") { Vector w; vt = v; T.TransformDual(vt); w = vt; T.InvTransformDual(w); w -= v; REQUIRE(w.Norml2() < tol * v.Norml2()); } SECTION("Inner product with linear form f(v)") { vt = v; T.TransformPrimal(vt); ft = f; T.TransformDual(ft); double fv = f * v; REQUIRE(fabs(fv - ft * vt) < tol * fabs(fv)); } } } } } TEST_CASE("DoF Transformation Functions", "[DofTransformation]" "[TransformPrimal]" "[TransformDual]") { int p = 3, q = 4; int seed = 123; double tol = 1e-13; ND_TetDofTransformation Tndp(p); ND_TetDofTransformation Tndq(q); Array ori(4); ori[0] = 1; ori[1] = 3; ori[2] = 5; ori[3] = 1; DofTransformation Tp(Tndp), Tq(Tndq); Tp.SetFaceOrientations(ori); Tq.SetFaceOrientations(ori); DenseMatrix A(Tp.Width(), Tq.Width()); { Vector Ac; for (int i=0; i