INF205 lab worksheet 3

Submit through Canvas by 14th March 2025.

We will continue working with the code from the previous worksheet. If you don't have one, or yours was not working, you can begin with the shared-library.zip example (but put it back together as a standalone executable, without the use of a shared library).

If you do have a working code from the previous worksheet, it will make much more sense if you continue using that.

If you do this as group work (up to three group members are allowed), it is necessary to say for each problem on the worksheet what group member had the lead or main responsibility for that part, and every group member needs to be the lead on at least one of the problems 6, 7, 8, 9, or 10. Best submit a ZIP file with the code in a subdirectory and a PDF, odt, docx or similar document in the main directory. Do not include compiled files (object files *.o, or any executable binary files) in your submission; instead, preferably include a makefile so that your code can be compiled easily.

6. Configuration generator

For debugging and performance optimization, it will be useful for you to build your own configuration generator. Make it such that it takes the box size (for a cubic box), the density (number of molecules per unit volume), and a file name as command-line arguments. The generated file should contain the position coordinates of the configuration in XYZ format. The executable should be called genxyz, such that for example, the command

./genxyz 20 0.4 box20-density0.40-positions.xyz

generates a file similar to the shared example box20-density0.40-positions.xyz. There, the box size is a = 20 in each spatial direction, so that the volume is V = a3 = 8000. Since the density is given as ρ = 0.4, the number of molecules generated is N = ρV = 3200.

Make it so that the positions are randomized to some extent, while avoiding (for densities in a normal range) that the molecules are unnecessarily close to each other; this is to avoid that Epot becomes extremely large, which it would if the positions were completely random. You should be able to go up to ρ = 0.8 without producing configurations with completely unreasonably large energies, such as 1010 or greater. (It is not necessary to devise any very complicated schemes to achieve this.)

The box size should never be smaller than 5.

7. Periodic boundary conditions

Change readxyz such that its first command-line argument is the box size a, corresponding to a cubic box sized a × a × a, and implement periodic boundary conditions. This means that space is periodic: When leaving the box to the right, we reenter the same box from the left; when leaving upward, we find ourselves again at the bottom, etc. You can assume that the box size a is never smaller than 5.

In this periodic space, we can go different ways to reach one site from another, but the shortest distance counts; this is called the minimum image convention. So, for example, if a = 6, and there are two molecules with the coordinates (5 / 5 / 5) and (1 / 5 / 5), their distance is 2.0, and the distance vector from the first to the second is (2.0, 0.0, 0.0); this is because the shortest path from the first to the second one is through the boundary of the box to the right (positive x direction), coming back from the left (negative x) side.

If this is done correctly, running

./readxyz 6.0 5molecules-positions.xyz 5molecules-velocities.xyz

should produce the same result as last time:

E_kin = 3.75.
E_pot = -0.180826.
E_kin + E_pot = 3.56917.

However, the same configuration shifted by (-1.0, -1.0, -1.0) across the periodic boundaries of the box

./readxyz 6.0 5molecules-positions-shifted.xyz 5molecules-velocities.xyz

should now produce the same result as well.

The example with 3200 molecules

./readxyz 20.0 box20-density0.40-positions.xyz box20-density0.40-velocities.xyz

should result in:

E_kin = 1200.
E_pot = -6166.72.
E_kin + E_pot = -4966.72.

8. Linked cell data structure

Extend readxyz by an algorithm and data structure for computing Epot based on pre-sorting the molecules into subvolumes (cells). Since all the interactions are local, this improves the scaling of the code for large volumes: Each molecule interacts only with molecules from its own cell or cells in its vicinity; some cells will only contain molecules that are at a distance greater than the cutoff distance of 2.5, and therefore do not need to be traversed when looking for interaction partners of that molecule. This is called a linked cell data structure.

For example, if a = 20, it is possible to set up a grid of 8 × 8 × 8 cells, each of which covers a 2.5 × 2.5 × 2.5 subvolume. In that case, molecules that are not in the same or in directly adjacent cells do not interact, since their distance is always greater than the cutoff. Your algorithm should work correctly for any a ≥ 5, not just for multiples of 2.5.

Keep both the previous and the new implementation for computing Epot in your code, so that they can be compared. Validate that they produce the same result, using configurations generated using the code from problem 6.

9. Speedup due to the data structure

Use the <chrono> library to measure the speedup due to the new data structure ratio between the runtime of the two implementations for computing Epot. An example for runtime measurements using chrono is given in std-copy.cpp.

What speedup do you get when using 8 × 8 × 8 linked cells for the following example?

./readxyz 20.0 box20-density0.40-positions.xyz

Your code should include this in its output, e.g., comparable to the following:

# Linked cell 8 x 8 x 8 grid set up.
#
E_pot = -6166.72. (Using linked-cell data structure, taking 22.338 ms.)
E_pot = -6166.72. (Computed without using linked cells, taking 50.034 ms.)
#
Speedup factor from linked cells: 2.23986

Use the compiler flags -O2 -DNDEBUG when doing performance measurements.

10. Heuristic for data structure selection and parameterization

Do some performance measurements, varying a, ρ, and the number of cells, and implement a heuristic that predicts the best data structure and automatically selects and builds it at runtime. For small systems, it is best not to use a linked cell data structure at all, as that will be slower than just iterating over all pairs of molecules in the system.

Your implementation should run the computation of Epot using your recommended data structure and the direct iteration over pairs (without linked cells); it should still include the runtime and speedup measurements as introduced in problem 9.

Support course redesign by evaluating the course

Please fill in the anonymous course evaluation form (underveisevaluering). Based on this year's experience, the INF205 course will undergo a thorough redesign toward "asynchronous and remote learning as a default." Through the underveisevaluering, you can provide your advice as to how this should be carried out.

Index