The AMUSE architecture is based on a layered design with 3 layers. The highest layer is a python script, written for a single problem or set of problems. The next layer contains the AMUSE code, this layer provides a library of objects and function to use in the python script. The last layer contains all the existing or legacy codes. In this layer the physical models are implemented.
Each layer builds upon a lower layer, adding functionality or ease of use to the previous layer:
Each layer has a different role in the AMUSE architecture:
The following sections contain a detailed explanation of the layers, starting with the lowest layer to the highest. Some details are further worked out in other chapters or in the reference manual.
The Community Codes layer contains the actual applications and the functionality to communicate with these applications. This layer exposes every community code as a set of functions. These functions are grouped in one class per code.
The AMUSE framework code and the community codes are designed to be run as separate applications. The AMUSE framework code consists of a python script and the AMUSE library. The community codes consist of the original code-base of a scientific code extended with a new main application that handles messages send to it from the python library. Function calls into the community codes are send via a message passing framework to the actual running codes.
The number of applications started and the machines on which these run can all be set dynamically in AMUSE. Depending on the problem a researcher can run all of AMUSE on a single desktop computer or in a mixed environment with clusters of computers. Every AMUSE run starts with one python script. This script can in turn start a number of different community codes (as separate applications). A complete run can consist of multiple applications running in parallel or in sequence and managed by one python script.
The amuse framework interacts with legacy codes via a message passing framework. Function calls in the python scripts are translated to messages and these messages are send to the community codes using the message passing framework . The community codes wait for message events and will decode the message upon arrival and perform the requested function. The results will be send back using a similar message.
The Library layer is responsible for providing an object oriented interface to the community codes. It also provides extra functionality to help write a user script, such as file input and output of common file formats and unit conversions. These extra functionalities can be used independent of the community codes.
Every community code has a low-level interface (defined in the community interface layer) and an object-oriented interface. The low-level interface is defined as as set of functions. The object-oriented interface uses these functions and combines these with models for state-transitions, units and data sets to provide an interface that is easier to use (less error prone) and easier to couple with other codes.
The community codes of every module in all physical domains are modelled using the same template. The template consists of attributes and wrappers. Attributes provide a common interface for sub-parts of the code, for example the particles attribute provides an interface to add, update and remove the particles in a code. Attributes combine several functions in a legacy interface into one object. Wrappers are defined on top of the community functions and add functionality to existing methods. For example for every method the units of the arguments and return values can be defined in a filter. Wrappers add functionality to individual methods.
The template divides the interface object of a code into a number of attributes. Each attribute refers to an object implementing a specific sub-interface of the code. For example a code can have a parameter attribute, this attribute implements the ParameterSet sub-interface. The ParameterSet sub-interface defines how to interact with the parameters of a code (in this case each parameter can be set or queried from the set by name using normal python attribute access).
The template for all codes is divided into the following sub-interfaces:
Wrappers decorate a method. Wrappers can do pre- and post-processing of the arguments or decide if a method can savely be called.
The implementation of the object-oriented interface is based on the adaptor pattern. A Community Code Interface class is adapted to create a class which provides “parameters”, “particle sets/gridpoints” , “methods with units” , “properties with units” , “state control” and “Unit conversions for incompatible unit systems”. Each functionality has the same interface for all codes in the system.
The final layer is the User Script Layer this layer contains all the scripts written by a researcher for a specific problem or set of problems. These scripts are always written in python and can use all the functionality provided by the two lower layers in the AMUSE framework. The scripts don’t need to follow a fixed design.