...

Commits (17)
 ... ... @@ -433,3 +433,97 @@ year = "2012" publisher={Addison-Wesley Professional} } %% NekPy references @misc{BoostPythonTutorial, author = "de Guzman J., Abrahams D.", title = "Boost.Python Tutorial - 1.67.0", year = "2018", url = "https://www.boost.org/doc/libs/1_67_0/libs/python/doc/html/tutorial/index.html", note = "[Accessed 1st May 2018]" } @misc{BoostPythonWikiEntry, title = "boost.python/HowTo - Python Wiki", year = "2015", url = "https://wiki.python.org/moin/boost.python/HowTo", note = "[Accessed 1st May 2018]" } @misc{GitHubExamples, title = "GitHub - TNG/boost-python-examples: Some examples for the use of boost::python", year = "2016", url = "https://github.com/TNG/boost-python-examples", note = "[Accessed 7th May 2018]" } @misc{OpenStreetGraphCookbook, title = "osgboostpython/WrappingCookbook.md at wiki · Skylark13/osgboostpython · GitHub", year = "2015", url = "https://github.com/Skylark13/osgboostpython/blob/wiki/WrappingCookbook.md", note = "[Accessed 7th May 2018]" } @misc{ManualWrappingRationale, title = "osgboostpython/ManualWrappingRationale.md at wiki · Skylark13/osgboostpython · GitHub", year = "2015", url = "https://github.com/Skylark13/osgboostpython/blob/wiki/ManualWrappingRationale.md", note = "[Accessed 7th May 2018]" } @misc{PEP257, title = "PEP 257 -- Docstring Conventions", author = "Goodger D., van Rossum G.", year = "2001", url = "https://www.python.org/dev/peps/pep-0257/", note = "[Accessed 16th May 2018]" } @misc{PythonEnumDocstring, title = "Piotr Jaroszyński's blog: Boost.Python: docstrings in enums", author = "Jaroszyński P.", year = "2007", url = "http://blog.piotrj.org/2007/07/boostpython-docstrings-in-enums.html", note = "[Accessed 16th May 2018]" } @misc{PythonGoogle, title = "Google Python Style Guide", author = "Patel A., Picard A., Jhong E. et al.", url = "https://google.github.io/styleguide/pyguide.html", note = "[Accessed 16th May 2018]" } @book{C++Api, title = "API Design for C++", author = "Reddy M.", year = "2011", publisher = "Burlington: Elsevier" } @book{C++Memory, author = "Daconta M.", title = "C++ pointers and dynamic memory management", publisher = "New York: Wiley", year = "1995" } @misc{C++SharedPtr, title =" std::shared\_ptr - cppreference.com", url = "http://en.cppreference.com/w/cpp/memory/shared\_ptr", note = "[Accessed 21 March 2018]" } @misc{PythonMemory, author = "Python Software Foundation", title = "Memory Management - Python 2.7.14 documentation", url = "https://docs.python.org/2/c-api/memory.html", note = "[Accessed 21 March 2018]" } @misc{PythonManualMemory, author = "Python Software Foundation", title = "Reference Counting - Python 2.7.14 documentation", url = "https://docs.python.org/2/c-api/refcounting.html", note = "[Accessed 21 March 2018]" } \ No newline at end of file
 ... ... @@ -76,6 +76,10 @@ \input{utilities/utilities-master.tex} \part{NekPy: Python interface to \nek{}} \label{part:nekpy} \input{python/python-master.tex} \bibliographystyle{plain} \bibliography{developers-guide} ... ...

75.2 KB

33.3 KB

4.58 KB

5.66 KB

7.32 KB

8.05 KB

22.2 KB

19.6 KB

