// Copyright (c) 2010-2020, 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 get_value { double func_1D_lin(const Vector &x) { return x[0]; } double func_2D_lin(const Vector &x) { return x[0] + 2.0 * x[1]; } double func_3D_lin(const Vector &x) { return x[0] + 2.0 * x[1] + 3.0 * x[2]; } void Func_2D_lin(const Vector &x, Vector &v) { v.SetSize(2); v[0] = 1.234 * x[0] - 2.357 * x[1]; v[1] = 2.537 * x[0] + 4.321 * x[1]; } void Func_3D_lin(const Vector &x, Vector &v) { v.SetSize(3); v[0] = 1.234 * x[0] - 2.357 * x[1] + 3.572 * x[2]; v[1] = 2.537 * x[0] + 4.321 * x[1] - 1.234 * x[2]; v[2] = -2.572 * x[0] + 1.321 * x[1] + 3.234 * x[2]; } TEST_CASE("1D GetValue", "[GridFunction]" "[GridFunctionCoefficient]") { int log = 1; int n = 1; int dim = 1; int order = 1; int npts = 0; double tol = 1e-6; for (int type = (int)Element::SEGMENT; type <= (int)Element::SEGMENT; type++) { Mesh mesh(n, 2.0); FunctionCoefficient linCoef(func_1D_lin); SECTION("1D GetValue tests for element type " + std::to_string(type)) { H1_FECollection h1_fec(order, dim); DG_FECollection dgv_fec(order, dim, BasisType::GaussLegendre, FiniteElement::VALUE); DG_FECollection dgi_fec(order, dim, BasisType::GaussLegendre, FiniteElement::INTEGRAL); FiniteElementSpace h1_fespace(&mesh, &h1_fec); FiniteElementSpace dgv_fespace(&mesh, &dgv_fec); FiniteElementSpace dgi_fespace(&mesh, &dgi_fec); GridFunction h1_x(&h1_fespace); GridFunction dgv_x(&dgv_fespace); GridFunction dgi_x(&dgi_fespace); GridFunctionCoefficient h1_xCoef(&h1_x); GridFunctionCoefficient dgv_xCoef(&dgv_x); GridFunctionCoefficient dgi_xCoef(&dgi_x); h1_x.ProjectCoefficient(linCoef); dgv_x.ProjectCoefficient(linCoef); dgi_x.ProjectCoefficient(linCoef); SECTION("Domain Evaluation 1D") { std::cout << "Domain Evaluation 1D" << std::endl; for (int e = 0; e < mesh.GetNE(); e++) { ElementTransformation *T = mesh.GetElementTransformation(e); const FiniteElement *fe = h1_fespace.GetFE(e); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[1]; Vector tip(tip_data, 1); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_1D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); double dgv_gf_val = dgv_xCoef.Eval(*T, ip); double dgi_gf_val = dgi_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); dgv_err += fabs(f_val - dgv_gf_val); dgi_err += fabs(f_val - dgi_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << e << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgv_gf_val) > tol) { std::cout << e << ":" << j << " dgv " << f_val << " " << dgv_gf_val << " " << fabs(f_val - dgv_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgi_gf_val) > tol) { std::cout << e << ":" << j << " dgi " << f_val << " " << dgi_gf_val << " " << fabs(f_val - dgi_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 1D (H1 Context)") { std::cout << "Boundary Evaluation 1D (H1 Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { ElementTransformation *T = mesh.GetBdrElementTransformation(be); const FiniteElement *fe = h1_fespace.GetBE(be); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[1]; Vector tip(tip_data, 1); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_1D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); double dgv_gf_val = dgv_xCoef.Eval(*T, ip); double dgi_gf_val = dgi_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); dgv_err += fabs(f_val - dgv_gf_val); dgi_err += fabs(f_val - dgi_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << be << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgv_gf_val) > tol) { std::cout << be << ":" << j << " dgv " << f_val << " " << dgv_gf_val << " " << fabs(f_val - dgv_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgi_gf_val) > tol) { std::cout << be << ":" << j << " dgi " << f_val << " " << dgi_gf_val << " " << fabs(f_val - dgi_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 1D (DG Context)") { std::cout << "Boundary Evaluation 1D (DG Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { FaceElementTransformations *T = mesh.GetBdrFaceTransformations(be); const IntegrationRule &ir = IntRules.Get(T->GetGeometryType(), 2*order + 2); double h1_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[1]; Vector tip(tip_data, 1); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_1D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); double dgv_gf_val = dgv_xCoef.Eval(*T, ip); double dgi_gf_val = dgi_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); dgv_err += fabs(f_val - dgv_gf_val); dgi_err += fabs(f_val - dgi_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << be << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgv_gf_val) > tol) { std::cout << be << ":" << j << " dgv " << f_val << " " << dgv_gf_val << " " << fabs(f_val - dgv_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgi_gf_val) > tol) { std::cout << be << ":" << j << " dgi " << f_val << " " << dgi_gf_val << " " << fabs(f_val - dgi_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } } } std::cout << "Checked GridFunction::GetValue at " << npts << " 1D points" << std::endl; } TEST_CASE("2D GetValue", "[GridFunction]" "[GridFunctionCoefficient]") { int log = 1; int n = 1; int dim = 2; int order = 1; int npts = 0; double tol = 1e-6; for (int type = (int)Element::TRIANGLE; type <= (int)Element::QUADRILATERAL; type++) { Mesh mesh(n, n, (Element::Type)type, 1, 2.0, 3.0); FunctionCoefficient linCoef(func_2D_lin); SECTION("2D GetValue tests for element type " + std::to_string(type)) { H1_FECollection h1_fec(order, dim); DG_FECollection dgv_fec(order, dim, BasisType::GaussLegendre, FiniteElement::VALUE); DG_FECollection dgi_fec(order, dim, BasisType::GaussLegendre, FiniteElement::INTEGRAL); FiniteElementSpace h1_fespace(&mesh, &h1_fec); FiniteElementSpace dgv_fespace(&mesh, &dgv_fec); FiniteElementSpace dgi_fespace(&mesh, &dgi_fec); GridFunction h1_x(&h1_fespace); GridFunction dgv_x(&dgv_fespace); GridFunction dgi_x(&dgi_fespace); GridFunctionCoefficient h1_xCoef(&h1_x); GridFunctionCoefficient dgv_xCoef(&dgv_x); GridFunctionCoefficient dgi_xCoef(&dgi_x); h1_x.ProjectCoefficient(linCoef); dgv_x.ProjectCoefficient(linCoef); dgi_x.ProjectCoefficient(linCoef); SECTION("Domain Evaluation 2D") { std::cout << "Domain Evaluation 2D" << std::endl; for (int e = 0; e < mesh.GetNE(); e++) { ElementTransformation *T = mesh.GetElementTransformation(e); const FiniteElement *fe = h1_fespace.GetFE(e); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_2D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); double dgv_gf_val = dgv_xCoef.Eval(*T, ip); double dgi_gf_val = dgi_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); dgv_err += fabs(f_val - dgv_gf_val); dgi_err += fabs(f_val - dgi_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << e << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgv_gf_val) > tol) { std::cout << e << ":" << j << " dgv " << f_val << " " << dgv_gf_val << " " << fabs(f_val - dgv_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgi_gf_val) > tol) { std::cout << e << ":" << j << " dgi " << f_val << " " << dgi_gf_val << " " << fabs(f_val - dgi_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 2D (H1 Context)") { std::cout << "Boundary Evaluation 2D (H1 Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { ElementTransformation *T = mesh.GetBdrElementTransformation(be); const FiniteElement *fe = h1_fespace.GetBE(be); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_2D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); double dgv_gf_val = dgv_xCoef.Eval(*T, ip); double dgi_gf_val = dgi_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); dgv_err += fabs(f_val - dgv_gf_val); dgi_err += fabs(f_val - dgi_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << be << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgv_gf_val) > tol) { std::cout << be << ":" << j << " dgv " << f_val << " " << dgv_gf_val << " " << fabs(f_val - dgv_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgi_gf_val) > tol) { std::cout << be << ":" << j << " dgi " << f_val << " " << dgi_gf_val << " " << fabs(f_val - dgi_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 2D (DG Context)") { std::cout << "Boundary Evaluation 2D (DG Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { FaceElementTransformations *T = mesh.GetBdrFaceTransformations(be); const IntegrationRule &ir = IntRules.Get(T->GetGeometryType(), 2*order + 2); double h1_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_2D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); double dgv_gf_val = dgv_xCoef.Eval(*T, ip); double dgi_gf_val = dgi_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); dgv_err += fabs(f_val - dgv_gf_val); dgi_err += fabs(f_val - dgi_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << be << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgv_gf_val) > tol) { std::cout << be << ":" << j << " dgv " << f_val << " " << dgv_gf_val << " " << fabs(f_val - dgv_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgi_gf_val) > tol) { std::cout << be << ":" << j << " dgi " << f_val << " " << dgi_gf_val << " " << fabs(f_val - dgi_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Edge Evaluation 2D (H1 Context)") { std::cout << "Edge Evaluation 2D (H1 Context)" << std::endl; for (int e = 0; e < mesh.GetNEdges(); e++) { ElementTransformation *T = mesh.GetEdgeTransformation(e); const FiniteElement *fe = h1_fespace.GetEdgeElement(e); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_3D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << e << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); } } } } std::cout << "Checked GridFunction::GetValue at " << npts << " 2D points" << std::endl; } TEST_CASE("3D GetValue", "[GridFunction]" "[GridFunctionCoefficient]") { int log = 1; int n = 1; int dim = 3; int order = 1; int npts = 0; double tol = 1e-6; for (int type = (int)Element::TETRAHEDRON; type <= (int)Element::WEDGE; type++) { Mesh mesh(n, n, n, (Element::Type)type, 1, 2.0, 3.0, 5.0); FunctionCoefficient linCoef(func_3D_lin); SECTION("3D GetValue tests for element type " + std::to_string(type)) { H1_FECollection h1_fec(order, dim); DG_FECollection dgv_fec(order, dim, BasisType::GaussLegendre, FiniteElement::VALUE); DG_FECollection dgi_fec(order, dim, BasisType::GaussLegendre, FiniteElement::INTEGRAL); FiniteElementSpace h1_fespace(&mesh, &h1_fec); FiniteElementSpace dgv_fespace(&mesh, &dgv_fec); FiniteElementSpace dgi_fespace(&mesh, &dgi_fec); GridFunction h1_x(&h1_fespace); GridFunction dgv_x(&dgv_fespace); GridFunction dgi_x(&dgi_fespace); GridFunctionCoefficient h1_xCoef(&h1_x); GridFunctionCoefficient dgv_xCoef(&dgv_x); GridFunctionCoefficient dgi_xCoef(&dgi_x); h1_x.ProjectCoefficient(linCoef); dgv_x.ProjectCoefficient(linCoef); dgi_x.ProjectCoefficient(linCoef); SECTION("Domain Evaluation 3D") { std::cout << "Domain Evaluation 3D" << std::endl; for (int e = 0; e < mesh.GetNE(); e++) { ElementTransformation *T = mesh.GetElementTransformation(e); const FiniteElement *fe = h1_fespace.GetFE(e); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_3D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); double dgv_gf_val = dgv_xCoef.Eval(*T, ip); double dgi_gf_val = dgi_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); dgv_err += fabs(f_val - dgv_gf_val); dgi_err += fabs(f_val - dgi_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << e << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgv_gf_val) > tol) { std::cout << e << ":" << j << " dgv " << f_val << " " << dgv_gf_val << " " << fabs(f_val - dgv_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgi_gf_val) > tol) { std::cout << e << ":" << j << " dgi " << f_val << " " << dgi_gf_val << " " << fabs(f_val - dgi_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 3D (H1 Context)") { std::cout << "Boundary Evaluation 3D (H1 Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { ElementTransformation *T = mesh.GetBdrElementTransformation(be); const FiniteElement *fe = h1_fespace.GetBE(be); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_3D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); double dgv_gf_val = dgv_xCoef.Eval(*T, ip); double dgi_gf_val = dgi_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); dgv_err += fabs(f_val - dgv_gf_val); dgi_err += fabs(f_val - dgi_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << be << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgv_gf_val) > tol) { std::cout << be << ":" << j << " dgv " << f_val << " " << dgv_gf_val << " " << fabs(f_val - dgv_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgi_gf_val) > tol) { std::cout << be << ":" << j << " dgi " << f_val << " " << dgi_gf_val << " " << fabs(f_val - dgi_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 3D (DG Context)") { std::cout << "Boundary Evaluation 3D (DG Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { FaceElementTransformations *T = mesh.GetBdrFaceTransformations(be); const IntegrationRule &ir = IntRules.Get(T->GetGeometryType(), 2*order + 2); double h1_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_3D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); double dgv_gf_val = dgv_xCoef.Eval(*T, ip); double dgi_gf_val = dgi_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); dgv_err += fabs(f_val - dgv_gf_val); dgi_err += fabs(f_val - dgi_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << be << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgv_gf_val) > tol) { std::cout << be << ":" << j << " dgv " << f_val << " " << dgv_gf_val << " " << fabs(f_val - dgv_gf_val) << std::endl; } if (log > 0 && fabs(f_val - dgi_gf_val) > tol) { std::cout << be << ":" << j << " dgi " << f_val << " " << dgi_gf_val << " " << fabs(f_val - dgi_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Edge Evaluation 3D (H1 Context)") { std::cout << "Edge Evaluation 3D (H1 Context)" << std::endl; for (int e = 0; e < mesh.GetNEdges(); e++) { ElementTransformation *T = mesh.GetEdgeTransformation(e); const FiniteElement *fe = h1_fespace.GetEdgeElement(e); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_3D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << e << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); } } SECTION("Face Evaluation 3D (H1 Context)") { std::cout << "Face Evaluation 3D (H1 Context)" << std::endl; for (int f = 0; f < mesh.GetNFaces(); f++) { ElementTransformation *T = mesh.GetFaceTransformation(f); const FiniteElement *fe = h1_fespace.GetFaceElement(f); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); double f_val = func_3D_lin(tip); double h1_gf_val = h1_xCoef.Eval(*T, ip); h1_err += fabs(f_val - h1_gf_val); if (log > 0 && fabs(f_val - h1_gf_val) > tol) { std::cout << f << ":" << j << " h1 " << f_val << " " << h1_gf_val << " " << fabs(f_val - h1_gf_val) << std::endl; } } h1_err /= ir.GetNPoints(); REQUIRE(h1_err == Approx(0.0)); } } } } std::cout << "Checked GridFunction::GetValue at " << npts << " 3D points" << std::endl; } TEST_CASE("2D GetVectorValue", "[GridFunction]" "[VectorGridFunctionCoefficient]") { int log = 1; int n = 1; int dim = 2; int order = 1; int npts = 0; double tol = 1e-6; for (int type = (int)Element::TRIANGLE; type <= (int)Element::QUADRILATERAL; type++) { Mesh mesh(n, n, (Element::Type)type, 1, 2.0, 3.0); VectorFunctionCoefficient linCoef(dim, Func_2D_lin); SECTION("2D GetVectorValue tests for element type " + std::to_string(type)) { H1_FECollection h1_fec(order, dim); ND_FECollection nd_fec(order+1, dim); RT_FECollection rt_fec(order+1, dim); L2_FECollection l2_fec(order, dim); DG_FECollection dgv_fec(order, dim, BasisType::GaussLegendre, FiniteElement::VALUE); DG_FECollection dgi_fec(order, dim, BasisType::GaussLegendre, FiniteElement::INTEGRAL); FiniteElementSpace h1_fespace(&mesh, &h1_fec, dim); FiniteElementSpace nd_fespace(&mesh, &nd_fec); FiniteElementSpace rt_fespace(&mesh, &rt_fec); FiniteElementSpace l2_fespace(&mesh, &l2_fec, dim); FiniteElementSpace dgv_fespace(&mesh, &dgv_fec, dim); FiniteElementSpace dgi_fespace(&mesh, &dgi_fec, dim); GridFunction h1_x( &h1_fespace); GridFunction nd_x( &nd_fespace); GridFunction rt_x( &rt_fespace); GridFunction l2_x( &l2_fespace); GridFunction dgv_x(&dgv_fespace); GridFunction dgi_x(&dgi_fespace); VectorGridFunctionCoefficient h1_xCoef( &h1_x); VectorGridFunctionCoefficient nd_xCoef( &nd_x); VectorGridFunctionCoefficient rt_xCoef( &rt_x); VectorGridFunctionCoefficient l2_xCoef( &l2_x); VectorGridFunctionCoefficient dgv_xCoef(&dgv_x); VectorGridFunctionCoefficient dgi_xCoef(&dgi_x); h1_x.ProjectCoefficient(linCoef); nd_x.ProjectCoefficient(linCoef); rt_x.ProjectCoefficient(linCoef); l2_x.ProjectCoefficient(linCoef); dgv_x.ProjectCoefficient(linCoef); dgi_x.ProjectCoefficient(linCoef); Vector f_val(dim); f_val = 0.0; Vector h1_gf_val(dim); h1_gf_val = 0.0; Vector nd_gf_val(dim); nd_gf_val = 0.0; Vector rt_gf_val(dim); rt_gf_val = 0.0; Vector l2_gf_val(dim); l2_gf_val = 0.0; Vector dgv_gf_val(dim); dgv_gf_val = 0.0; Vector dgi_gf_val(dim); dgi_gf_val = 0.0; SECTION("Domain Evaluation 2D") { std::cout << "Domain Evaluation 2D" << std::endl; for (int e = 0; e < mesh.GetNE(); e++) { ElementTransformation *T = mesh.GetElementTransformation(e); const FiniteElement *fe = h1_fespace.GetFE(e); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double nd_err = 0.0; double rt_err = 0.0; double l2_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); Func_2D_lin(tip, f_val); h1_xCoef.Eval(h1_gf_val, *T, ip); nd_xCoef.Eval(nd_gf_val, *T, ip); rt_xCoef.Eval(rt_gf_val, *T, ip); l2_xCoef.Eval(l2_gf_val, *T, ip); dgv_xCoef.Eval(dgv_gf_val, *T, ip); dgi_xCoef.Eval(dgi_gf_val, *T, ip); double h1_dist = Distance(f_val, h1_gf_val, 2); double nd_dist = Distance(f_val, nd_gf_val, 2); double rt_dist = Distance(f_val, rt_gf_val, 2); double l2_dist = Distance(f_val, l2_gf_val, 2); double dgv_dist = Distance(f_val, dgv_gf_val, 2); double dgi_dist = Distance(f_val, dgi_gf_val, 2); h1_err += h1_dist; nd_err += nd_dist; rt_err += rt_dist; l2_err += l2_dist; dgv_err += dgv_dist; dgi_err += dgi_dist; if (log > 0 && h1_dist > tol) { std::cout << e << ":" << j << " h1 (" << f_val[0] << "," << f_val[1] << ") vs. (" << h1_gf_val[0] << "," << h1_gf_val[1] << ") " << h1_dist << std::endl; } if (log > 0 && nd_dist > tol) { std::cout << e << ":" << j << " nd (" << f_val[0] << "," << f_val[1] << ") vs. (" << nd_gf_val[0] << "," << nd_gf_val[1] << ") " << nd_dist << std::endl; } if (log > 0 && rt_dist > tol) { std::cout << e << ":" << j << " rt (" << f_val[0] << "," << f_val[1] << ") vs. (" << rt_gf_val[0] << "," << rt_gf_val[1] << ") " << rt_dist << std::endl; } if (log > 0 && l2_dist > tol) { std::cout << e << ":" << j << " l2 (" << f_val[0] << "," << f_val[1] << ") vs. (" << l2_gf_val[0] << "," << l2_gf_val[1] << ") " << l2_dist << std::endl; } if (log > 0 && dgv_dist > tol) { std::cout << e << ":" << j << " dgv (" << f_val[0] << "," << f_val[1] << ") vs. (" << dgv_gf_val[0] << "," << dgv_gf_val[1] << ") " << dgv_dist << std::endl; } if (log > 0 && dgi_dist > tol) { std::cout << e << ":" << j << " dgi (" << f_val[0] << "," << f_val[1] << ") vs. (" << dgi_gf_val[0] << "," << dgi_gf_val[1] << ") " << dgi_dist << std::endl; } } h1_err /= ir.GetNPoints(); nd_err /= ir.GetNPoints(); rt_err /= ir.GetNPoints(); l2_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE( h1_err == Approx(0.0)); REQUIRE( nd_err == Approx(0.0)); REQUIRE( rt_err == Approx(0.0)); REQUIRE( l2_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 2D (H1 Context)") { std::cout << "Boundary Evaluation 2D (H1 Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { ElementTransformation *T = mesh.GetBdrElementTransformation(be); const FiniteElement *fe = h1_fespace.GetBE(be); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double nd_err = 0.0; double rt_err = 0.0; double l2_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); Func_2D_lin(tip, f_val); h1_xCoef.Eval(h1_gf_val, *T, ip); nd_xCoef.Eval(nd_gf_val, *T, ip); rt_xCoef.Eval(rt_gf_val, *T, ip); l2_xCoef.Eval(l2_gf_val, *T, ip); dgv_xCoef.Eval(dgv_gf_val, *T, ip); dgi_xCoef.Eval(dgi_gf_val, *T, ip); double h1_dist = Distance(f_val, h1_gf_val, 2); double nd_dist = Distance(f_val, nd_gf_val, 2); double rt_dist = Distance(f_val, rt_gf_val, 2); double l2_dist = Distance(f_val, l2_gf_val, 2); double dgv_dist = Distance(f_val, dgv_gf_val, 2); double dgi_dist = Distance(f_val, dgi_gf_val, 2); h1_err += h1_dist; nd_err += nd_dist; rt_err += rt_dist; l2_err += l2_dist; dgv_err += dgv_dist; dgi_err += dgi_dist; if (log > 0 && h1_dist > tol) { std::cout << be << ":" << j << " h1 (" << f_val[0] << "," << f_val[1] << ") vs. (" << h1_gf_val[0] << "," << h1_gf_val[1] << ") " << h1_dist << std::endl; } if (log > 0 && nd_dist > tol) { std::cout << be << ":" << j << " nd (" << f_val[0] << "," << f_val[1] << ") vs. (" << nd_gf_val[0] << "," << nd_gf_val[1] << ") " << nd_dist << std::endl; } if (log > 0 && rt_dist > tol) { std::cout << be << ":" << j << " rt (" << f_val[0] << "," << f_val[1] << ") vs. (" << rt_gf_val[0] << "," << rt_gf_val[1] << ") " << rt_dist << std::endl; } if (log > 0 && l2_dist > tol) { std::cout << be << ":" << j << " l2 (" << f_val[0] << "," << f_val[1] << ") vs. (" << l2_gf_val[0] << "," << l2_gf_val[1] << ") " << l2_dist << std::endl; } if (log > 0 && dgv_dist > tol) { std::cout << be << ":" << j << " dgv (" << f_val[0] << "," << f_val[1] << ") vs. (" << dgv_gf_val[0] << "," << dgv_gf_val[1] << ") " << dgv_dist << std::endl; } if (log > 0 && dgi_dist > tol) { std::cout << be << ":" << j << " dgi (" << f_val[0] << "," << f_val[1] << ") vs. (" << dgi_gf_val[0] << "," << dgi_gf_val[1] << ") " << dgi_dist << std::endl; } } h1_err /= ir.GetNPoints(); nd_err /= ir.GetNPoints(); rt_err /= ir.GetNPoints(); l2_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE( h1_err == Approx(0.0)); REQUIRE( nd_err == Approx(0.0)); REQUIRE( rt_err == Approx(0.0)); REQUIRE( l2_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 2D (DG Context)") { std::cout << "Boundary Evaluation 2D (DG Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { FaceElementTransformations *T = mesh.GetBdrFaceTransformations(be); const IntegrationRule &ir = IntRules.Get(T->GetGeometryType(), 2*order + 2); double h1_err = 0.0; double nd_err = 0.0; double rt_err = 0.0; double l2_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); Func_2D_lin(tip, f_val); h1_xCoef.Eval(h1_gf_val, *T, ip); nd_xCoef.Eval(nd_gf_val, *T, ip); rt_xCoef.Eval(rt_gf_val, *T, ip); l2_xCoef.Eval(l2_gf_val, *T, ip); dgv_xCoef.Eval(dgv_gf_val, *T, ip); dgi_xCoef.Eval(dgi_gf_val, *T, ip); double h1_dist = Distance(f_val, h1_gf_val, 2); double nd_dist = Distance(f_val, nd_gf_val, 2); double rt_dist = Distance(f_val, rt_gf_val, 2); double l2_dist = Distance(f_val, l2_gf_val, 2); double dgv_dist = Distance(f_val, dgv_gf_val, 2); double dgi_dist = Distance(f_val, dgi_gf_val, 2); h1_err += h1_dist; nd_err += nd_dist; rt_err += rt_dist; l2_err += l2_dist; dgv_err += dgv_dist; dgi_err += dgi_dist; if (log > 0 && h1_dist > tol) { std::cout << be << ":" << j << " h1 (" << f_val[0] << "," << f_val[1] << ") vs. (" << h1_gf_val[0] << "," << h1_gf_val[1] << ") " << h1_dist << std::endl; } if (log > 0 && nd_dist > tol) { std::cout << be << ":" << j << " nd (" << f_val[0] << "," << f_val[1] << ") vs. (" << nd_gf_val[0] << "," << nd_gf_val[1] << ") " << nd_dist << std::endl; } if (log > 0 && rt_dist > tol) { std::cout << be << ":" << j << " rt (" << f_val[0] << "," << f_val[1] << ") vs. (" << rt_gf_val[0] << "," << rt_gf_val[1] << ") " << rt_dist << std::endl; } if (log > 0 && l2_dist > tol) { std::cout << be << ":" << j << " l2 (" << f_val[0] << "," << f_val[1] << ") vs. (" << l2_gf_val[0] << "," << l2_gf_val[1] << ") " << l2_dist << std::endl; } if (log > 0 && dgv_dist > tol) { std::cout << be << ":" << j << " dgv (" << f_val[0] << "," << f_val[1] << ") vs. (" << dgv_gf_val[0] << "," << dgv_gf_val[1] << ") " << dgv_dist << std::endl; } if (log > 0 && dgi_dist > tol) { std::cout << be << ":" << j << " dgi (" << f_val[0] << "," << f_val[1] << ") vs. (" << dgi_gf_val[0] << "," << dgi_gf_val[1] << ") " << dgi_dist << std::endl; } } h1_err /= ir.GetNPoints(); nd_err /= ir.GetNPoints(); rt_err /= ir.GetNPoints(); l2_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE( h1_err == Approx(0.0)); REQUIRE( nd_err == Approx(0.0)); REQUIRE( rt_err == Approx(0.0)); REQUIRE( l2_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Edge Evaluation 2D") { std::cout << "Edge Evaluation 2D" << std::endl; for (int e = 0; e < mesh.GetNEdges(); e++) { ElementTransformation *T = mesh.GetEdgeTransformation(e); const FiniteElement *fe = h1_fespace.GetEdgeElement(e); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); Func_2D_lin(tip, f_val); h1_xCoef.Eval(h1_gf_val, *T, ip); double h1_dist = Distance(f_val, h1_gf_val, 2); h1_err += h1_dist; if (log > 0 && h1_dist > tol) { std::cout << e << ":" << j << " h1 (" << f_val[0] << "," << f_val[1] << ") vs. (" << h1_gf_val[0] << "," << h1_gf_val[1] << ") " << h1_dist << std::endl; } } h1_err /= ir.GetNPoints(); REQUIRE( h1_err == Approx(0.0)); } } } } std::cout << "Checked GridFunction::GetVectorValue at " << npts << " 2D points" << std::endl; } TEST_CASE("3D GetVectorValue", "[GridFunction]" "[VectorGridFunctionCoefficient]") { int log = 1; int n = 1; int dim = 3; int order = 1; int npts = 0; double tol = 1e-6; for (int type = (int)Element::TETRAHEDRON; type <= (int)Element::HEXAHEDRON; type++) { Mesh mesh(n, n, n, (Element::Type)type, 1, 2.0, 3.0, 5.0); VectorFunctionCoefficient linCoef(dim, Func_3D_lin); SECTION("3D GetVectorValue tests for element type " + std::to_string(type)) { H1_FECollection h1_fec(order, dim); ND_FECollection nd_fec(order+1, dim); RT_FECollection rt_fec(order+1, dim); L2_FECollection l2_fec(order, dim); DG_FECollection dgv_fec(order, dim, BasisType::GaussLegendre, FiniteElement::VALUE); DG_FECollection dgi_fec(order, dim, BasisType::GaussLegendre, FiniteElement::INTEGRAL); FiniteElementSpace h1_fespace(&mesh, &h1_fec, dim); FiniteElementSpace nd_fespace(&mesh, &nd_fec); FiniteElementSpace rt_fespace(&mesh, &rt_fec); FiniteElementSpace l2_fespace(&mesh, &l2_fec, dim); FiniteElementSpace dgv_fespace(&mesh, &dgv_fec, dim); FiniteElementSpace dgi_fespace(&mesh, &dgi_fec, dim); GridFunction h1_x( &h1_fespace); GridFunction nd_x( &nd_fespace); GridFunction rt_x( &rt_fespace); GridFunction l2_x( &l2_fespace); GridFunction dgv_x(&dgv_fespace); GridFunction dgi_x(&dgi_fespace); VectorGridFunctionCoefficient h1_xCoef( &h1_x); VectorGridFunctionCoefficient nd_xCoef( &nd_x); VectorGridFunctionCoefficient rt_xCoef( &rt_x); VectorGridFunctionCoefficient l2_xCoef( &l2_x); VectorGridFunctionCoefficient dgv_xCoef(&dgv_x); VectorGridFunctionCoefficient dgi_xCoef(&dgi_x); h1_x.ProjectCoefficient(linCoef); nd_x.ProjectCoefficient(linCoef); rt_x.ProjectCoefficient(linCoef); l2_x.ProjectCoefficient(linCoef); dgv_x.ProjectCoefficient(linCoef); dgi_x.ProjectCoefficient(linCoef); Vector f_val(dim); f_val = 0.0; Vector h1_gf_val(dim); h1_gf_val = 0.0; Vector nd_gf_val(dim); nd_gf_val = 0.0; Vector rt_gf_val(dim); rt_gf_val = 0.0; Vector l2_gf_val(dim); l2_gf_val = 0.0; Vector dgv_gf_val(dim); dgv_gf_val = 0.0; Vector dgi_gf_val(dim); dgi_gf_val = 0.0; SECTION("Domain Evaluation 3D") { std::cout << "Domain Evaluation 3D" << std::endl; for (int e = 0; e < mesh.GetNE(); e++) { ElementTransformation *T = mesh.GetElementTransformation(e); const FiniteElement *fe = h1_fespace.GetFE(e); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double nd_err = 0.0; double rt_err = 0.0; double l2_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); Func_3D_lin(tip, f_val); h1_xCoef.Eval(h1_gf_val, *T, ip); nd_xCoef.Eval(nd_gf_val, *T, ip); rt_xCoef.Eval(rt_gf_val, *T, ip); l2_xCoef.Eval(l2_gf_val, *T, ip); dgv_xCoef.Eval(dgv_gf_val, *T, ip); dgi_xCoef.Eval(dgi_gf_val, *T, ip); double h1_dist = Distance(f_val, h1_gf_val, dim); double nd_dist = Distance(f_val, nd_gf_val, dim); double rt_dist = Distance(f_val, rt_gf_val, dim); double l2_dist = Distance(f_val, l2_gf_val, dim); double dgv_dist = Distance(f_val, dgv_gf_val, dim); double dgi_dist = Distance(f_val, dgi_gf_val, dim); h1_err += h1_dist; nd_err += nd_dist; rt_err += rt_dist; l2_err += l2_dist; dgv_err += dgv_dist; dgi_err += dgi_dist; if (log > 0 && h1_dist > tol) { std::cout << e << ":" << j << " h1 (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << h1_gf_val[0] << "," << h1_gf_val[1] << "," << h1_gf_val[2] << ") " << h1_dist << std::endl; } if (log > 0 && nd_dist > tol) { std::cout << e << ":" << j << " nd (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << nd_gf_val[0] << "," << nd_gf_val[1] << "," << nd_gf_val[2] << ") " << nd_dist << std::endl; } if (log > 0 && rt_dist > tol) { std::cout << e << ":" << j << " rt (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << rt_gf_val[0] << "," << rt_gf_val[1] << "," << rt_gf_val[2] << ") " << rt_dist << std::endl; } if (log > 0 && l2_dist > tol) { std::cout << e << ":" << j << " l2 (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << l2_gf_val[0] << "," << l2_gf_val[1] << "," << l2_gf_val[2] << ") " << l2_dist << std::endl; } if (log > 0 && dgv_dist > tol) { std::cout << e << ":" << j << " dgv (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << dgv_gf_val[0] << "," << dgv_gf_val[1] << "," << dgv_gf_val[2] << ") " << dgv_dist << std::endl; } if (log > 0 && dgi_dist > tol) { std::cout << e << ":" << j << " dgi (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << dgi_gf_val[0] << "," << dgi_gf_val[1] << "," << dgi_gf_val[2] << ") " << dgi_dist << std::endl; } } h1_err /= ir.GetNPoints(); nd_err /= ir.GetNPoints(); rt_err /= ir.GetNPoints(); l2_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE( h1_err == Approx(0.0)); REQUIRE( nd_err == Approx(0.0)); REQUIRE( rt_err == Approx(0.0)); REQUIRE( l2_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 3D (H1 Context)") { std::cout << "Boundary Evaluation 3D (H1 Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { ElementTransformation *T = mesh.GetBdrElementTransformation(be); const FiniteElement *fe = h1_fespace.GetBE(be); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double nd_err = 0.0; double rt_err = 0.0; double l2_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); Func_3D_lin(tip, f_val); h1_xCoef.Eval(h1_gf_val, *T, ip); nd_xCoef.Eval(nd_gf_val, *T, ip); rt_xCoef.Eval(rt_gf_val, *T, ip); l2_xCoef.Eval(l2_gf_val, *T, ip); dgv_xCoef.Eval(dgv_gf_val, *T, ip); dgi_xCoef.Eval(dgi_gf_val, *T, ip); double h1_dist = Distance(f_val, h1_gf_val, dim); double nd_dist = Distance(f_val, nd_gf_val, dim); double rt_dist = Distance(f_val, rt_gf_val, dim); double l2_dist = Distance(f_val, l2_gf_val, dim); double dgv_dist = Distance(f_val, dgv_gf_val, dim); double dgi_dist = Distance(f_val, dgi_gf_val, dim); h1_err += h1_dist; nd_err += nd_dist; rt_err += rt_dist; l2_err += l2_dist; dgv_err += dgv_dist; dgi_err += dgi_dist; if (log > 0 && h1_dist > tol) { std::cout << be << ":" << j << " h1 (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << h1_gf_val[0] << "," << h1_gf_val[1] << "," << h1_gf_val[2] << ") " << h1_dist << std::endl; } if (log > 0 && nd_dist > tol) { std::cout << be << ":" << j << " nd (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << nd_gf_val[0] << "," << nd_gf_val[1] << "," << nd_gf_val[2] << ") " << nd_dist << std::endl; } if (log > 0 && rt_dist > tol) { std::cout << be << ":" << j << " rt (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << rt_gf_val[0] << "," << rt_gf_val[1] << "," << rt_gf_val[2] << ") " << rt_dist << std::endl; } if (log > 0 && l2_dist > tol) { std::cout << be << ":" << j << " l2 (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << l2_gf_val[0] << "," << l2_gf_val[1] << "," << l2_gf_val[2] << ") " << l2_dist << std::endl; } if (log > 0 && dgv_dist > tol) { std::cout << be << ":" << j << " dgv (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << dgv_gf_val[0] << "," << dgv_gf_val[1] << "," << dgv_gf_val[2] << ") " << dgv_dist << std::endl; } if (log > 0 && dgi_dist > tol) { std::cout << be << ":" << j << " dgi (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << dgi_gf_val[0] << "," << dgi_gf_val[1] << "," << dgi_gf_val[2] << ") " << dgi_dist << std::endl; } } h1_err /= ir.GetNPoints(); nd_err /= ir.GetNPoints(); rt_err /= ir.GetNPoints(); l2_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE( h1_err == Approx(0.0)); REQUIRE( nd_err == Approx(0.0)); REQUIRE( rt_err == Approx(0.0)); REQUIRE( l2_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Boundary Evaluation 3D (DG Context)") { std::cout << "Boundary Evaluation 3D (DG Context)" << std::endl; for (int be = 0; be < mesh.GetNBE(); be++) { FaceElementTransformations *T = mesh.GetBdrFaceTransformations(be); const IntegrationRule &ir = IntRules.Get(T->GetGeometryType(), 2*order + 2); double h1_err = 0.0; double nd_err = 0.0; double rt_err = 0.0; double l2_err = 0.0; double dgv_err = 0.0; double dgi_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); Func_3D_lin(tip, f_val); h1_xCoef.Eval(h1_gf_val, *T, ip); nd_xCoef.Eval(nd_gf_val, *T, ip); rt_xCoef.Eval(rt_gf_val, *T, ip); l2_xCoef.Eval(l2_gf_val, *T, ip); dgv_xCoef.Eval(dgv_gf_val, *T, ip); dgi_xCoef.Eval(dgi_gf_val, *T, ip); double h1_dist = Distance(f_val, h1_gf_val, dim); double nd_dist = Distance(f_val, nd_gf_val, dim); double rt_dist = Distance(f_val, rt_gf_val, dim); double l2_dist = Distance(f_val, l2_gf_val, dim); double dgv_dist = Distance(f_val, dgv_gf_val, dim); double dgi_dist = Distance(f_val, dgi_gf_val, dim); h1_err += h1_dist; nd_err += nd_dist; rt_err += rt_dist; l2_err += l2_dist; dgv_err += dgv_dist; dgi_err += dgi_dist; if (log > 0 && h1_dist > tol) { std::cout << be << ":" << j << " h1 (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << h1_gf_val[0] << "," << h1_gf_val[1] << "," << h1_gf_val[2] << ") " << h1_dist << std::endl; } if (log > 0 && nd_dist > tol) { std::cout << be << ":" << j << " nd (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << nd_gf_val[0] << "," << nd_gf_val[1] << "," << nd_gf_val[2] << ") " << nd_dist << std::endl; } if (log > 0 && rt_dist > tol) { std::cout << be << ":" << j << " rt (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << rt_gf_val[0] << "," << rt_gf_val[1] << "," << rt_gf_val[2] << ") " << rt_dist << std::endl; } if (log > 0 && l2_dist > tol) { std::cout << be << ":" << j << " l2 (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << l2_gf_val[0] << "," << l2_gf_val[1] << "," << l2_gf_val[2] << ") " << l2_dist << std::endl; } if (log > 0 && dgv_dist > tol) { std::cout << be << ":" << j << " dgv (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << dgv_gf_val[0] << "," << dgv_gf_val[1] << "," << dgv_gf_val[2] << ") " << dgv_dist << std::endl; } if (log > 0 && dgi_dist > tol) { std::cout << be << ":" << j << " dgi (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << dgi_gf_val[0] << "," << dgi_gf_val[1] << "," << dgi_gf_val[2] << ") " << dgi_dist << std::endl; } } h1_err /= ir.GetNPoints(); nd_err /= ir.GetNPoints(); rt_err /= ir.GetNPoints(); l2_err /= ir.GetNPoints(); dgv_err /= ir.GetNPoints(); dgi_err /= ir.GetNPoints(); REQUIRE( h1_err == Approx(0.0)); REQUIRE( nd_err == Approx(0.0)); REQUIRE( rt_err == Approx(0.0)); REQUIRE( l2_err == Approx(0.0)); REQUIRE(dgv_err == Approx(0.0)); REQUIRE(dgi_err == Approx(0.0)); } } SECTION("Edge Evaluation 3D") { std::cout << "Edge Evaluation 3D" << std::endl; for (int e = 0; e < mesh.GetNEdges(); e++) { ElementTransformation *T = mesh.GetEdgeTransformation(e); const FiniteElement *fe = h1_fespace.GetEdgeElement(e); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); Func_3D_lin(tip, f_val); h1_xCoef.Eval(h1_gf_val, *T, ip); double h1_dist = Distance(f_val, h1_gf_val, dim); h1_err += h1_dist; if (log > 0 && h1_dist > tol) { std::cout << e << ":" << j << " h1 (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << h1_gf_val[0] << "," << h1_gf_val[1] << "," << h1_gf_val[2] << ") " << h1_dist << std::endl; } } h1_err /= ir.GetNPoints(); REQUIRE( h1_err == Approx(0.0)); } } SECTION("Face Evaluation 3D") { std::cout << "Face Evaluation 3D" << std::endl; for (int f = 0; f < mesh.GetNFaces(); f++) { ElementTransformation *T = mesh.GetFaceTransformation(f); const FiniteElement *fe = h1_fespace.GetFaceElement(f); const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), 2*order + 2); double h1_err = 0.0; double tip_data[dim]; Vector tip(tip_data, dim); for (int j=0; jSetIntPoint(&ip); T->Transform(ip, tip); Func_3D_lin(tip, f_val); h1_xCoef.Eval(h1_gf_val, *T, ip); double h1_dist = Distance(f_val, h1_gf_val, dim); h1_err += h1_dist; if (log > 0 && h1_dist > tol) { std::cout << f << ":" << j << " h1 (" << f_val[0] << "," << f_val[1] << "," << f_val[2] << ") vs. (" << h1_gf_val[0] << "," << h1_gf_val[1] << "," << h1_gf_val[2] << ") " << h1_dist << std::endl; } } h1_err /= ir.GetNPoints(); REQUIRE( h1_err == Approx(0.0)); } } } } std::cout << "Checked GridFunction::GetVectorValue at " << npts << " 3D points" << std::endl; } } // namespace get_value