/*-----------------------------anneal.c--------------------------------
  This program anneals carbon structures to their equilibrium positions
  using the Tersoff-Brenner potential.  The "annealing" is accomplished
  by alternating perturbations to the atomic coordinates and relaxation.
  It is not a realistic simulation of thermal effects, but just an
  energy minimization technique with the ability to jump out of small
  local minima. This software was written by Stephen Jordan.
  ---------------------------------------------------------------------*/

#include "abcio.h"               //for loadabc and saveabc
#include "cell.h"                //for the cell structure
#include "defs.h"                //for the defs structure
#include "diags.h"               //for the diags structure
#include "calculate.h"           //for calculate
#include "tbinit.h"              //for tbinit
#include "potential.h"           //for energy
#include "handy.h"               //for strip_path
#include <stdio.h>               //for sprintf, fopen, FILE
#include <stdlib.h>              //for EXIT_SUCCESS and EXIT_FAILURE
#include <string.h>              //for strchr and strcpy

//add random perturbations to the atomic coordinates
//the maximum perturbation is "distance" in Angstroms
void perturb(cell *C, double distance) {
  int i;
  double uniform;
  for(i = 0; i < 3*C->atoms; i++) {
    //uniformly distributed random variable from -1 to 1
    uniform = (2.0*(double)rand() - (double)RAND_MAX)/(double)RAND_MAX;
    C->x[i] += distance*uniform;
  }
}

void mk_stagename(int stage, char *outfile, char *stagename) {
  char prefix[16];
  char stage_str[16];
  int zeros, i;
  sprintf(stage_str, "%i", stage);
  zeros = 4 - strlen(stage_str); //hence 0000_whatever.abc etc.
  stagename[0] = '\0';
  for(i = 0; i < zeros; i++) strcat(stagename, "0");
  strcat(stagename, stage_str);
  strcat(stagename, "_A_");
  strcat(stagename, outfile);
}


int main(int argc, char *argv[]) {
  FILE *infile;
  FILE *outfile;
  char filename[256];
  char header[65536];
  int digits, i, j, stages;
  double tb_energy;
  cell C;
  defs d;
  diags dia;
  stages = 0;
  if(argc < 3) {
    printf("Usage: anneal stages filename.abc\n");
    return EXIT_FAILURE;
  }
  sscanf(argv[1], "%i", &stages);
  printf("stages = %i\n", stages);
  for(i = 2; i < argc; i++) {
      infile = fopen(argv[i], "r");
      if(infile == NULL) {
        printf("Unable to open %s\n", argv[i]);
        return EXIT_FAILURE;
      }
      strip_path(argv[i]);
      loadabc(infile, &C, 1);
      tbinit(&C, 1);  
      printf("atoms = %i\tbonds = %i\n", C.atoms, C.bonds);
      d.start  = 0;
      d.stop   = 0;
      d.offset = 0; 
      strcpy(d.infile, argv[i]);
      strcpy(d.outfile, filename);
      strcpy(d.datafile, "none");
      strcpy(d.logfile, "none");
      d.verbose = 0;
      d.digits = 9;
      d.automatic = 1;
      d.threshold = 1e-9;
      d.f_num = 0;
      d.tip = 0;
      for(j = 0; j < stages; j++) {
        printf("stage %i\n", j);
        perturb(&C, 0.05); 
        calculate(&C, &d, &dia, 0);
        tb_energy = energy(C.bond_array, C.bonds);
        printf("iterations = %i\tenergy = %f\n", dia.iter, tb_energy);
        find_neighb_i(&C); //keep bonds up to date
        makeheader(header, &d, &dia, 0);
        mk_stagename(j, argv[i], filename);
        outfile = fopen(filename, "w");
        if(outfile == NULL) {
          printf("Unable to create %s\n", filename);
          return EXIT_FAILURE;
        }
        saveabc(outfile, &C, header, digits, 0);
        fclose(outfile);
      }
      fclose(infile);
      destroy_cell(&C);
  }
  printf("Done.\n");
}







