Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
446f080
Merge pull request #269 from mfem/mfem_48_dev
sshiraiwa Apr 23, 2025
ccac1f7
added wrappers for miniapps/dpg/utils
sshiraiwa Apr 24, 2025
0383446
Merge branch 'mfem_48_dev' into dpg_dev
sshiraiwa Apr 27, 2025
3b56b38
minor edit to setup.py
sshiraiwa Apr 28, 2025
6a13251
Merge branch 'mfem_48_dev' into dpg_dev
sshiraiwa May 17, 2025
2201fb9
pmaxwell.py
sshiraiwa May 24, 2025
4d3b446
pmaxwell.py
sshiraiwa May 24, 2025
0e11b17
(WIP) work in progress
sshiraiwa May 24, 2025
bb3f56e
made ser/par.dpg module to load all dpg related routines
sshiraiwa May 26, 2025
26657dc
(WIP)...pmaxwell.py
sshiraiwa May 26, 2025
e234fca
(WIP) pmaxwell
sshiraiwa May 27, 2025
e1914ba
(WIP...)
sshiraiwa May 27, 2025
ceeaca7
merged
sshiraiwa May 28, 2025
1782435
merged
sshiraiwa May 28, 2025
96a3d26
(WIP) pmaxwell.py seems okay
sshiraiwa May 28, 2025
8ae8d8e
merged new build-install system
sshiraiwa Jun 5, 2025
b05be34
Merge remote-tracking branch 'origin/mfem_48_dev' into dpg_dev
sshiraiwa Jun 8, 2025
3da4f4f
merged
sshiraiwa Jun 23, 2025
68f5506
removed rectangular matrix coefficient warnings
sshiraiwa Jul 2, 2025
f8a77e5
Merge branch 'dpg_dev' of github.com:mfem/PyMFEM into dpg_dev
sshiraiwa Jul 2, 2025
993774c
preparig for merge
sshiraiwa Jul 2, 2025
cf44e73
Merge branch 'dpg_dev' of github.com:mfem/PyMFEM into dpg_dev
sshiraiwa Jul 2, 2025
3cca3b7
improved DPGweakform constructor. Instead of passing mfem::Array, we …
sshiraiwa Jul 30, 2025
9b68fe8
merged perlmutter_fix
sshiraiwa Jul 30, 2025
8e69e62
(WIP)
sshiraiwa Dec 15, 2025
d75793c
added partcileset/particlevector wrapping
sshiraiwa Dec 15, 2025
c7ebcef
merged dpg
sshiraiwa Dec 23, 2025
2f29cfd
addressed change in hypre.hpp to fix const correctness (https://githu…
sshiraiwa Dec 25, 2025
69b975e
Merge branch 'fix_hypre_typemap' into dgp_merge
sshiraiwa Dec 25, 2025
4e9df3a
picked-up dpg-dev branch, added link to the orignal object when Vecto…
sshiraiwa Jan 1, 2026
81e3435
merged particleset/particlevector branch
sshiraiwa Jan 1, 2026
96c2d21
update change log
sshiraiwa Jan 1, 2026
7ba9465
fixed DenseMatrix::GetDataArray()
sshiraiwa Jan 2, 2026
49d6112
minor fix...response to copilot...
sshiraiwa Jan 6, 2026
99ac290
update shadowed method in fespace.i and pfespace.i
sshiraiwa Jan 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pip install . -C"with-parallel=Yes" -C"with-gslib=Yes"
|------|-------------|
| `--with-parallel` | Install both serial and parallel versions of `MFEM` and the wrapper<br>(note: this option turns on building `metis` and `hypre`) |
| `--mfem-branch=<reference>` | Download/install MFEM using a specific reference (`git` `branch`, `hash`, or `tag`) |
| `--mfem-miniapps` | Install MFEM with MFEM C++ miniapps |
| `--user` | Install in user's site-package |

## Advanced options
Expand Down
20 changes: 13 additions & 7 deletions _build_system/build_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def print_config():
print(" when needed, the dependency (mfem/hypre/metis) will be installed under " +
bglb.ext_prefix)
print(" build mfem : " + ("Yes" if bglb.build_mfem else "No"))
print(" build miniapps: " + ("Yes" if bglb.mfem_miniapps else "No"))
print(" build metis : " + ("Yes" if bglb.build_metis else "No"))
print(" build hypre : " + ("Yes" if bglb.build_hypre else "No"))
print(" build libceed : " + ("Yes" if bglb.build_libceed else "No"))
Expand Down Expand Up @@ -89,7 +90,7 @@ def initialize_cmd_options(command_obj):
command_obj.mfem_source = bglb.mfem_source
command_obj.mfem_branch = ''
command_obj.mfem_debug = False
command_obj.mfem_build_miniapps = False
command_obj.mfem_miniapps = True
Copy link

Copilot AI Jan 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default value for mfem_miniapps is changed from False to True. This is a significant behavior change that could affect existing workflows. Consider whether this should default to False for backward compatibility, or ensure this change is well-documented in the PR description.

Suggested change
command_obj.mfem_miniapps = True
command_obj.mfem_miniapps = False

Copilot uses AI. Check for mistakes.
command_obj.metis_prefix = ''
command_obj.hypre_prefix = ''

Expand Down Expand Up @@ -146,7 +147,7 @@ def initialize_cmd_options(command_obj):
('mfem-source=', None, 'Specify mfem source location' +
'MFEM source directory. Required to run-swig '),
('mfem-debug', None, 'Build MFME with MFEM_DEBUG enabled'),
('mfem-build-miniapps', None, 'build MFME Miniapps'),
('mfem-miniapps', None, 'build MFME Miniapps'),
('hypre-prefix=', None, 'Specify locaiton of hypre' +
'libHYPRE.so must exits under <hypre-prefix>/lib'),
('metis-prefix=', None, 'Specify locaiton of metis' +
Expand Down Expand Up @@ -221,15 +222,22 @@ def process_cmd_options(command_obj, cfs):
assert False, str(command_obj) + " does not have " + attr
setattr(command_obj, attr, value)
else:
value = cfs.pop(param, "No")
if not hasattr(command_obj, attr):
assert False, str(command_obj) + " does not have " + attr

if getattr(command_obj, attr):
value = cfs.pop(param, "Yes")
else:
value = cfs.pop(param, "No")

if value.upper() in ("YES", "TRUE", "1"):
setattr(command_obj, attr, True)
else:
setattr(command_obj, attr, False)

if len(cfs) != 0:
assert False, "unknonw input is given " + str(cfs)


def process_setup_options(command_obj, args):
for item in args:
Expand Down Expand Up @@ -298,7 +306,7 @@ def configure_install(self):
bglb.run_swig_parallel = bool(self.with_parallel)

bglb.mfem_debug = bool(self.mfem_debug)
bglb.mfem_build_miniapps = bool(self.mfem_build_miniapps)
bglb.mfem_miniapps = bool(self.mfem_miniapps)

if bglb.build_serial:
bglb.build_serial = (not bglb.swig_only and not bglb.ext_only)
Expand Down Expand Up @@ -439,7 +447,6 @@ def configure_install(self):
bglb.build_parallel = False
bglb.keep_temp = True


if bglb.libceed_only:
bglb.clean_swig = False
bglb.run_swig = False
Expand All @@ -453,7 +460,6 @@ def configure_install(self):
bglb.build_libceed = True
bglb.keep_temp = True


if bglb.gslib_only:
bglb.clean_swig = False
bglb.run_swig = False
Expand All @@ -466,7 +472,7 @@ def configure_install(self):
bglb.build_gslib = True
bglb.keep_temp = True


bglb.is_configured = True


configure_build = configure_install
6 changes: 3 additions & 3 deletions _build_system/build_mfem.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def add_rpath(p, dest):

cmake_opts = {'DBUILD_SHARED_LIBS': '1',
'DMFEM_ENABLE_EXAMPLES': '1',
'DMFEM_ENABLE_MINIAPPS': '0',
'DMFEM_ENABLE_MINIAPPS': '1',
'DCMAKE_SHARED_LINKER_FLAGS': ldflags,
'DMFEM_USE_ZLIB': '1',
'DCMAKE_CXX_FLAGS': bglb.cxxstd_flag,
Expand All @@ -56,8 +56,8 @@ def add_rpath(p, dest):
if bglb.mfem_debug:
cmake_opts['DMFEM_DEBUG'] = 'YES'

if bglb.mfem_build_miniapps:
cmake_opts['DMFEM_ENABLE_MINIAPPS'] = '1'
if not bglb.mfem_miniapps:
cmake_opts['DMFEM_ENABLE_MINIAPPS'] = '0'

if bglb.verbose:
cmake_opts['DCMAKE_VERBOSE_MAKEFILE'] = '1'
Expand Down
1 change: 1 addition & 0 deletions _build_system/build_pymfem.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def write_setup_local():
'gslibpinc': os.path.join(bglb.gslibp_prefix, 'include'),
'cxxstdflag': bglb.cxxstd_flag,
'build_mfem': '1' if bglb.build_mfem else '0',
'build_miniapps': '1' if bglb.mfem_miniapps else '0',
'bdist_wheel_dir': bglb.bdist_wheel_dir,
}

Expand Down
42 changes: 25 additions & 17 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
2025 12
* PyMFEM4.9
- ordering.i is added and made correponding adjustment in *.i files.
Copy link

Copilot AI Jan 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the changelog, "correponding" is misspelled. It should be "corresponding".

Suggested change
- ordering.i is added and made correponding adjustment in *.i files.
- ordering.i is added and made corresponding adjustment in *.i files.

Copilot uses AI. Check for mistakes.
- update ex22, ex22p to save ComplexGridFunction as is
- fixed ParComplexGridFunction::Save wrapping
- fixed GetDataArray of Vector/DenseMatrix/DenseTensor/SparseMatrix so that
destructore is not pre-maturely called when return value is not stored to
Copy link

Copilot AI Jan 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the changelog, "destructore" is misspelled. It should be "destructor".

Suggested change
destructore is not pre-maturely called when return value is not stored to
destructor is not pre-maturely called when return value is not stored to

Copilot uses AI. Check for mistakes.
a variable.
- particleset.hpp, particlevector.hpp wrapper
- miniapp/dpg/utils/*.hpp is wrapped.
- Python version of pmaxwell.py in miniapp/dpg directory
- Shadowed method in fespace.i and pfespace.i are improved to return intArray and DofTransformation
as a pre-allocated object.

2025 09
* PyMFEM 4.8
Expand All @@ -21,26 +31,26 @@
- wrappers for the following MFEM objects are added
-- Array2D
-- IterativeSolverController
-- CoefficientPtrArray
-- VectorCoefficientPtrArray
-- MatrixCoefficientPtrArray
- bounds.i is added to support bounds.hpp
- c++ standared is moved to c++17
-- CoefficientPtrArray
-- VectorCoefficientPtrArray
-- MatrixCoefficientPtrArray
- bounds.i is added to support bounds.hpp
- c++ standared is moved to c++17

2024 08
* MFEM 4.7 support
- AttributeSets are supported. ex39 and ex39p are added to demonstrate how to use it from Python
- Hyperbolic conservation element/face form integrators (hyperbolic.hpp) are supported. ex18.py and
ex18.py are updated to conform with the updated C++ examples.
- Update SWIG requirement to >= 4.2.1 (required to wrap MFEM routines which use recent C++ features)
- Buiding --with-libceed will download libceed=0.12.0, as required by MFEM 4.7
- Fixed eltrans::transformback
- Improved testing using Github actions
- New caller and dispatch yml configulations allows for running a test manually
- Test runs automatically for PR and PR update
- Test using Python 3.11 is added
- Hyperbolic conservation element/face form integrators (hyperbolic.hpp) are supported. ex18.py and
ex18.py are updated to conform with the updated C++ examples.
- Update SWIG requirement to >= 4.2.1 (required to wrap MFEM routines which use recent C++ features)
- Buiding --with-libceed will download libceed=0.12.0, as required by MFEM 4.7
- Fixed eltrans::transformback
- Improved testing using Github actions
- New caller and dispatch yml configulations allows for running a test manually
- Test runs automatically for PR and PR update
- Test using Python 3.11 is added
- Refresh install instruction (Install.md)
- Python 3.7 has reached EOL and is no longer supported. This version will support Python 3.8 and above, and
- Python 3.7 has reached EOL and is no longer supported. This version will support Python 3.8 and above, and
will likely be the last version to support Python 3.8.


Expand Down Expand Up @@ -323,5 +333,3 @@
2017 10.10 chypre.py
* CHypreMat::__add__ and CHypreMat::__sub__ was calling CHypreMat without
specifing col_parts.


48 changes: 48 additions & 0 deletions docs/manual.txt
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,54 @@ to find more details of the MFEM library.
M = mfem.GSSmoother(AA)
mfem.PCG(A, M, B, X, 1, 200, 1e-12, 0.0)

4-19) fespace/pfespace
Following routines are wrapped using Shadow feature
FiniteElementSpace::GetBdrElementVDofs
FiniteElementSpace::GetElementVDofs
FiniteElementSpace::GetPatchVDofs
FiniteElementSpace::GetFaceVDofs
FiniteElementSpace::GetEdgeVDofs
FiniteElementSpace::GetVertexVDofs
FiniteElementSpace::GetElementInteriorVDofs
FiniteElementSpace::GetEdgeInteriorVDofs

FiniteElementSpace::GetBdrElementDofs
FiniteElementSpace::GetElementDofs
FiniteElementSpace::GetPatchDofs
FiniteElementSpace::GetFaceDofs
FiniteElementSpace::GetEdgeDofs
FiniteElementSpace::GetVertexDofs
FiniteElementSpace::GetElementInteriorDofs
FiniteElementSpace::GetEdgeInterioVDofs

ParFiniteElementSpace::GetSharedEdgeDofs
ParFiniteElementSpace::GetSharedTriangleDofs
ParFiniteElementSpace::GetSharedQuadrilateralDofs
ParFiniteElementSpace::GetFaceNbrElementVDofs

For example, GetPatchDofs are wrapped with

%feature("shadow") mfem::FiniteElementSpace::GetPatchDofs %{
def GetPatchDofs(self, *args):
if len(args) == 1:
from .array import intArray
dofs = intArray()
$action(self, args[0], dofs)
return vdofs.ToList()
else:
return $action(self, *args)
%}

Therefore,
# this returns a newly created Python list,
GetPatchDofs(i)

# this stores data to intArray (more closed to C++ syntax)
arr = mfem.ntArray()
GetPatchDofs(i, arr)



-- Known issues --

PyMFEM is an on-going effort. Not all MFEM functionality is properly
Expand Down
6 changes: 6 additions & 0 deletions mfem/_par/blockoperator.i
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,15 @@ if len(args) == 2:
mfem::SparseMatrix *Opr2SparseMat(mfem::Operator *op) {
return dynamic_cast<mfem::SparseMatrix*>(op);
}
mfem::SparseMatrix *Opr2SparseMatrix(mfem::Operator *op) {
return dynamic_cast<mfem::SparseMatrix*>(op);
}
mfem::HypreParMatrix *Opr2HypreParMat(mfem::Operator *op) {
return dynamic_cast<mfem::HypreParMatrix*>(op);
}
mfem::HypreParMatrix *Opr2HypreParMatrix(mfem::Operator *op) {
return dynamic_cast<mfem::HypreParMatrix*>(op);
}

%}
%include "linalg/blockoperator.hpp"
46 changes: 46 additions & 0 deletions mfem/_par/blockstaticcond.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
%module(package="mfem._par") blockstaticcond
%{
#include "mfem.hpp"
#include "numpy/arrayobject.h"
#include "miniapps/dpg/util/blockstaticcond.hpp"
#include "../common/pyoperator.hpp"
#include "../common/pysolvers.hpp"
#include "../common/pycoefficient.hpp"
#include "../common/pyintrules.hpp"
#include "../common/pybilininteg.hpp"
#include "../common/pynonlininteg.hpp"
#include "../common/io_stream.hpp"
%}

%include "../common/existing_mfem_headers.i"
#ifdef FILE_EXISTS_MINIAPPS_DPG_UTIL_BLOCKSTATICCOND

%init %{
import_array();
%}

%inline %{
#include "miniapps/dpg/util/blockstaticcond.cpp"
%}


%include "exception.i"
%import "element.i"
%import "../common/exception.i"

%import "array.i"
%import "vector.i"
%import "densemat.i"
%import "operators.i"
%import "blockmatrix.i"
%import "blockoperator.i"
%import "fespace.i"
%import "../common/exception.i"
%import "../common/io_stream_typemap.i"

OSTREAM_TYPEMAP(std::ostream&)

%ignore mfem::BlockStaticCondensation::ConvertListToReducedTrueDofs;
%include "miniapps/dpg/util/blockstaticcond.hpp"

#endif
30 changes: 30 additions & 0 deletions mfem/_par/complex_densemat.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
%module(package="mfem._par") complex_densemat
%{
#include "mfem.hpp"
#include "numpy/arrayobject.h"
#include "../common/pyoperator.hpp"
#include "../common/pysolvers.hpp"
#include "../common/pycoefficient.hpp"
#include "../common/pyintrules.hpp"
#include "../common/pybilininteg.hpp"
#include "../common/pynonlininteg.hpp"
#include "../common/io_stream.hpp"
%}

%init %{
import_array();
%}

%include "exception.i"
%import "element.i"
%import "../common/exception.i"

%import "array.i"
%import "vector.i"
%import "densemat.i"
%import "complex_operator.i"
%import "../common/exception.i"
%import "../common/io_stream_typemap.i"

%ignore mfem::ComplexLUFactors::Mult(int m, int n, std::complex<real_t> *X) const;
%include "linalg/complex_densemat.hpp"
48 changes: 48 additions & 0 deletions mfem/_par/complexstaticcond.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
%module(package="mfem._par") complexstaticcond
%{
#include "mfem.hpp"
#include "numpy/arrayobject.h"
#include "miniapps/dpg/util/complexstaticcond.hpp"
#include "../common/pyoperator.hpp"
#include "../common/pysolvers.hpp"
#include "../common/pycoefficient.hpp"
#include "../common/pyintrules.hpp"
#include "../common/pybilininteg.hpp"
#include "../common/pynonlininteg.hpp"
#include "../common/io_stream.hpp"
%}

%include "../common/existing_mfem_headers.i"
#ifdef FILE_EXISTS_MINIAPPS_DPG_UTIL_COMPLEXSTATICCOND

%init %{
import_array();
%}

%inline %{
#include "miniapps/dpg/util/complexstaticcond.cpp"
%}


%include "exception.i"
%import "element.i"
%import "../common/exception.i"

%import "array.i"
%import "vector.i"
%import "gridfunc.i"
%import "mesh.i"
%import "solvers.i"
%import "operators.i"
%import "blockmatrix.i"
%import "blockoperator.i"
%import "complex_densemat.i"
%import "../common/exception.i"
%import "../common/io_stream_typemap.i"

OSTREAM_TYPEMAP(std::ostream&)

%ignore mfem::ComplexBlockStaticCondensation::ConvertListToReducedTrueDofs;
%include "miniapps/dpg/util/complexstaticcond.hpp"

#endif
Loading
Loading