feat(initial): added portable mfem build system
This commit is contained in:
91
src/python/bindings.cpp
Normal file
91
src/python/bindings.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <meson_mfem_template/config.hpp>
|
||||
#include <mfem.hpp>
|
||||
#include <nanobind/nanobind.h>
|
||||
#include <nanobind/stl/string.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace nb = nanobind;
|
||||
|
||||
namespace
|
||||
{
|
||||
int serial_poisson_dofs(int cells, int order)
|
||||
{
|
||||
if (cells < 2 || order < 1)
|
||||
{
|
||||
throw nb::value_error("cells must be >= 2 and order must be >= 1");
|
||||
}
|
||||
mfem::Mesh mesh = mfem::Mesh::MakeCartesian2D(
|
||||
cells, cells, mfem::Element::QUADRILATERAL, true, 1.0, 1.0);
|
||||
mfem::H1_FECollection elements(order, mesh.Dimension());
|
||||
mfem::FiniteElementSpace space(&mesh, &elements);
|
||||
mfem::Array<int> essential_boundary(mesh.bdr_attributes.Max());
|
||||
essential_boundary = 1;
|
||||
mfem::Array<int> essential_dofs;
|
||||
space.GetEssentialTrueDofs(essential_boundary, essential_dofs);
|
||||
|
||||
mfem::ConstantCoefficient one(1.0);
|
||||
mfem::LinearForm rhs(&space);
|
||||
rhs.AddDomainIntegrator(new mfem::DomainLFIntegrator(one));
|
||||
rhs.Assemble();
|
||||
mfem::GridFunction solution(&space);
|
||||
solution = 0.0;
|
||||
mfem::BilinearForm diffusion(&space);
|
||||
diffusion.AddDomainIntegrator(new mfem::DiffusionIntegrator(one));
|
||||
diffusion.Assemble();
|
||||
|
||||
mfem::OperatorPtr matrix;
|
||||
mfem::Vector linear_rhs;
|
||||
mfem::Vector linear_solution;
|
||||
diffusion.FormLinearSystem(
|
||||
essential_dofs, solution, rhs, matrix, linear_solution, linear_rhs);
|
||||
mfem::GSSmoother smoother(static_cast<mfem::SparseMatrix &>(*matrix));
|
||||
mfem::CGSolver solver;
|
||||
solver.SetOperator(*matrix);
|
||||
solver.SetPreconditioner(smoother);
|
||||
solver.SetRelTol(1e-10);
|
||||
solver.SetMaxIter(200);
|
||||
solver.SetPrintLevel(0);
|
||||
solver.Mult(linear_rhs, linear_solution);
|
||||
if (!solver.GetConverged())
|
||||
{
|
||||
throw std::runtime_error("MFEM CG solve did not converge");
|
||||
}
|
||||
return space.GetTrueVSize();
|
||||
}
|
||||
|
||||
nb::dict capabilities()
|
||||
{
|
||||
nb::dict result;
|
||||
result["mpi"] = MESON_MFEM_HAS_MPI != 0;
|
||||
result["hypre"] = MESON_MFEM_HAS_HYPRE != 0;
|
||||
result["metis"] = MESON_MFEM_HAS_METIS != 0;
|
||||
result["cuda"] = MESON_MFEM_HAS_CUDA != 0;
|
||||
result["hip"] = MESON_MFEM_HAS_HIP != 0;
|
||||
result["openmp"] = MESON_MFEM_HAS_OPENMP != 0;
|
||||
result["gslib"] = MESON_MFEM_HAS_GSLIB != 0;
|
||||
result["zlib"] = MESON_MFEM_HAS_ZLIB != 0;
|
||||
result["sundials"] = MESON_MFEM_HAS_SUNDIALS != 0;
|
||||
result["ceed"] = MESON_MFEM_HAS_CEED != 0;
|
||||
result["fms"] = MESON_MFEM_HAS_FMS != 0;
|
||||
result["algoim"] = MESON_MFEM_HAS_ALGOIM != 0;
|
||||
result["simd"] = MESON_MFEM_HAS_SIMD != 0;
|
||||
result["bundled_mfem"] = MESON_MFEM_USING_BUNDLED_MFEM != 0;
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
NB_MODULE(_core, module)
|
||||
{
|
||||
module.doc() = "Small nanobind validation module for the Meson MFEM bundle";
|
||||
module.def("mfem_version", []() { return std::string(MFEM_VERSION_STRING); });
|
||||
module.def("capabilities", &capabilities);
|
||||
module.def(
|
||||
"serial_poisson_dofs",
|
||||
&serial_poisson_dofs,
|
||||
nb::arg("cells") = 4,
|
||||
nb::arg("order") = 2,
|
||||
"Assemble and solve a small MFEM Poisson problem; return true DOFs.");
|
||||
}
|
||||
Reference in New Issue
Block a user