From afbe790c374a437cbe54c501b12b7b5b25ad5400 Mon Sep 17 00:00:00 2001
From: Pascal Engeler <engelerp@phys.ethz.ch>
Date: Mon, 20 Jan 2020 17:23:21 +0100
Subject: [PATCH] Matrix element calculator docs

---
 README.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 57 insertions(+), 11 deletions(-)

diff --git a/README.md b/README.md
index 3577e04..a05e129 100644
--- a/README.md
+++ b/README.md
@@ -181,33 +181,79 @@ An example implementation of a `Coupler` is shown in `include/coupler_simple.hpp
      - Takes a `params_t`
      - Returns a pair that characterizes the generated lattice
        - a vector of drums `ds`
-       - an adjacency vector of vectors `adj`, such that `ds[i]` and `ds[adj[i]]` are neighbours
+       - an adjacency vector of vectors `adj`, such that `ds[i]` and `ds[adj[i][0]]` are neighbours
      - All drums have the same `params_t`, except that the `position` members differ.
 3. Description
+
 An example child of the `LatticeGenerator` is shown in the file `include/rbcomb_generator.hpp`.
+4. Further developments
+
+In the future, there may be another overload for the functional. For example, it could either take an
+`std::vector<params_t>` or an additional random number generator to construct the drums
+differently.
+5. Dependents
+   - None
+6. Typical dependencies
+   - `params_t`
+     - Existence of `position` member
 
+#### Neighbour ordering convention
 An important note is the __convention of neighbour ordering__. Each drum has neighbours 0 thru 3.
 For drums in different sublattices, these neighbours are:
 - Sublattice 'A':
-  - 0, adj[0]: straight down
-  - 1, adj[1]: top left
-  - 2, adj[2]: top right
+  - 0, `adj[0]`: straight down
+  - 1, `adj[1]`: top left
+  - 2, `adj[2]`: top right
 - Sublattice 'B':
-  - 0, adj[0]: straight up
-  - 1, adj[1]: bottom right
-  - 2, adj[2]: bottom left
+  - 0, `adj[0]`: straight up
+  - 1, `adj[1]`: bottom right
+  - 2, `adj[2]`: bottom left
 Here _adj[]_ signifies the adjacency list of the given drum. Similarly, the couplings
 _t0_ thru _t2_ in objects of type `params_t` should also respect this ordering. More
 generally, whenever neighbours of a specific drum are ordered in some fashion, they
 are assumed to respect the above convention. Note that with this convention,
 neighbours see each other as the same neighbour index (the i-th neighbour of j
   sees j as its i-th neighbour). __Never violate this convention__.
-4. Further developments
-In the future, there may be another overload for the functional. For example, it could either take an
-`std::vector<params_t>` or an additional random number generator to construct the drums
-differently.
 
+#### Inexistent neighbour convention
+Another __convention__ concerns __inexistent neighbours__. For that purpose, this class should append
+an auxiliary drum to the end of the drum vector. If neighbour i of a drum does not exist
+(due to boundary, for example), the corresponding neighbour index will point to the
+auxiliary drum, i.e. it will show an index `drum_vec.size()`. All couplings of this auxiliary
+drum are to be kept at 0. This condition can then be applied in force calculation to avoid branching,
+if one uses the couplings of the neighbours instead of the considered drum.
+
+### Interface template `MatrixElementCalculator` (matrix_element_calculator.hpp), calculates matrix elements
+1. Template arguments
+   - `value_t`: Scalar type
+   - `params_t`: Drum parameters type
+   - `vars_t`: Drum variables type
+   - `drum_t`: Drum type
+2. Virtual functions
+   - `value_t operator()(size_t index, std::vector<drum_t>)`
+     - Returns the diagonal element (index, index).
+   - `value_t operator()(size_t index1, size_t index2, std::vector<drum_t>)`
+     - Returns the coupling element (index1, index2), where these are each others neighbour 0
+   - `value_t operator()(size_t index1, size_t index2, std::vector<drum_t>, int)`
+     - Returns the coupling element (index1, index2), where these are each others neighbour 1
+   - `value_t operator()(size_t index1, size_t index2, std::vector<drum_t>, int, int)`
+     - Returns the coupling element (index1, index2), where these are each others neighbour 2
+3. Description
+
+The overload of the functional is done to avoid branching. When building the matrix, one calls
+the individual functions correctly to accomodate the correct neighbours.
 
+4. Dependents
+   - `System`
+     - Existence of the virtual functions
+5. Typical dependencies
+   - `params_t`
+     - Class semantics
+   - `vars_t`
+     - Class semantics
+   - `drum_t`
+     - `get_parameters()`
+     - `get_variables()`
 
 ### Template Type `Rk4Stepper` (rk4_stepper.hpp), performs timesteps using rk4 scheme
 1. Template arguments
-- 
GitLab