Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 145 additions & 0 deletions doc/tutorial/adding_example_code_tidymess.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
.. _adding_example_code_tidymess:

Adding a C++ N-Body Code to AMUSE
=================================

In this tutorial, we will create an interface from scratch for the
TIdal DYnamics of Multi-body ExtraSolar Systems code, or ``TIDYMESS``,
written by Dr. Tjarda Boekholt and Dr. Alexandre Correia. This code
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a paper we can cite here?

implements detailed tidal forces into an N-body code to track the deformation
of bodies. This community code has already been implemented into AMUSE so you
can follow along this tutorial.

.. NOTE::

In this guide, ``TIDYMESS`` refers to the standalone simulation package,
while ``Tidymess`` refers to the ``TIDYMESS`` package inside of ``AMUSE``.


Getting Started
===============

This tutorial assumes you have a working amuse or amuse development build,
preferrably in seperated environment (virtualenv, venv or conda etc).
Comment thread
elkogerville marked this conversation as resolved.
Outdated
Please ensure that amuse is setup correctly, this can be verified by running the
Comment thread
elkogerville marked this conversation as resolved.
Outdated
``amusifier`` .

.. code-block:: bash

> amusifier --help

Naming our project
~~~~~~~~~~~~~~~~~~
Amuse naming conventions typically follows PascalCase, so we will name our project Tidymess.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a class name, and PEP-8 says they should be formatted like that. So nothing AMUSE-specific.


Creating the initial directory structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To start, we need to create the directory structure for ``Tidymess``, along with the
necessary files to build our interface. The fastest method to setup the directory is
by using the ``amusifier`` script with ``--mode=dir``.

Since ``TIDYMESS`` is a native C++ code with no other dependencies, we will specify
``--type=c``, but the ``amusifier`` can also build the interface directory for
``f90`` and ``python`` codes.

.. code-block:: bash

> amusifier --type=c --mode=dir Tidymess

Having run the ``amusifier``, we now have our new directory in ``amuse/src/amuse_tidymess``.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that depends. Did we move into amuse/src first?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, there are two options: inside AMUSE here, and stand-alone in any directory or a separate repository or whatever. But I think it would be best to explain the stand-alone option in a separate section at the end.

There should be all the required folders for building our interface, as well as a few code
stubs to expand upon.

Building the code
=================
Before we start working on the interface, we should try and install and compile ``TIDYMESS``
Comment thread
elkogerville marked this conversation as resolved.
Outdated
inside of ``AMUSE``.

Defining dependencies
~~~~~~~~~~~~~~~~~~~~~
The ``AMUSE`` build system needs to know what packages and libraries our project depends on.
Navigate to ``amuse_tidymess/packages/amuse_tidymess.amuse_deps``, which is where we define every
dependency we will need. By default it will look like:

.. code-block:: text

c c++ fortran java python cmake install download mpi openmp cuda opencl x11 opengl blas lapack gsl gmp mpfr fftw hdf5 netcdf4

Since ``TIDYMESS`` is a standalone C++ code, we can delete most of those and simplify our dependencies to:

.. code-block:: text

c c++
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually need c? The code is C++, and the bindings too, right? Or am I missing something again?


Setting up Autoconf
~~~~~~~~~~~~~~~~~~~
The ``amuse_deps`` file we just created informs the ``AMUSE`` build system about whether or not our
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove this first sentence, as it's repetitive and not very related to the rest of this paragraph. Instead, maybe add an instruction to the previous paragraph for the user to go to the top-level directory and run ./setup, so that they can see their code in the list?

package is buildable given the available compilers and libraries detected on your computer. We now need
to determine what compilers and libraries are on the system and how to use them. For this we will edit
the ``configure.ac`` file in ``amuse_tidymess/support/``. This file contains a set of macros which will
detect the tools and libraries needed to build our package. The template should contain all the macros
needed for our package, so its just a matter of deleting what we don't need. Delete any comment prefaced
with ``#####``, but only after following the direction of the comment.

Once ``configure.ac`` is setup correctly, we can edit ``config.mk.in``, and remove any unneeded variables
as well as any ``#####`` comment. This file is a template for ``config.mk``, which will contain a description
of all the compiler and library variables needed for our package.