18.7 KB

 \chapter{FieldConvert in NekPy} This chapter will describe the idea behind the \texttt{FieldConvert} utility in NekPy and discuss how the process is implemented through a Python \texttt{FieldConverter} class. As this part of the project has not been fully completed yet, this chapter also outlines the tasks that need to be done in order to show the proof-of-concept, as well as some ideas for further improving the tool. \section{Idea and motivation} The idea behind porting \texttt{FieldConvert} utility to Python is to allow the user to execute a seamless workflow, from converting the mesh and running calculations to preparing data visualisations. This solution is a potential improvement over the original \texttt{FieldConvert} tool, as the Python-based workflow can potentially be executed from a single Python script. Another advantage of the Python version of the tool is the possibility of interacting with other software featuring Python interface, e.g. Paraview. This could make the process of visualising the results of computations done with \nek{} even easier. \section{Design and implementation} \texttt{FieldConvert} utility in Python was designed to provide the user with an easy workflow. Hence, a minimum effort is required to set up the conversion and the majority of work is done behind the scenes. This section will discuss the design of the utility, including the description of work yet to be done, as well as the user workflow required to execute the basic conversions. \subsection{\texttt{FieldConverter} class} The entire procedure outlined in the original \texttt{FieldConvert} utility is managed by the \texttt{FieldConverter} class located in \path{utilities/FieldConvert/Python/FieldConvert.py}. The class has the following attributes: \begin{itemize} \item \texttt{fieldSharedPtr}: a shared pointer to the field, necessary to initialise a module; \begin{itemize} \item \emph{TO-DO}: \texttt{FieldSharedPtr} type remains to be wrapped. \item \emph{TO-DO}: Whether a separate \texttt{FieldSharedPtr} is needed for each module initialisation needs to be discussed. \end{itemize} \item \texttt{moduleFactory}: would be equivalent to \texttt{GetModuleFactory()} in the original utility; \begin{itemize} \item \emph{TO-DO}: Whether this is possible needs to be discussed. \item \emph{TO-DO}: It would be best to wrap the general template \texttt{NekFactory} and initialise a module factory this way. \end{itemize} \item \texttt{availableModuleList}: holds a list of available modules in order to assert that the modules requested by the user are available; \begin{itemize} \item \emph{TO-DO}: \texttt{PrintAvailableClasses} method needs to be wrapped. \item \emph{TO-DO}: It would definitely be neater if the available modules existed as an enum rather than just strings containing names. \end{itemize} \item \texttt{sessionFile}, \texttt{inputFile}, \texttt{outputFile}: hold the necessary filenames; \item \texttt{moduleList}: holds a list of \texttt{Module} objects, created as requested by the user; \item \texttt{variableMap}: equivalent of \texttt{vm} variable from the original utility. \begin{itemize} \item \emph{TO-DO}: This variable map needs to be constructed from user input as it needs to be passed into \texttt{Process} method of \texttt{Module} class. \end{itemize} \end{itemize} \subsection{User workflow} The currently suggested user workflow is as follows: \begin{enumerate} \item Initialise an instance of \texttt{FieldConverter} class. \item Add a session file as well as an input and an output file. \begin{itemize} \item The converter will assert that the session file and the input file exist, assert that the file extensions are supported and create appropriate modules. \end{itemize} \item Add any modules, e.g. \texttt{vorticity}. \begin{itemize} \item Currently the argument passed into \texttt{addProcessModule} is a string containing the module name. \item \emph{TO-DO}: As mentioned before, it would be neater if said argument was an enum. \item \emph{TO-DO}: Some more thought is required about how to support modules requiring or permitting parameters. One solution would be to pass a tuple containing module name and parameters. Care needs to be taking in asserting the validity of parameters. \item As before, the converter will assert that the module exists and create an appropriate \texttt{Module} class object. \end{itemize} \item Run the conversion. \end{enumerate} The code showcasing the suggested workflow can be found in the main function of the \texttt{FieldConvert.py} file. \subsection{Conversion process} \section{Further development and improvement} \ No newline at end of file
 \chapter{Installing NekPy} NekPy has the following list of requirements: \begin{itemize} \item Boost with Python support \item Nektar++ \texttt{master} branch compiled from source (i.e. not from packages) \item Python 2.7+ (note that examples rely on Python 2.7) \item NumPy \end{itemize} Most of these can be installed using package managers on various operating systems, as we describe below. We also have a requirement on the \texttt{Boost.NumPy} package, which is available in Boost 1.63 or later. If this isn't found on your system, it will be automatically downloaded and compiled. \section{Compiling and installing Nektar++} Nektar++ should be compiled as per the user guide instructions and installed into a directory which we will refer to as \texttt{\$NEKDIR}. By default this is the \texttt{dist} directory inside the Nektar++ build directory. Note that Nektar++ must, at a minimum, be compiled with \texttt{NEKTAR\_BUILD\_LIBRARY}, \texttt{NEKTAR\_BUILD\_UTILITIES} , \texttt{NEKTAR\_BUILD\_SOLVERS} and \texttt{NEKTAR\_BUILD\_PYTHON}. This will automatically download and install \texttt{Boost.NumPy} if required. Note that all solvers may be disabled as long as the \texttt{NEKTAR\_BUILD\_SOLVERS} option is set. \subsection{macOS} \subsubsection{Homebrew} Users of Homebrew should make sure their installation is up-to-date with \texttt{brew upgrade}. Then run \begin{lstlisting}[language=bash] brew install python boost-python \end{lstlisting} To install the NumPy package, use the \texttt{pip} package manager: \begin{lstlisting}[language=bash] pip install numpy \end{lstlisting} \subsubsection{MacPorts} Users of MacPorts should sure their installation is up-to-date with \texttt{sudo port selfupdate \&\& sudo port upgrade outdated}. Then run \begin{lstlisting}[language=bash] sudo port install python27 py27-numpy sudo port select --set python python27 \end{lstlisting} \subsection{Linux: Ubuntu/Debian} Users of Debian and Ubuntu Linux systems should sure their installation is up-to-date with \texttt{sudo apt-get update \&\& sudo apt-get upgrade} \begin{lstlisting}[language=bash] sudo apt-get install libboost-python-dev python-numpy \end{lstlisting} \subsection{Compiling the wrappers} Run the following command in \path{$NEKDIR/build} directory to install the Python package for the current user: \begin{lstlisting}[language=bash] make nekpy-install-user \end{lstlisting} Alternatively, the following command can be used to install the package for all users: \begin{lstlisting}[language=bash] make nekpy-install-system \end{lstlisting} \section{Using the bindings} By default, the bindings will install into the \texttt{dist} directory, along with a number of examples that are stored in the \path{$NEKDIR/library/Demos/Python} directory. To test your installation, you can for example run one of these (e.g. \texttt{python Basis.py}) or launch an interactive session: \begin{lstlisting}[language=bash]$ cd builds $python Python 2.7.13 (default, Apr 4 2017, 08:47:57) [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from NekPy.LibUtilities import PointsKey, PointsType >>> PointsKey(10, PointsType.GaussLobattoLegendre) \end{lstlisting} \subsection{Examples} A number of examples of the wrappers can be found in the \path{$NEKDIR/library/Demos/Python} directory, along with a sample mesh \texttt{newsquare\_2x2.xml}: \begin{itemize} \item \texttt{SessionReader.py} is the simplest example and shows how to construct a session reader object. Run it as \texttt{python SessionReader.py mesh.xml}. \item \texttt{Basis.py} shows functionality of basic \texttt{LibUtilities} points and basis classes. Run this as \texttt{python Basis.py}. \item \texttt{StdProject.py} shows how to use some of the \texttt{StdRegions} wrappers and duplicates the functionality of \texttt{Basis.py} using the \texttt{StdExpansion} class. Run this as \texttt{python StdProject.py}. \item \texttt{MeshGraph.py} loads a mesh and prints out some basic properties of its quadrilateral elements. Run it as \texttt{python MeshGraph.py newsquare\_2x2.xml}. \end{itemize} If you want to modify the source files, it's advisable to edit them in the \path{\$NEKDIR/library/Demos/Python} directory and re-run \texttt{make install}, otherwise local changes will be overwritten by the next \texttt{make install}.
 \chapter{Introduction} This part of the guide contains the information on using and developing \texttt{NekPy} Python wrappers for the \nek{} spectral/\textit{hp} element framework. \emph{As a disclaimer, these wrappings are experimental and incomplete.} You should not rely on their current structure and API remaining unchanged. Currently, representative classes from the \texttt{LibUtilities}, \texttt{StdRegions}, \texttt{SpatialDomains}, \texttt{LocalRegions} and \texttt{MultiRegions} libraries have been wrapped in order to show the proof-of-concept. \section{Features and functionality} \texttt{NekPy} uses the \texttt{Boost.Python} library to provide a set of high-quality, hand-written Python bindings for selected functions and classes in Nektar++. It is worth noting that Python (CPython, the standard Python implementation written in C, in particular) includes C API and that everything in Python is strictly speaking a C structure called \texttt{PyObject}. Hence, defining a new class, method etc. in Python is in reality creating a new \texttt{PyObject} structure. Boost.Python is essentially a wrapper for Python C API which conveniently exports C++ classes and methods into \texttt{PyObjects}. At compilation time a dynamic library is created which is then imported to Python, as shown in Figure \ref{fig:boost_python}. \begin{figure}[h!] \centering \includegraphics[width=0.9\textwidth]{img/boost_python} \caption{A schematic diagram of how C++ code is converted into Python with Boost.Python \cite{C++Api}} \label{fig:boost_python} \end{figure} A typical snippet could look something like: \begin{lstlisting}[caption={NekPy sample snippet}, label={lst:nekpy_sample}, language=Python] from NekPy.LibUtilities import PointsKey, PointsType, BasisKey, BasisType from NekPy.StdRegions import StdQuadExp import numpy as np numModes = 8 numPts = 9 ptsKey = PointsKey(numPts, PointsType.GaussLobattoLegendre) basisKey = BasisKey(BasisType.Modified_A, numModes, ptsKey) quadExp = StdQuadExp(basisKey, basisKey) x, y = quadExp.GetCoords() fx = np.sin(x) * np.cos(y) proj = quadExp.FwdTrans(fx) \end{lstlisting} \texttt{NekPy} uses the \texttt{Boost.NumPy} library, contained in Boost 1.63+, to automatically convert C++ \texttt{Array} objects to and from the commonly-used \texttt{numpy.ndarray} object, which makes the integration more seamless between Python and C++. \ No newline at end of file
