91 lines
2.5 KiB
C++
91 lines
2.5 KiB
C++
// 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 "unit_tests.hpp"
|
|
#include "mfem.hpp"
|
|
|
|
namespace mfem
|
|
{
|
|
|
|
#ifdef MFEM_USE_MPI
|
|
#if MFEM_HYPRE_VERSION >= 21900
|
|
|
|
|
|
TEST_CASE("HypreILU and HypreFGMRES wrappers",
|
|
"[Parallel], [HypreILU], [HypreFGMRES]")
|
|
{
|
|
if (HypreUsingGPU())
|
|
{
|
|
mfem::out << "\nAs of mfem-4.3 and hypre-2.22.0 (July 2021) this unit test\n"
|
|
<< "is NOT supported with the GPU version of hypre.\n\n";
|
|
return;
|
|
}
|
|
|
|
// Build a small diffusion problem to test the solver and preconditioner
|
|
int rank;
|
|
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
|
|
int ne = 40;
|
|
Mesh mesh = Mesh::MakeCartesian2D(
|
|
ne, ne, Element::QUADRILATERAL, 1, 1.0, 1.0);
|
|
ParMesh pmesh(MPI_COMM_WORLD, mesh);
|
|
mesh.Clear();
|
|
|
|
FiniteElementCollection *fec = new H1_FECollection(1, 2);
|
|
ParFiniteElementSpace fespace(&pmesh, fec);
|
|
Array<int> ess_tdof_list;
|
|
Array<int> ess_bdr(pmesh.bdr_attributes.Max());
|
|
ess_bdr = 1;
|
|
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
|
|
|
ConstantCoefficient one(1.0);
|
|
ParLinearForm b(&fespace);
|
|
b.AddDomainIntegrator(new DomainLFIntegrator(one));
|
|
b.Assemble();
|
|
ParBilinearForm a(&fespace);
|
|
a.AddDomainIntegrator(new DiffusionIntegrator(one));
|
|
a.Assemble();
|
|
ParGridFunction x(&fespace);
|
|
x = 0.0;
|
|
|
|
OperatorPtr A;
|
|
Vector B, X;
|
|
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B);
|
|
|
|
HypreSolver *ilu = new HypreILU();
|
|
HYPRE_ILUSetLevelOfFill(*ilu, 4); // fill level of 4
|
|
|
|
HypreFGMRES fgmres(MPI_COMM_WORLD);
|
|
const double tol = 1e-10;
|
|
fgmres.SetTol(tol);
|
|
fgmres.SetMaxIter(100);
|
|
fgmres.SetPrintLevel(0);
|
|
fgmres.SetKDim(100);
|
|
fgmres.SetPreconditioner(*ilu);
|
|
fgmres.SetOperator(*A);
|
|
fgmres.Mult(B, X);
|
|
|
|
HYPRE_Int converged;
|
|
HYPRE_FlexGMRESGetConverged(fgmres, &converged);
|
|
REQUIRE(converged == 1);
|
|
|
|
HYPRE_Real rel_resid;
|
|
HYPRE_FlexGMRESGetFinalRelativeResidualNorm(fgmres, &rel_resid);
|
|
REQUIRE(rel_resid < tol);
|
|
|
|
delete ilu;
|
|
delete fec;
|
|
}
|
|
|
|
#endif // MFEM_USE_MPI
|
|
#endif // MFEM_HYPRE_VERSION
|
|
|
|
} // namespace mfem
|