CCL Home Page
Up Directory CCL menu
/* Here's an example where we link the libmol.a stuff to a little interpreter
 * of sorts. This understands the 'script' file.
 */

#include 

#include "atom.h"
#include "bond.h"
#include "term.h"
#include "group.h"

enum WHAT_TO_PRINT
{
  /* things that can be printed */
  TIME, TOTAL_ENERGY, ENERGY, POSITION, VELOCITY, FORCE, XYZ, NEWLINE
};

struct to_print
{
  enum WHAT_TO_PRINT token;
  int which_atom;
};

#define MAX_PRINTABLES 200
int num_printables = 0;
struct to_print printables[MAX_PRINTABLES];

group g;

int every_modulo = 1;
double dt, t;

enum SPECIES lookup_species (char *w)
{
  if (strcmp (w, "c-sp3") == 0) return C_SP3;
  if (strcmp (w, "c-sp2") == 0) return C_SP2;
  if (strcmp (w, "c-sp" ) == 0) return C_SP;
  if (strcmp (w, "h"    ) == 0) return H;
  if (strcmp (w, "n-sp3") == 0) return N_SP3;
  if (strcmp (w, "n-sp2") == 0) return N_SP2;
  if (strcmp (w, "n-sp" ) == 0) return N_SP;
  if (strcmp (w, "o-sp3") == 0) return O_SP3;
  if (strcmp (w, "o-sp2") == 0) return O_SP2;
  return C_SP3;
}

char *
element_name (enum SPECIES s)
{
  switch (s)
    {
    case C_SP3:
    case C_SP2:
    case C_SP:
      return "C";
    case N_SP3:
    case N_SP2:
    case N_SP:
      return "N";
    case O_SP3:
    case O_SP2:
      return "O";
    case H:
      return "H";
    }
  return "?";
}

/* The idea here is to print the kinds of XYZ frames that
 * Al Globus uses to make animations.
 */
void
print_xyz (void)
{
  int i;
  atom *a;

  cout << g.atom_count << endl;
  for (i = 0; i < g.atom_count; i++)
    {
      a = g.choose_atom (i);
      cout << element_name (a->species) << " "
	   << a->x[0] << " "
	   << a->x[1] << " "
	   << a->x[2] << endl;
    }
}

void printout (void)
{
  int i;
  atom *a;

  for (i = 0; i < num_printables; i++)
    {
      a = g.choose_atom (printables[i].which_atom);
      switch (printables[i].token)
	{
	case TIME:
	  cout << t << " ";
	  break;
	case TOTAL_ENERGY:
	  cout << g.energy() << " ";
	  break;
	case ENERGY:
	  cout << a->kinetic_energy() << " ";
	  break;
	case POSITION:
	  cout << "["
	       << a->x[0] << " "
	       << a->x[1] << " "
	       << a->x[2] << "] ";
	  break;
	case VELOCITY:
	  cout << "["
	       << a->v[0] << " "
	       << a->v[1] << " "
	       << a->v[2] << "] ";
	  break;
	case FORCE:
	  cout << "["
	       << a->f[0] << " "
	       << a->f[1] << " "
	       << a->f[2] << "] ";
	  break;
	case XYZ:
	  print_xyz ();
	  break;
	case NEWLINE:
	  cout << endl;
	  break;
	}
    }
}