This diff is collapsed.
 \chapter{Package structure} The NekPy wrapper is designed to mimic the library structure of Nektar++, with directories for the \texttt{LibUtilities}, \texttt{SpatialDomains} and \texttt{StdRegions} libraries. This is a deliberate design decision, so that classes and definitions in Nektar++ can be easily located inside NekPy. There are also some other directories and files: \begin{itemize} \item \path{LibUtilities/Python/NekPyConfig.hpp} is a convenience header that all \texttt{.cpp} files should import. It sets appropriate namespaces for \texttt{boost::python} and \texttt{boost::python::numpy}, depending on whether the \texttt{Boost.NumPy} library was compiled or is included in Boost, \item \path{cmake/python} contains templates for \texttt{init.py} and \texttt{setup.py} files which every Python package should contain, \item \path{cmake/ThirdPartyPython.cmake} is a CMake configuration file which searches for \texttt{Boost.Python} and prepares \texttt{make} targets for installing NekPy. \end{itemize} Figure \ref{fig:package_str} shows the location of Python wrapper files within Nektar++ structure. Every sub-module of Nektar++ hosts an additional folder for Python files and the structure of the Python folder mimics the structure of the sub-module itself, as shown on the left of the figure with \texttt{LibUtilities} sub-module. Individual \texttt{.cpp} files, such as \texttt{Expansion.cpp} contain the wrappers for classes and methods from corresponding Nektar++ library files whereas \texttt{.cpp} files named after sub-modules (e.g. \texttt{LibUtilities.cpp}) contain \texttt{BOOST\_PYTHON\_MODULE} definitions which create package modules (e.g. \texttt{NekPy.LibUtilities}). \begin{figure}[h!] \centering \includegraphics[width=0.9\textwidth]{img/package_str} \caption{The location of Python wrapper files within Nektar++ structure.} \label{fig:package_str} \end{figure} \ No newline at end of file
