// 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 "catch.hpp" #include "mfem.hpp" #include "unit_tests.hpp" using namespace mfem; Mesh MakeCartesianNonaligned(const int dim, const int ne) { Mesh mesh; if (dim == 2) { mesh = Mesh::MakeCartesian2D(ne, ne, Element::QUADRILATERAL, 1, 1.0, 1.0); } else { mesh = Mesh::MakeCartesian3D(ne, ne, ne, Element::HEXAHEDRON, 1.0, 1.0, 1.0); } // Remap vertices so that the mesh is not aligned with axes. for (int i=0; iHeight(); outsize = assembled_grad_mat->Width(); } else { insize = assembled_grad_mat->Width(); outsize = assembled_grad_mat->Height(); } Vector xv(insize); Vector assembled_y(outsize); Vector pa_y(outsize); assembled_y = 0.0; pa_y = 0.0; xv.Randomize(); if (transpose) { assembled_grad_mat->MultTranspose(xv, assembled_y); pa_grad_oper->MultTranspose(xv, pa_y); } else { assembled_grad_mat->Mult(xv, assembled_y); pa_grad_oper->Mult(xv, pa_y); } Vector error_vec(pa_y); error_vec -= assembled_y; // serial norms and serial error; we are enforcing equality on each processor // in the test double error = error_vec.Norml2() / assembled_y.Norml2(); for (int p = 0; p < size; ++p) { if (rank == p) { INFO("[" << rank << "][par] dim " << dim << " ne " << num_elements << " order " << order << (transpose ? " T:" : ":") << " error in PA gradient: " << error); } MPI_Barrier(MPI_COMM_WORLD); } delete h1_fec; delete nd_fec; delete assembled_grad_mat; delete mesh; return error; } TEST_CASE("ParallelPAGradient", "[Parallel], [ParallelPAGradient]") { auto transpose = GENERATE(true, false); auto order = GENERATE(1, 2, 3, 4); auto dim = GENERATE(2, 3); auto num_elements = GENERATE(4, 5); double error = par_compare_pa_assembly(dim, num_elements, order, transpose); REQUIRE(error == MFEM_Approx(0.0, 1.0e-14)); } #endif