Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonuniform/Adaptive DMD bindings #9

Closed
wants to merge 6 commits into from
Closed
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -63,6 +63,9 @@ jobs:
pytest test_pyBasisReader.py --verbose
echo run pyBasisWriter unit test
pytest test_pyBasisWriter.py --verbose
echo run pyDMD unit test
pytest test_pyDMD.py --verbose
mpirun -n 2 pytest test_pyDMD.py --verbose
cmake-with-librom:
runs-on: ubuntu-latest
needs: [docker-librom-image]
@@ -115,6 +118,9 @@ jobs:
pytest test_pyBasisReader.py --verbose
echo run pyBasisWriter unit test
pytest test_pyBasisWriter.py --verbose
echo run pyDMD unit test
pytest test_pyDMD.py --verbose
mpirun -n 2 pytest test_pyDMD.py --verbose
baseline:
runs-on: ubuntu-latest
needs: [docker-base-image]
@@ -164,4 +170,7 @@ jobs:
pytest test_pyBasisReader.py --verbose
echo run pyBasisWriter unit test
pytest test_pyBasisWriter.py --verbose
echo run pyDMD unit test
pytest test_pyDMD.py --verbose
mpirun -n 2 pytest test_pyDMD.py --verbose

1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -143,6 +143,7 @@ pybind11_add_module(_pylibROM

bindings/pylibROM/algo/pyDMD.cpp
bindings/pylibROM/algo/pyParametricDMD.cpp
bindings/pylibROM/algo/pyNonuniformDMD.cpp

bindings/pylibROM/utils/mpi_utils.cpp
bindings/pylibROM/utils/pyDatabase.hpp
31 changes: 31 additions & 0 deletions bindings/pylibROM/algo/pyAdaptiveDMD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "algo/AdaptiveDMD.h"
#include "linalg/Vector.h"
#include "linalg/Matrix.h"

namespace py = pybind11;
using namespace CAROM;

PYBIND11_MODULE(adaptivedmd, m) {
py::class_<AdaptiveDMD, DMD>(m, "AdaptiveDMD")
.def(py::init<int, double, std::string, std::string, double, bool, Vector*>(),
py::arg("dim"),
py::arg("desired_dt") = -1.0,
py::arg("rbf") = "G",
py::arg("interp_method") = "LS",
py::arg("closest_rbf_val") = 0.9,
py::arg("alt_output_basis") = false,
py::arg("state_offset") = nullptr)
.def("train", (void (AdaptiveDMD::*)(double, const Matrix*, double)) &AdaptiveDMD::train,
py::arg("energy_fraction").noconvert(),
py::arg("W0") = nullptr,
py::arg("linearity_tol") = 0.0)
.def("train", (void (AdaptiveDMD::*)(int, const Matrix*, double)) &AdaptiveDMD::train,
py::arg("k").noconvert(),
py::arg("W0") = nullptr,
py::arg("linearity_tol") = 0.0)
.def("getTrueDt", &AdaptiveDMD::getTrueDt)
.def("getInterpolatedSnapshots", &AdaptiveDMD::getInterpolatedSnapshots);
}

2 changes: 1 addition & 1 deletion bindings/pylibROM/algo/pyDMD.cpp
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ void init_DMD(pybind11::module_ &m) {
return new DMD(dim, dt, alt_output_basis, vec);
}), py::arg("dim"), py::arg("dt"), py::arg("alt_output_basis") = false, py::arg("vec") = nullptr)

// .def("setOffset", &PyDMD::setOffset, py::arg("offset_vector"), py::arg("order")) //problem if we want to name the wrapper as DMD. Could get rid of the using namespace directive?
.def("setOffset", &DMD::setOffset, py::arg("offset_vector"), py::arg("order"))
.def("takeSample", [](DMD &self, py::array_t<double> &u_in, double t) {
self.takeSample(getVectorPointer(u_in), t);
})
40 changes: 40 additions & 0 deletions bindings/pylibROM/algo/pyNonuniformDMD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// Created by barrow9 on 6/4/23.
//
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/operators.h>
#include <pybind11/stl.h>
#include "librom.h"
#include "python_utils/cpp_utils.hpp"

