Rat bindings ============ Rat is split into a suite of interdependent C++ libraries which define many classes and items to be used in together to model magnets and compute 3D magnetic simulations. Rat classes ----------- Each Rat class is usually defined in their own translation units in each repository, for instance `rat-common/include/log.hh`_ defines the interface for the ``rat::cmn::Log`` class which is a utility to log information to console during calculations. Its implementation is done in `rat-common/src/log.cpp`_. Most Rat classes use **type definitions** to implement a factory pattern that returns a **shared pointer** to the underlying instance of class. This eases memory management for most users by avoiding to manually free memory afterwards. .. code-block:: cpp :caption: ``log.hh`` example namespace rat{namespace cmn{ // shared pointer definition for log typedef std::shared_ptr ShLogPr; // shared pointer definition for no-output log typedef std::shared_ptr ShNullLogPr; // logging to the terminal class Log{ // properties protected: ... // methods public: // logo options enum LogoType{RAT,NONE}; // constructor explicit Log( LogoType logo = NONE, const std::shared_ptr& cancel_flag = nullptr); // factory static ShLogPr create(LogoType logo = NONE); ... This factory pattern utilizes the ``create`` method to return the corresponding shared pointer to a ``Log`` instance. pyRat_ takes advantage of this workflow by using the shared pointer as the container type for pybind11_. That way Python_ users can interact with Rat C++ libraries through the shared pointer. Binding Rat classes ------------------- pyRat_ follows the Project-Rat_ structures by defining translation units for all classes to bind within each separated submodules: common, distmesh, etc... pyRat_ also splits: - `pyrat/include`_ for bindings documentations and docstrings, - `pyrat/src`_ for bindings implementations and modules. Header files in `pyrat/include`_ are also used for linking implementations when building pyRat_. For instance the `pyrat/src/common`_ submodule for binding Rat-Common items has the following structure: .. code-block:: text pyrat/src/common ├── common.cpp ← Submodule binding ├── elements.cpp ← Elements namespace bindings ├── extra.cpp ← Extra namespace bindings ├── freecad.cpp ← FreeCAD class bindings ├── gauss.cpp ← Gauss class bindings ├── gmshfile.cpp ← GmshFile class bindings ├── log.cpp ← Log class bindings ├── ... Binding a class then looks something like this to begin with: .. code-block:: cpp :caption: ``log.cpp`` binding example // Bind void bind(py::module_ &m) { // Rat shorthands using rat::cmn::Log; using rat::cmn::ShLogPr; // Class wrapper for Log auto Log_cls = py::class_(m, "Log", doc::Log); // Constructors for Log utils::add_constructors( Log_cls, // class wrapper defined above &Log::create, // rat::mdl::Log original constructor method doc::Log_create, // documentation from pyrat/src/common/log.hh py::arg("logo") = rat::cmn::Log::LogoType::NONE) // default agument; The ``utils::add_constructors`` function is a pyRat_ utility to bind the ``Log::create`` constructor method in Python_ in two ways: - using the ``Log.create()`` static method - using the ``Log()`` constructor syntax. Both ways are identical but the latter enables a more *pythonic* way of instantiating classes. The ``Log`` class can then be added to the common submodule among other classes: .. code-block:: cpp :caption: ``common.cpp`` example // Init void init(py::module_ &m) { // Common module doc m.doc() = doc::module_doc; // Bind Typecast test class Typecast::bind(m); // Bind Common module items Quadrilateral::bind(m); // Elements Node::bind(m); Log::bind(m); Gauss::bind(m); Serializer::bind(m); FreeCAD::bind(m); Opera::bind(m); GmshFile::bind(m); Extra::bind(m); // Standalone, might use other items as types }}} which can itself be added to the ``rat`` core module: .. code-block:: cpp :caption: ``rat.cpp`` example // Python core module PYBIND11_MODULE(rat, m) { // Module documentation m.doc() = pyrat::doc::module_doc; // Module metadata ... // Common submodule #ifdef ENABLE_COMMON auto common = m.def_submodule(pyrat::cmn::doc::module_name); pyrat::cmn::init(common); #endif // ENABLE_COMMON ... Each Rat submodule has its own binding of the same name, here ``common.cpp``, which aggregates all bindings defined in other source files, exposing a ``common`` submodule which will is later added to the top ``pyrat.rat`` submodule in the main `pyrat/src/rat.cpp`_ source file. For instance the ``Log`` class should be accessed in Python_ with the ``pyrat.rat.cmn.Log`` dot syntax for members. Namespaces ---------- pyRat_ makes use a **C++ namespaces** to have clean scopes. The general structure is as follow: - ``pyrat::::::bind`` for the main bind function, - ``pyrat::::::doc::`` for the docstring. For instance: - ``pyrat::cmn::Log::bind`` for the main bind function, - ``pyrat::cmn::Log::doc::create`` for the constructors documentation docstring, - ``pyrat::cmn::Log::doc::msg`` for the ``msg`` method documentation docstring, and many others. This clarifies where items come from and generalizes imports and usages. .. Links .. _Project-Rat: https://gitlab.com/project-rat .. _PRE Docs: https://gitlab.com/project-rat-extras/docs .. _Project-Rat: https://gitlab.com/project-rat .. _Project-Rat-Extras: https://gitlab.com/project-rat-extras .. _pybind11: https://github.com/pybind/pybind11 .. _pyRat: https://gitlab.com/project-rat-extras/pyrat .. _pyrat/src: https://gitlab.com/project-rat-extras/pyrat/-/tree/main/src?ref_type=heads .. _pyrat/include: https://gitlab.com/project-rat-extras/pyrat/-/tree/main/include?ref_type=heads .. _pyrat/src/common: https://gitlab.com/project-rat-extras/pyrat/-/tree/main/src/common?ref_type=heads .. _pyrat/src/rat.cpp: https://gitlab.com/project-rat-extras/pyrat/-/tree/main/src/rat.cpp?ref_type=heads .. _Python: https://www.python.org/ .. _Python wheel: https://pythonwheels.com/ .. _Python wheels: https://pythonwheels.com/ .. _Rat-Docs: https://gitlab.com/project-rat/rat-documentation .. _rat-common/include/log.hh: https://gitlab.com/Project-Rat/rat-common/-/blob/master/include/log.hh?ref_type=heads .. _rat-common/src/log.cpp: https://gitlab.com/Project-Rat/rat-common/-/blob/master/src/log.cpp?ref_type=heads .. _Rat-vcpkg: https://gitlab.com/project-rat-extras/rat-vcpkg