diff --git a/HW4/ReadMe.md b/HW4/ReadMe.md index 27f4458..5aed420 100644 --- a/HW4/ReadMe.md +++ b/HW4/ReadMe.md @@ -1,35 +1,35 @@ # The very last HW Igor Tomic and Mahmoud Shaqfa ## Ex. 1 - 1.1 CMakeLists.txt has been changed to include pybind11 included in the subdirectory ./pybind11. - 1.2 Python bindings have been included in ./py_wrap.cc file accordingly to ./main.py file includes. - 1.3 ## Ex. 2 ## Ex. 3 To build and make the project's binaries call the following shell script. This shell script will make a "build" file, call out Cmake and make. -- 3.1.1 to make excecutable (if not) and run +- 3.1.1 to make excecutable (if not) and run C/P: ``` chmod +x compile.sh && ./compile.sh ``` -- 3.1.2 to run only: +- 3.1.2 to run only C/P: ``` ./compile.sh ``` -- 3.1.3 to run the final python file use the following command: +- 3.1.3 to run the final python file use the following command C/P: ``` -cd build && python3 main.py nsteps, freq, filename, particle_type, timestep +cd build && python3 main.py nsteps freq filename particle_type timestep ``` diff --git a/HW4/py_wrap.cc b/HW4/py_wrap.cc index c79bb92..7220f3c 100644 --- a/HW4/py_wrap.cc +++ b/HW4/py_wrap.cc @@ -1,147 +1,148 @@ #include #include #include #include "material_points_factory.hh" #include "ping_pong_balls_factory.hh" #include "particles_factory_interface.hh" #include "planets_factory.hh" #include "compute_temperature.hh" #include "csv_writer.hh" #include "system.hh" #include "my_types.hh" // All the classes which are to be used in python are included here, together with the needed external library. // instead of just including this header at the end of each file! namespace py = pybind11; //Start of the py_wrap.cc module: PYBIND11_MODULE(pypart,m){ // Generate Documentation m.doc()="This file is to wrap the C++ library over a Python API for the particles project."; // Wrapping ParticlesFactoryInterface with Reference Return (C++ will handle the Garbage Collection). However, we don't need the Reference Return in all cases. Primary case when required is if we're dealing with singletons. py::class_(m, "ParticlesFactoryInterface") .def("getInstance", &ParticlesFactoryInterface::getInstance, py::return_value_policy::reference) .def("createSimulation", - &ParticlesFactoryInterface::createSimulation) + &ParticlesFactoryInterface::createSimulation, + py::return_value_policy::reference) .def_property_readonly("system_evolution", &ParticlesFactoryInterface::getSystemEvolution) ; // Wrapping the PingPongBallsFactory (Reference Return) py::class_(m, "PingPongBallsFactory") .def("getInstance", &PingPongBallsFactory::getInstance, py::return_value_policy::reference) .def("createSimulation", &PingPongBallsFactory::createSimulation, py::return_value_policy::reference) ; // Wrapping the PlanetsFactory interface (Reference Return) py::class_(m, "PlanetsFactory") .def("getInstance", &PlanetsFactory::getInstance, py::return_value_policy::reference) .def("createSimulation", &PlanetsFactory::createSimulation, - py::return_value_policy::reference) + py::return_value_policy::reference) ; // Wrapping the MaterialPointsFactory (Reference Return) py::class_(m, "MaterialPointsFactory") .def("getInstance", &MaterialPointsFactory::getInstance, py::return_value_policy::reference) .def("createSimulation", (SystemEvolution & (MaterialPointsFactory::*)(const std::string &, Real)) &MaterialPointsFactory::createSimulation, py::return_value_policy::reference) .def("createSimulation", py::overload_cast (&MaterialPointsFactory::createSimulation), py::return_value_policy::reference) // In this case py::overload_cast operator has been used. The reason is that otherwise compiler can not know which method to use and thus produces the error. // In Python method overloading does not exist in the same way like in c++ (there is no overloading resolution by the compiler obviously), thus we use py::overload_cast. // Here, py::overload_cast only requires the parameter types to be specified. The return type and class are deduced .def_property_readonly("system_evolution", &MaterialPointsFactory::getSystemEvolution) ; // Wrapping SystemEvoution class py::class_(m, "SystemEvolution") .def("setNSteps", &SystemEvolution::setNSteps) .def("setDumpFreq", &SystemEvolution::setDumpFreq) .def("evolve", &SystemEvolution::evolve) .def("addCompute", &SystemEvolution::addCompute) .def("getSystem", &SystemEvolution::getSystem) ; // Wrapping the system writer (CSV files) py::class_(m, "CsvWriter") .def(py::init()) .def("write", &CsvWriter::write) ; py::class_(m, "System"); py::class_>(m, "Compute"); // Wrapping ComputeTemperature class // To read protected classes variables in Python, it is necessary to use "getsmt" methods, instead of reading them directly. py::class_>(m, "ComputeTemperature") // Define Getters first and then Setters, otherwise doesn't work! .def(py::init()) .def("compute", &ComputeTemperature::compute) .def_property("deltat", &ComputeTemperature::getDeltat, &ComputeTemperature::setDeltat) .def_property("density", &ComputeTemperature::getDensity, &ComputeTemperature::setDensity) .def_property("L", &ComputeTemperature::getL, &ComputeTemperature::setL) .def_property("capacity", &ComputeTemperature::getCapacity, &ComputeTemperature::setCapacity) .def_property("conductivity", &ComputeTemperature::getConductivity, &ComputeTemperature::setConductivity) ; }