@mainpage Accurate relaxation of a 2D crystal interacting with a quasicrystalline surface [TOC] # Abstract We investigate the energetic properties of a hexagonal 2D monolayer of colloidal particles interacting with a rigid decagonal quasicrystalline corrugation potential. Using classical molecular dynamics, we study the effectiveness and applicability of numerical optimization techniques to investigate the presence of an optimal angular orientation, following an extension of the Novaco-McTague theory. # Dependencies - A C compiler - Make - [Gnuplot](https://gnuplot.info) - [LAMMPS](https://lammps.org) - [Doxygen](https://doxygen.nl) for documentation - Coreutils (only tested with GNU coreutils, so the scripts may be reliant on non-standard flags) # Compiling The code complies with the C99 standard, it has been tested with GCC, but Clang (or any other C compiler for that matter) should also work. ```sh $ make # to compile $ make check # to compile and run tests ``` Some of the scripts depend on small utilities stored in the `bin/` directory, so add it to your path, to ease this you can simply source `environment.sh`: ```sh $ . ./environment.sh ``` ## Documentation To generate HTML documentation use [Doxygen](https://doxygen.nl): ```sh $ doxygen ``` This will populate the `html` directory with docs, open `html/index.html` in any web browser to browse them. ## Debugging If you want to change the code, or you find a bug, compile it like this to include debug symbols: ``` $ make DEBUG=1 ``` and run the programs with the highest log level (i.e. with the option `-l VERBOSE`). This will let you use a debugger (e.g. [gdb](https://gnu.org/software/gdb)), and will add source file and line information to all of the logging. This will also compile the code with the [Undefined Behavior Sanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html). If you want to enable the [Address Sanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) also add the variable `ASAN=1`. # Generating simulations To generate a simulation use the `simulation` program: ```sh $ simulation rotation simulation-directory ``` This will create subdirectories and create all of the necessary files, it should also generate an sbatch-compatible shell script, called *run.sh*, to run the simulation and collect the results. Note that you might want to modify the sbatch parameters. If you don't need to run under SLURM, then you can just run LAMMPS with the `*.in` files as inputs, like so: ```sh $ lmp -i lattice_r0.in ``` By default in rotation mode it will generate 60 simulation inputs, one for each angle from 0.0° to 6.0° every 0.1°. The program also collects some of the parameters in a file called METADATA, this might be useful when reviewing the results later. To explore the options run ```sh $ simulation -h ``` # Analyzing results Once simulations are over, you can analyze the results with the `analyze` program: ```sh $ analyze simulation-directory ``` Analyzing effectively means extracting the energies from the LAMMPS outputs and subtracting the initial values from the relaxed ones, the result of this is stored in 4 files: - **angles.energies** or **translation.energies**: relaxed - rigid (zJ) - **normalized.energies**: relaxed - rigid / Ntot (zJ) - **normalized_movable.energies**: relaxed - rigid / N (zJ) (excluding the fixed border from the normalization) - **rigid.energies** rigid energies (zJ) One of the most important invariants of the simulations is that it should be 2D, this requires multiple LAMMPS commands to achieve and is prone to error, therefore the `analyze` command accepts the `-e` switch to check the final results for out of plane z components i.e. ```sh $ ./analyze -e some-wrong-simulation [WARNING] some-wrong-simulation/conf_finale_r0_t0.data: non zero z component 44523 1 1 -104.40039562276402 -1155.2665943350287 0.04082829989134281 0 0 0 ~~~~^ Errors occurred, the analysis might not be complete. Good luck. ``` ## Expected energy profile To get the expected energy profile, as a function of the mismatch angle, run ``novaco_v1p0.py``, this will also store all of the q vectors (see Novaco Notes) used for the energy calculations in a file called `file_q.dat` so whenever gnuplot scripts refer to some `file_q-SOME_NAME.dat`, this is the file they expect. ## Gnuplot scripts Under `thesis/` there are a lot of gnuplot scripts I wrote to produce the plots I used in my thesis, a couple of them seem to be important enough to be worth explaining here. ### q vectors To plot the **q** vectors in the first Brillouin zone you can use the scripts under `thesis/qs`. Take [thesis/qs/qs-5.4.gp](../thesis/qs/qs-5.4.gp) as an example to make your own representation of the q vectors, this requires two files: - **file_q.dat**: which is the **q** vectors file generated by [novaco_v0p5.py](../novaco_v0p5.py), - **tauvectors.dat**: which is a file containing the 6 shortest vectors of the triangular lattice, used to plot the first Brillouin zone. ### Moiré pattern Scripts under `thesis/moire` are used to produce the colorful moiré patterns, see Fig. 12 in my thesis for an example. The most important script in that directory is [thesis/moire/generate-polar-displacements.sh](../thesis/moire/generate-polar-displacement.sh). In order to plot the moiré pattern you will need to setup a simulation that stores particle configurations both before and after the minization. It is important to have LAMMPS do this because it will reorder particles at the beginning of the simulation, but to be able to calculate displacements we need to rely on the fact that both files will have the same particle ordering. To setup a simulation e.g. at the optimal NM angle for apot = 5.4 µm, which is 5.3°, you may do something like this: ```sh $ . environment.sh # If you didn't already do this $ simulation r -f 5.3 -t 5.3 -m fire -d data/bigger.lmpdat -p 5.4 moire-5.3-apot-5.4 # 5.3 is ≈ the optimal angle ``` this will generate a single LAMMPs input under `moire-5.3-apot-5.4/lattice_r53.in` which you need to edit in order to have LAMMPS save the initial configuration, e.g. add this line before the `minimize` command: ``` write_data initial_something_something.data ``` Then run the simulation: ```sh $ cd moire-5.3-apot-5.4 $ lmp -i lattice-r53.in ``` Then copy the relevant files under `thesis/moire` and run [thesis/moire/generate-polar-displacement.sh](../thesis/moire/generate-polar-displacement.sh) like this: ```sh $ cd thesis/moire $ ./generate-polar-displacements.sh initial_something_something.data conf_finale.data novaco.dat > some-moire.dat ``` where `novaco.dat` refers to the output of [novaco_v1p0.py](../novaco_v1p0.py) for the same values of the parameters. `some-moire.dat` will contain the following columns: ``` # particle-type x y ux uy |u| angle ``` where `x` and `y` are the particle positions, `ux` and `uy` are the components of the displacement, `|u|` is the length of the displacement, `angle` is the angle with respect to the horizontal axis. The last step is to create a copy of one of the preexisting moire scripts, e.g. [thesis/moire/moire-5.4.gp](../thesis/moire/moire-5.4.gp), changing the variables that specify the input data; these scripts just include [thesis/moire/polar-color-dots.gp](../thesis/moire/polar-color-dots.gp) which does all of the heavy lifting, i.e. mapping displacements and angles to colors, finding the shortest q vector with [thesis/moire/min.sh](../thesis/moire/min.sh), and plotting a nice figure with a legend. All of this process assumes you want to look at the displacement pattern for the NM angle, if you don't, you will have to modify the scripts so that they accept the angle as a parameter rather than relying on the output of [novaco_v1p0.py](../novaco_v1p0.py) to find the NM angle. # License All of the programs I wrote are released under the terms of the GNU General Public License version 3, or any later version, see the `LICENSE` file for information. If the paternity of any of the files is unclear, [contact me](https://marioforzanini.com/contacts.html).