This diff is collapsed.
 \input{nekpy_introduction.tex} \input{nekpy_installation.tex} \input{nekpy_structure.tex} \input{nekpy_wrapping.tex} \input{nekpy_documentation.tex} \input{nekpy_memory_management.tex} \input{nekpy_fieldconvert.tex} \ No newline at end of file
 ... ... @@ -21,6 +21,8 @@ openany, % A chapter may start on either a recto or verso page. \usepackage{lmodern} \usepackage[english]{babel} % English please \usepackage[final]{microtype} % Less badboxes \usepackage[stable]{footmisc} % Footnotes in section titles \usepackage{url} % \usepackage{kpfonts} %Font ... ... @@ -30,6 +32,7 @@ openany, % A chapter may start on either a recto or verso page. \usepackage{graphicx} % Include figures \usepackage{makeidx} \usepackage{import} \usepackage{subcaption} %%% PAGE LAYOUT %%%----------------------------------------------------------------------------- ... ... @@ -89,8 +92,9 @@ openany, % A chapter may start on either a recto or verso page. \captionnamefont{\small\bfseries} % Font of the caption name \captiontitlefont{\small\normalfont} % Font of the caption text \changecaptionwidth % Change the width of the caption \captionwidth{1\textwidth} % % incompatible with subcaption package so commented out for now %\changecaptionwidth % Change the width of the caption %\captionwidth{1\textwidth} % %%% ABSTRACT %%%------------------------------------------------------------------------------ ... ... @@ -172,6 +176,9 @@ openany, % A chapter may start on either a recto or verso page. \usepackage{listings} % Display code / shell commands \usepackage{lstautogobble} %\newcommand{\shellcommand}[1]{\begin{lstlisting} \#1 \end{lstlisting} \lstset{ breaklines=true } \lstdefinestyle{BashInputStyle}{ language=bash, basicstyle=\small\ttfamily, ... ... @@ -184,6 +191,7 @@ openany, % A chapter may start on either a recto or verso page. linewidth=0.95\linewidth, xleftmargin=0.05\linewidth, keepspaces=true, breaklines=true, framesep=5pt, rulecolor=\color{black!30}, aboveskip=10pt, ... ... @@ -206,7 +214,8 @@ openany, % A chapter may start on either a recto or verso page. morecomment=[s]{}, commentstyle=\color{gray}, stringstyle=\color{orange}, identifierstyle=\color{darkblue} identifierstyle=\color{darkblue}, breaklines=true } \lstdefinestyle{XMLStyle}{ language=XML, ... ... @@ -218,7 +227,8 @@ openany, % A chapter may start on either a recto or verso page. columns=fullflexible, backgroundcolor=\color{black!05}, linewidth=0.95\linewidth, xleftmargin=0.05\linewidth xleftmargin=0.05\linewidth, breaklines=true } \lstdefinestyle{C++Style}{ language=C++, ... ... @@ -232,7 +242,8 @@ openany, % A chapter may start on either a recto or verso page. linewidth=0.9\linewidth, xleftmargin=0.1\linewidth, showspaces=false, showstringspaces=false showstringspaces=false, breaklines=true } \ifdefined\HCode ... ...