Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 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
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
8 changes: 8 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
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

2025 09
* PyMFEM 4.8
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
65 changes: 65 additions & 0 deletions mfem/_par/complexweakform.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
%module(package="mfem._par") complexweakform
%{
#include "mfem.hpp"
#include "numpy/arrayobject.h"
#include "miniapps/dpg/util/complexweakform.hpp"
#include "../common/pyoperator.hpp"
#include "../common/pysolvers.hpp"
#include "../common/pycoefficient.hpp"
#include "../common/pyintrules.hpp"
#include "../common/pylininteg.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_COMPLEXWEAKFORM

%init %{
import_array();
%}

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


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

%import "coefficient.i"
%import "gridfunc.i"
%import "mesh.i"
%import "solvers.i"
%import "operators.i"
%import "blockmatrix.i"
%import "../common/exception.i"
%import "../common/io_stream_typemap.i"

OSTREAM_TYPEMAP(std::ostream&)

%import "../common/object_array_typemap.i"
LIST_TO_MFEMOBJ_ARRAY_IN(const mfem::Array<mfem::FiniteElementSpace*>&,
mfem::FiniteElementSpace*)
LIST_TO_MFEMOBJ_ARRAY_IN(const mfem::Array<mfem::FiniteElementCollection*>&,
mfem::FiniteElementCollection*)


%pythonprepend mfem::ComplexDPGWeakForm::ComplexDPGWeakForm %{
if len(args) > 0:
fes_, fecol_ = args
self._fes = fes_
self._fecol = fecol_
%}

%pythonprepend mfem::ComplexDPGWeakForm::SetSpaces %{
self._fes = fes_
self._fecol = fecol_
%}


%include "miniapps/dpg/util/complexweakform.hpp"

#endif
17 changes: 17 additions & 0 deletions mfem/_par/densemat.i
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,23 @@ def __getitem__(self, *args):
return _densemat.DenseTensor___getitem__(self, check)
%}

%typemap(out) PyObject* mfem::DenseMatrix::GetDataArray() {
// assign self to base object
Py_INCREF($self);
PyObject * base = PyArray_BASE((PyArrayObject *) $1);
PyArray_SetBaseObject((PyArrayObject *) base , $self);

$result = $1;
}
%typemap(out) PyObject* mfem::DenseTensor::GetDataArray() {
// assign self to base object
Py_INCREF($self);
PyObject * base = PyArray_BASE((PyArrayObject *) $1);
PyArray_SetBaseObject((PyArrayObject *) base, $self);

$result = $1;
}

%include "linalg/densemat.hpp"

%extend mfem::DenseMatrix {
Expand Down
Loading
Loading