Skip to content

structure overview

ocekmer edited this page Jan 13, 2021 · 18 revisions

Repository layout

  • contrib holds third party libraries required by the project. These include things like Catch2, Clara, and a locally-built BLAS/Lapack if requested by the user at configure time.
  • src holds all of the component file triads, as well as the main.cpp that defines main() for the ASGarD binary.
  • testing contains support files for code testing, including the data files holding golden values for comparison, the matlab scripts to generate the golden values, and any global auxiliary functions needed for testing.
  • build this directory is not tracked in the repo, but is where the code expects to be built. This restriction will be lifted in the future to support out-of-tree builds (see https://github.com/project-asgard/asgard/issues/34).

Component-based structure

Components are just a convention for the physical organization of the code. It allows a summary of the overall structure of the code, while providing clean boundaries between units of related functionality. A "component" in this context is a logical grouping of code of very closely related functionality, and they are typically fairly small.

A component named "foo" is defined by three files:

  1. foo.cpp - the implementation of the component
  2. foo.hpp - the interface of the component
  3. foo_tests.cpp - all unit tests associated with the component

component.cpp files

The internal implementation of the component, including any explicitly instantiated templates that are needed.

  • first line is always the #include for the component's own header, followed by a blank line (so that clang-format does not reorder into the list of the remaining #includes)

  • remaining #includes are listed together with no blank lines, and clang-format will reorder them as necessary.

  • any necessary explicit template instantiations come at the very bottom of the file.

component.hpp header files

The interface of the component, included exported template specializations via extern template.

  • first line is #pragma once

  • The component header should only #include what is needed to define the interface. The implementation (.cpp) file will take care of its own #includes.

  • any necessary extern template declarations come at the very bottom of the header.

component_tests.cpp files

Holds all (and only) unit tests of the component contained in Catch TEST_CASE(){} blocks.

adding new components to the project

Having components makes adding new code to the CMake system fairly straightforward. There is a list of all components defined via set (components ..., which among other things allows the source files to be added and the tests to be built, all automatically.

To add a new component:

  1. ensure that the component named "foo" consists of exactly three files in the top-level of the src/ directory named foo.hpp, foo.cpp, and foo_tests.cpp.
  2. add the component name to the component list, in alphabetical order.
  3. add a target_link_libraries entry for the component (again, alphabetically), defining its private/public/interface relations to other components.
  4. if the component is directly used by the main.cpp file, then add the component name to the link list defined by set (main_app_link_deps ...)

Structural overview

generated with:

$ cmake .. --graphviz=struct.dot
$ dot -Tpng struct.dot.asgard -o asgard_structure.png

UML Class diagrams

Unified Modeling Language (UML) Class diagrams were prepared to analyze the structures of the classes used in ASGarD. The diagram shows the name of the class on top, class members (attributes) below that, and class member functions (methods) at the bottom. +, and - indicate public, and private access specifiers, respectively. These diagrams were created and can be edited using LibreOffice Vanilla, and these editable files have .odg extensions.

distribution

The class diagrams of the classes in distribution.hpp are as follows.

pde

The class diagrams of the classes in pde/pde_base.hpp are as follows.

The diagrams below are three examples for the other classes in pde for PDE_continuity, PDE_diffusion, and PDE_fokkerplanck, respectively.