namespace py = pybind11;
using namespace CAROM;

void init_NonuniformDMD(pybind11::module_ &m) {

py::class_<NonuniformDMD, DMD>(m, "NonuniformDMD")

//constructor, default.
.def(py::init<std::string>()) //constructor a

.def(py::init([](int dim,
bool alt_output_basis,
Vector* state_offset,
Vector* derivative_offset) {
return new NonuniformDMD(dim, alt_output_basis, state_offset, derivative_offset);
}),
py::arg("dim"),
py::arg("alt_output_basis") = false,
py::arg("state_offset") = nullptr,
py::arg("derivative_offset") = nullptr)

//TODO: needed explicitly?
.def("__del__", [](NonuniformDMD& self) { self.~NonuniformDMD(); }) // Destructor

.def("setOffset", &NonuniformDMD::setOffset, py::arg("offset_vector"), py::arg("order"))

.def("load", &NonuniformDMD::load, py::arg("base_file_name"))
.def("save", &NonuniformDMD::save, py::arg("base_file_name"));

}
2 changes: 2 additions & 0 deletions bindings/pylibROM/pylibROM.cpp
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ void init_IncrementalSVD(pybind11::module_ &m);
//algo
void init_DMD(pybind11::module_ &);
void init_ParametricDMD(pybind11::module_ &m);
void init_NonuniformDMD(pybind11::module_ &m);

//utils
void init_mpi_utils(pybind11::module_ &m);
@@ -56,6 +57,7 @@ PYBIND11_MODULE(_pylibROM, m) {
py::module algo = m.def_submodule("algo");
init_DMD(algo);
init_ParametricDMD(algo);
init_NonuniformDMD(algo);

// py::module mfem = m.def_submodule("mfem");
// init_mfem_Utilities(mfem);
289 changes: 0 additions & 289 deletions tests/test_DMD.py

This file was deleted.

49 changes: 49 additions & 0 deletions tests/test_pyDMD.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import pytest
import numpy as np
import sys
try:
# import pip-installed package
import pylibROM
import pylibROM.linalg as linalg
import pylibROM.algo as algo
import pylibROM.utils as utils
except ModuleNotFoundError:
# If pip-installed package is not found, import cmake-built package
sys.path.append("../build")
import _pylibROM as pylibROM
import _pylibROM.linalg as linalg
import _pylibROM.algo as algo
import _pylibROM.utils as utils

def test_DMD():
from mpi4py import MPI
d_rank = MPI.COMM_WORLD.Get_rank()
d_num_procs = MPI.COMM_WORLD.Get_size()

num_total_rows = 5
d_num_rows = utils.split_dimension(num_total_rows, MPI.COMM_WORLD)
num_total_rows_check, row_offset = utils.get_global_offsets(d_num_rows, MPI.COMM_WORLD)
assert(num_total_rows == num_total_rows_check)

samples = [[0.5377, 1.8339, -2.2588, 0.8622, 0.3188],
[-1.3077, -0.4336, 0.3426, 3.5784, 2.7694],
[-1.3499, 3.0349, 0.7254, -0.0631, 0.7147]]
prediction_baseline = [-0.4344, -0.0974, 0.0542, 1.2544, 0.9610]

dmd = algo.DMD(d_num_rows, 1.0)
for k, sample in enumerate(samples):
dmd.takeSample(sample[row_offset[d_rank]:row_offset[d_rank]+d_num_rows], k * 1.0)

dmd.train(2)
result = dmd.predict(3.0)
# print("rank: %d, " % d_rank, result.getData())
assert np.allclose(result.getData(), prediction_baseline[row_offset[d_rank]:row_offset[d_rank]+d_num_rows], atol=1e-3)

dmd.save("test_DMD")
dmd_load = algo.DMD("test_DMD")
result_load = dmd_load.predict(3.0)

assert np.allclose(result_load.getData(), prediction_baseline[row_offset[d_rank]:row_offset[d_rank]+d_num_rows], atol=1e-3)

if __name__ == '__main__':
pytest.main()