int main (void)
{
  char word[200];

  while (cin >> word)
    {
      if (word[0] == '#')
	{
	  cin.getline (word, 200, '\n');
	}
      else if (strcmp (word, "atom") == 0)
	{
	  enum SPECIES s;
	  double ch, x, y, z;

	  cin >> word;
	  s = lookup_species (word);
	  cin >> ch >> x >> y >> z;
	  g.add_atom (new atom (s, ch, x, y, z));
	}
      else if (strcmp (word, "bond") == 0)
	{
	  int f, s;
	  cin >> f >> s;
	  g.add_bond (new bond(f, s));
	}
      else if (strcmp (word, "length") == 0)
	{
	  term *t;
	  int a1, a2;
	  cin >> a1 >> a2;
	  t = length_term (g.choose_atom (a1), g.choose_atom (a2));
	  g.add_term (t);
	}
      else if (strcmp (word, "angle") == 0)
	{
	  term *t;
	  int a1, a2, a3;
	  cin >> a1 >> a2 >> a3;
	  t = angle_term (g.choose_atom (a1), g.choose_atom (a2),
			  g.choose_atom (a3));
	  g.add_term (t);
	}
      else if (strcmp (word, "torsion") == 0)
	{
	  term *t;
	  int a1, a2, a3, a4;
	  cin >> a1 >> a2 >> a3 >> a4;
	  t = torsion_term (g.choose_atom (a1), g.choose_atom (a2),
			    g.choose_atom (a3), g.choose_atom (a4));
	  g.add_term (t);
	}
      else if (strcmp (word, "vdw") == 0)
	{
	  term *t;
	  int a1, a2;
	  cin >> a1 >> a2;
	  t = vdw_term (g.choose_atom (a1), g.choose_atom (a2));
	  g.add_term (t);
	}
      else if (strcmp (word, "electrostatic") == 0)
	{
	  term *t;
	  int a1, a2;
	  cin >> a1 >> a2;
	  t = electrostatic_term (g.choose_atom (a1), g.choose_atom (a2));
	  g.add_term (t);
	}
      else if (strcmp (word, "spring-damper") == 0)
	{
	  term *t;
	  int a1, a2;
	  double k, r0, d;
	  cin >> a1 >> a2 >> k >> r0 >> d;
	  t = spring_damper_term (g.choose_atom (a1), g.choose_atom (a2),
				  k, r0, d);
	  g.add_term (t);
	}
      else if (strcmp (word, "time-step") == 0)
	{
	  cin >> dt;
	}
      else if (strcmp (word, "every") == 0)
	{
	  cin >> every_modulo;
	}
      else if (strcmp (word, "run") == 0)
	{
	  int n;
	  double t0, t1;
	  cin >> t0 >> t1;
	  t1 += 0.5 * dt;
	  for (n = 0, t = t0; t < t1; t += dt, n++)
	    {
	      if ((n % every_modulo) == 0)
		printout ();
	      g.physics_time_step (dt);
	    }
	}
      else if (strcmp (word, "newline") == 0)
	{
	  printables[num_printables++].token = NEWLINE;
	}
      else if (strcmp (word, "print") == 0)
	{
	  struct to_print *p = &printables[num_printables++];
	  cin >> word;
	  if      (strcmp (word, "time") == 0)
	    {
	      p->token = TIME;
	    }
	  else if (strcmp (word, "total-energy") == 0)
	    {
	      p->token = TOTAL_ENERGY;
	    }
	  else if (strcmp (word, "energy") == 0)
	    {
	      p->token = ENERGY;
	      cin >> p->which_atom;
	    }
	  else if (strcmp (word, "position") == 0)
	    {
	      p->token = POSITION;
	      cin >> p->which_atom;
	    }
	  else if (strcmp (word, "velocity") == 0)
	    {
	      p->token = VELOCITY;
	      cin >> p->which_atom;
	    }
	  else if (strcmp (word, "force") == 0)
	    {
	      p->token = FORCE;
	      cin >> p->which_atom;
	    }
	  else if (strcmp (word, "xyz") == 0)
	    {
	      p->token = XYZ;
	    }
	  else if (strcmp (word, "newline") == 0)
	    {
	      p->token = NEWLINE;
	    }
	  else
	    {
	      cerr << "Bad print statement: " << word << endl;
	      num_printables--;
	    }
	}
      else cerr << "Bad command: " << word << endl;
    }
}
Modified: Wed May 21 16:00:00 1997 GMT
Page accessed 4223 times since Sat Apr 17 22:46:20 1999 GMT