Once these files are cleaned up, run ``autoreconf`` to (re)create the ``configure`` script, then run
``./configure``. This will test the detection and check for errors. As a sanity check, run ``cat config.mk``
and ensure that there are no ``@VARIABLE@`` symbols left! If there are, check that ``configure.ac`` and
``config.mk.in`` were setup correctly.

.. WARNING::

Make sure the the ``amuse_tidymess/support/shared/`` folder is a simlink to ``amuse/support/shared/``
Comment thread
elkogerville marked this conversation as resolved.
Outdated
to ensure that there is no code duplication in the codebase, and that bug fixes are propagated to each
package automatically. This should be done automatically by the ``amusifier`` but can be a source of bugs
if not setup correctly.

Setting up the Makefile
~~~~~~~~~~~~~~~~~~~~~~~
With our build system detection working, we now need to download ``TIDYMESS`` into ``AMUSE``!
This is where the Makefiles come in. ``AMUSE`` packages typically have 2 Makefiles.


Creating the Interfaces
=======================
With ``TIDYMESS`` compiled into ``AMUSE``, we can now begin the process of creating our interface!
The interface system allows community codes, which are all unique and depend on diverse libraries and
programming languages, to communicate with the ``AMUSE`` framework, which is native Python. ``AMUSE``
interfaces define a number of interface functions, which provide a standardized way for ``AMUSE`` to
communicate with each community code. This way, the experience of using any ``AMUSE`` code is identical:
all codes can be evolved with the ``evolve_model`` method, particles are represented as
``amuse.datamodel.particles``, etc... The strength of ``AMUSE`` lies in its ability to prototype quickly:
If the user wants to see what solution a different code would give for the same calculation, all they have
to do is switch which code they are using, and the script most likely does not need to change.

Therefore, our job when creating an interface is to map the community code functions to the ``AMUSE`` interface
functions. The amusifier already created all the files we need: the ``interface.py`` and the ``interface.cc``.

Defining the Python interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``interface.py`` actually defines two classes: the high-level and low-level Python interfaces. The high-level
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph could use some work. Maybe instead of "high-level" and "low-level" we could call it the Python interface and the native interface? That's a bit more descriptive (although that term native may also not be well-known, hmm). It's not explained what the low-level interface does anyway.

As for the structure, this mixes explanation of concepts, a practical description of what the amusifier does, and the next step to do. I think it's better to 1) briefly introduce the structure (two interfaces, user calls Python interface, which is handled by AMUSE and results in a call to the native interface, which calls the code or accesses data), then 2) in the next paragraph explain that the first step is making the Python interface, introduce the concept of standard interfaces, and then 3) we get to the practical side and we can mention that there's a stub for interface.py already there.

interface is what the user interacts with when using the community code. This defines the methods, parameters,
and properties of each community code, and defines how the ``amuse.datamodel.particles`` work within that code.
The ``amusifer`` generates a minimal code stub for the ``interface.py``, which is enough to get us started.
The process of defining our interface starts with figuring out what type of code we are adding to ``AMUSE``.
``AMUSE`` has a set of predefined Python interfaces we can use to build our interface from.


+----------------------------------+-------------------------------------------+
| Interface: | Example codes: |
+----------------------------------+-------------------------------------------+
| ``GravitationDynamicsInterface`` | N-body: Tidymess, Ph4, Huyano |
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Huayno", it's an Andean dance.

+----------------------------------+-------------------------------------------+
| ``HydrodynamicsInterface`` | Hydrodynamical: Capreole |
+----------------------------------+-------------------------------------------+
| ``MagnetoHydrodynamicsInterface``| MHD: Athena |
+----------------------------------+-------------------------------------------+
| ``StellarEvolutionInterface`` | Stellar: MESA, EVtwin, SeBa |
+----------------------------------+-------------------------------------------+

These interfaces define many
of the required interface functions so that we don't have to.
In this case, ``TIDYMESS`` is a N-Body code, and therefore falls under the
2 changes: 1 addition & 1 deletion doc/tutorial/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ Tutorials
legacy_code
plot
grid_boundary

adding_example_code_tidymess
Loading