/**
 * Initialize the link force algorithm and start simulation.
 */
function startLinkSimulation() {
  console.log("startLinkSimulation")
  springForce = false;
  alreadyRanIterations = 0;
  manualStop = true;
  simulation.stop();
  p1 = performance.now();
  let links = [], force;

  if (tweakedVerOfLink) {
    force = d3.forceLinkFullyConnected()
              .distance(function (n, m) {
                return distanceFunction(n, m, props, norm);
              });
  }
  else {
    for (i = nodes.length-1; i >= 1; i--) {
      for (j = i-1; j >= 0; j--) {
        links.push({
          source: nodes[i],
          target: nodes[j],
        });
      }
    }
    force = d3.forceLink()
              .distance(function (n) {
               return distanceFunction(n.source, n.target, props, norm);
              })
             .links(links);
  }

  /* Add force
   * Please add the distance function, links, and set simulation nodes
   *   before feeding the force to the simulation.
   *
   * On setting the distance fn or being initialized by the simulation, the
   *   force will pre-calculate high-dimensional distances of every link and
   *   store that as cache.
   * Adding distance fn and links before being initialize by the simulation
   *    means that the first pre-calculation will calculate noting as there was
   *    no nodes list.
   * The full pre-calculation will then occur once when the force is being
   *   initialized by the simulation where nodes list is given.
   */

  simulation
    .alphaDecay(0)
    .alpha(1)
    .on("tick", ticked)
    .on("end", ended)
    //.velocityDecay(0.8)
    .force(forceName,force)
    .restart();
}
