Commit f675c5a1 authored by Michaël Sghaïer's avatar Michaël Sghaïer
Browse files

Add a minimalist Boost.Python wrapper to the FieldVector class (see the junior job description)

parent 0456eef1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ add_subdirectory("am")
add_subdirectory("doc")
add_subdirectory("cmake/modules")
add_subdirectory("cmake/scripts")
add_subdirectory("src")

# finalize the dune project, e.g. generating config.h etc.
finalize_dune_project()

src/CMakeLists.txt

0 → 100644
+16 −0
Original line number Diff line number Diff line
FIND_PACKAGE(Boost)
IF(Boost_FOUND)
    INCLUDE_DIRECTORIES("${Boost_INCLUDE_DIRS}" "/usr/include/python3.5m")

    SET(Boost_USE_STATIC_LIBS OFF)
    SET(Boost_USE_MULTITHREADED ON)
    SET(Boost_USE_STATIC_RUNTIME OFF)

    FIND_PACKAGE(Boost COMPONENTS python3)

    ADD_LIBRARY(fvector SHARED fvector.cc)
    TARGET_LINK_LIBRARIES(fvector ${Boost_LIBRARIES})

ELSEIF(NOT Boost_FOUND)
    MESSAGE(FATAL_ERROR "Unable to find correct Boost version. Did you set BOOST_ROOT?")
ENDIF()

src/fvector.cc

0 → 100644
+14 −0
Original line number Diff line number Diff line
#include "./fvector.hh"
#include <boost/python.hpp>
#include <boost/python/docstring_options.hpp>

BOOST_PYTHON_MODULE(libfvector)
{
    using namespace boost::python;

    docstring_options doc_options(true);

    RegisterFieldVector<double, 1>();
    RegisterFieldVector<double, 2>();
    RegisterFieldVector<double, 3>();
}

src/fvector.hh

0 → 100644
+36 −0
Original line number Diff line number Diff line
#include <../dune/common/fvector.hh>
#include <boost/python.hpp>
#include<initializer_list>

template<class K, int SIZE>
struct RegisterFieldVector
{
    typedef Dune::FieldVector<K, SIZE> FVector;

    static K& get_item(FVector* fvector, unsigned int i)
    {
        return (*fvector)[i];
    }

    RegisterFieldVector()
    {
        using namespace boost::python;

        class_<FVector>(("FieldVector" + std::to_string(SIZE)).c_str())
            .def(init<>("Constructor making default-initialized vector"))

            .def(init<K>(args("t"),
                        "Constructor making vector with identical coordinates"))

            .def(init<const FVector>(args("x"),
                        "Copy constructor"))

            .def(init<std::initializer_list<K> const&>(args("l"),
                        "Construct from a std::initializer_list"))

            .def("__len__", &FVector::size, "Return the length of the given field vector")

            .def("__getitem__", get_item, return_value_policy<return_by_value>(),
                    args("i"), "Get the ith item of the given field vector");
    }
};
+40 −0
Original line number Diff line number Diff line
import importlib.util

spec = importlib.util.spec_from_file_location("libfvector", "../../build-cmake/src/libfvector.so")
libfvector = importlib.util.module_from_spec(spec)
spec.loader.exec_module(libfvector)

import unittest

class TestWrapperDoubleFieldVector(unittest.TestCase):

    def test_constructorByValue(self):
        x = libfvector.FieldVector1(3.14)
        self.assertEqual(x[0], 3.14)

        y = libfvector.FieldVector3(1.1)
        for i in range(0, 3):
            self.assertEqual(y[i], 1.1)

    def test_constructorByCopy(self):
        x = libfvector.FieldVector3(3.14)
        y = libfvector.FieldVector3(x)

        for i in range(0, 3):
            self.assertEqual(y[i], x[i])

    def test_getItem(self):
        x = libfvector.FieldVector1(3.14)
        self.assertEqual(x[0], 3.14)

    def test_len(self):
        x = libfvector.FieldVector1(1)
        y = libfvector.FieldVector2(2)
        z = libfvector.FieldVector3(3)

        self.assertEqual(len(x), 1)
        self.assertEqual(len(y), 2)
        self.assertEqual(len(z), 3)

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