Skip to content

Commit b3fcd02

Browse files
committed
Introduce bindings to linear system
1 parent f1ac0f0 commit b3fcd02

File tree

6 files changed

+274
-1
lines changed

6 files changed

+274
-1
lines changed

bindings/Modules/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
project(Bindings.Modules)
22

3-
set(MODULEBINDINGS_MODULE_LIST SofaBaseTopology SofaDeformable SofaLinearSolver SofaConstraintSolver)
3+
set(MODULEBINDINGS_MODULE_LIST
4+
SofaBaseTopology
5+
SofaDeformable
6+
SofaLinearSolver
7+
SofaLinearSystem
8+
SofaConstraintSolver
9+
)
410

511
sofa_find_package(Sofa.GL QUIET)
612
if(Sofa.GL_FOUND)
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/******************************************************************************
2+
* SOFA, Simulation Open-Framework Architecture *
3+
* (c) 2021 INRIA, USTL, UJF, CNRS, MGH *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify it *
6+
* under the terms of the GNU Lesser General Public License as published by *
7+
* the Free Software Foundation; either version 2.1 of the License, or (at *
8+
* your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, but WITHOUT *
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13+
* for more details. *
14+
* *
15+
* You should have received a copy of the GNU Lesser General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*******************************************************************************
18+
* Contact information: [email protected] *
19+
******************************************************************************/
20+
#include <SofaPython3/SofaLinearSystem/Binding_LinearSystem.h>
21+
#include <SofaPython3/SofaLinearSystem/Binding_LinearSystem_doc.h>
22+
#include <pybind11/pybind11.h>
23+
24+
#include <SofaPython3/Sofa/Core/Binding_Base.h>
25+
#include <SofaPython3/PythonFactory.h>
26+
27+
#include <sofa/component/linearsystem/TypedMatrixLinearSystem.h>
28+
#include <pybind11/eigen.h>
29+
#include <sofa/linearalgebra/CompressedRowSparseMatrix.h>
30+
31+
32+
namespace py { using namespace pybind11; }
33+
34+
namespace sofapython3 {
35+
36+
using EigenSparseMatrix = Eigen::SparseMatrix<SReal, Eigen::RowMajor>;
37+
using EigenMatrixMap = Eigen::Map<Eigen::SparseMatrix<SReal, Eigen::RowMajor> >;
38+
using Vector = Eigen::Matrix<SReal,Eigen::Dynamic, 1>;
39+
using EigenVectorMap = Eigen::Map<Vector>;
40+
41+
template<class TBlock>
42+
EigenSparseMatrix toEigen(sofa::linearalgebra::CompressedRowSparseMatrix<TBlock>& matrix)
43+
{
44+
sofa::linearalgebra::CompressedRowSparseMatrix<typename TBlock::Real> filtered;
45+
filtered.copyNonZeros(matrix);
46+
filtered.compress();
47+
return EigenMatrixMap(filtered.rows(), filtered.cols(), filtered.getColsValue().size(),
48+
(EigenMatrixMap::StorageIndex*)filtered.rowBegin.data(), (EigenMatrixMap::StorageIndex*)filtered.colsIndex.data(), filtered.colsValue.data());
49+
}
50+
51+
template<>
52+
EigenSparseMatrix toEigen<SReal>(sofa::linearalgebra::CompressedRowSparseMatrix<SReal>& matrix)
53+
{
54+
return EigenMatrixMap(matrix.rows(), matrix.cols(), matrix.getColsValue().size(),
55+
(EigenMatrixMap::StorageIndex*)matrix.rowBegin.data(), (EigenMatrixMap::StorageIndex*)matrix.colsIndex.data(), matrix.colsValue.data());
56+
}
57+
58+
template<class TBlock>
59+
void bindLinearSystems(py::module &m)
60+
{
61+
using CRS = sofa::linearalgebra::CompressedRowSparseMatrix<TBlock>;
62+
using CRSLinearSystem = sofa::component::linearsystem::TypedMatrixLinearSystem<CRS, sofa::linearalgebra::FullVector<SReal> >;
63+
64+
const std::string typeName = CRSLinearSystem::GetClass()->className + CRSLinearSystem::GetCustomTemplateName();
65+
66+
py::class_<CRSLinearSystem,
67+
sofa::core::objectmodel::BaseObject,
68+
sofapython3::py_shared_ptr<CRSLinearSystem> > c(m, typeName.c_str(), sofapython3::doc::linearsystem::linearSystemClass);
69+
70+
c.def("A", [](CRSLinearSystem& self) -> EigenSparseMatrix
71+
{
72+
if (CRS* matrix = self.getSystemMatrix())
73+
{
74+
return toEigen(*matrix);
75+
}
76+
return {};
77+
}, sofapython3::doc::linearsystem::linearSystem_A);
78+
79+
c.def("b", [](CRSLinearSystem& self) -> Vector
80+
{
81+
if (auto* vector = self.getRHSVector())
82+
{
83+
return EigenVectorMap(vector->ptr(), vector->size());
84+
}
85+
return {};
86+
}, sofapython3::doc::linearsystem::linearSystem_b);
87+
88+
c.def("x", [](CRSLinearSystem& self) -> Vector
89+
{
90+
if (auto* vector = self.getSolutionVector())
91+
{
92+
return EigenVectorMap(vector->ptr(), vector->size());
93+
}
94+
return {};
95+
}, sofapython3::doc::linearsystem::linearSystem_x);
96+
97+
98+
/// register the binding in the downcasting subsystem
99+
PythonFactory::registerType<CRSLinearSystem>([](sofa::core::objectmodel::Base* object)
100+
{
101+
return py::cast(dynamic_cast<CRSLinearSystem*>(object));
102+
});
103+
}
104+
105+
void moduleAddLinearSystem(py::module &m)
106+
{
107+
bindLinearSystems<SReal>(m);
108+
bindLinearSystems<sofa::type::Mat<3, 3, SReal> >(m);
109+
}
110+
111+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/******************************************************************************
2+
* SOFA, Simulation Open-Framework Architecture *
3+
* (c) 2021 INRIA, USTL, UJF, CNRS, MGH *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify it *
6+
* under the terms of the GNU Lesser General Public License as published by *
7+
* the Free Software Foundation; either version 2.1 of the License, or (at *
8+
* your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, but WITHOUT *
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13+
* for more details. *
14+
* *
15+
* You should have received a copy of the GNU Lesser General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*******************************************************************************
18+
* Contact information: [email protected] *
19+
******************************************************************************/
20+
21+
#pragma once
22+
23+
#include <pybind11/pybind11.h>
24+
25+
namespace sofapython3
26+
{
27+
28+
void moduleAddLinearSystem(pybind11::module &m);
29+
30+
} /// namespace sofapython3
31+
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/******************************************************************************
2+
* SOFA, Simulation Open-Framework Architecture *
3+
* (c) 2021 INRIA, USTL, UJF, CNRS, MGH *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify it *
6+
* under the terms of the GNU Lesser General Public License as published by *
7+
* the Free Software Foundation; either version 2.1 of the License, or (at *
8+
* your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, but WITHOUT *
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13+
* for more details. *
14+
* *
15+
* You should have received a copy of the GNU Lesser General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*******************************************************************************
18+
* Contact information: [email protected] *
19+
******************************************************************************/
20+
21+
#pragma once
22+
23+
namespace sofapython3::doc::linearsystem {
24+
25+
static auto linearSystemClass =
26+
R"(
27+
Linear system. Supports only CompressedRowSparseMatrix.
28+
29+
example:
30+
------------
31+
32+
linear_system = root.addObject('MatrixLinearSystem', template='CompressedRowSparseMatrixd')
33+
)";
34+
35+
static auto linearSystem_A =
36+
R"(
37+
Returns the global system matrix as a scipy sparse matrix
38+
39+
example:
40+
------------
41+
linear_system = root.addObject('MatrixLinearSystem', template='CompressedRowSparseMatrixd')
42+
matrix = linear_system.A()
43+
)";
44+
45+
static auto linearSystem_b =
46+
R"(
47+
Returns the global system right hand side as a numpy array
48+
49+
example:
50+
------------
51+
linear_system = root.addObject('MatrixLinearSystem', template='CompressedRowSparseMatrixd')
52+
matrix = linear_system.b()
53+
)";
54+
55+
static auto linearSystem_x =
56+
R"(
57+
Returns the global system solution vector as a numpy array
58+
59+
example:
60+
------------
61+
linear_system = root.addObject('MatrixLinearSystem', template='CompressedRowSparseMatrixd')
62+
matrix = linear_system.x()
63+
)";
64+
65+
} // namespace sofapython3::doc::baseCamera
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
project(Bindings.Modules.SofaLinearSystem)
2+
3+
set(HEADER_FILES
4+
${CMAKE_CURRENT_SOURCE_DIR}/Binding_LinearSystem.h
5+
${CMAKE_CURRENT_SOURCE_DIR}/Binding_LinearSystem_doc.h
6+
)
7+
8+
set(SOURCE_FILES
9+
${CMAKE_CURRENT_SOURCE_DIR}/Binding_LinearSystem.cpp
10+
${CMAKE_CURRENT_SOURCE_DIR}/Module_SofaLinearSystem.cpp
11+
)
12+
13+
if (NOT TARGET SofaPython3::Plugin)
14+
find_package(SofaPython3 REQUIRED COMPONENTS Plugin Bindings.Sofa)
15+
endif()
16+
17+
sofa_find_package(Sofa.Component.LinearSystem REQUIRED)
18+
19+
SP3_add_python_module(
20+
TARGET ${PROJECT_NAME}
21+
PACKAGE Bindings.Modules
22+
MODULE SofaLinearSystem
23+
DESTINATION Sofa
24+
SOURCES ${SOURCE_FILES}
25+
HEADERS ${HEADER_FILES}
26+
DEPENDS Sofa.Component.LinearSystem SofaPython3::Plugin SofaPython3::Bindings.Sofa.Core
27+
)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/******************************************************************************
2+
* SofaPython3 plugin *
3+
* (c) 2021 CNRS, University of Lille, INRIA *
4+
* *
5+
* This program is free software; you can redistribute it and/or modify it *
6+
* under the terms of the GNU Lesser General Public License as published by *
7+
* the Free Software Foundation; either version 2.1 of the License, or (at *
8+
* your option) any later version. *
9+
* *
10+
* This program is distributed in the hope that it will be useful, but WITHOUT *
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
13+
* for more details. *
14+
* *
15+
* You should have received a copy of the GNU Lesser General Public License *
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
17+
*******************************************************************************
18+
* Contact information: [email protected] *
19+
******************************************************************************/
20+
21+
#include <pybind11/pybind11.h>
22+
#include <SofaPython3/SofaLinearSystem/Binding_LinearSystem.h>
23+
24+
namespace sofapython3
25+
{
26+
27+
PYBIND11_MODULE(SofaLinearSystem, m)
28+
{
29+
moduleAddLinearSystem(m);
30+
}
31+
32+
} // namespace sofapython3
33+

0 commit comments

Comments
 (0)