CCL Home Page
Up Directory CCL group.C
/*
 *  Groups of atoms, and interesting operations on them
 */

#include 

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

group::group ()
{
  atom_count = bond_count = term_count = 0;
}

/* Everything that follows assumes that atoms, bonds, and terms are 
 * allocated in static arrays. Some day I'll do something more clever
 * than that, and all this code will need to be rewritten.
 */

void group::
add_atom (atom * a)
{
  if (atom_count < MAX_NUM_ATOMS)
    atoms[atom_count++] = a;
  else
    cerr << "Too many atoms" << endl;
}

void group::
add_bond (bond * b)
{
  if (bond_count < MAX_NUM_BONDS)
    bonds[bond_count++] = b;
  else
    cerr << "Too many bonds" << endl;
}

void group::
add_term (term * t)
{
  if (term_count < MAX_NUM_TERMS)
    terms[term_count++] = t;
  else
    cerr << "Too many terms" << endl;
}

atom *group::
choose_atom (int index)
{
  return atoms[index];
}

bond *group::
choose_bond (int index)
{
  return bonds[index];
}

term *group::
choose_term (int index)
{
  return terms[index];
}

double group::
energy ()
{
  double e;
  int i;
  
  for (i = 0, e = 0.0; i < atom_count; i++)
    e += atoms[i]->kinetic_energy ();
  for (i = 0; i < term_count; i++)
    e += terms[i]->energy_function ();
  return e;
}

void group::
physics_time_step (double dt)
{
  int i;
  
  for (i = 0; i < atom_count; i++)
    {
      atoms[i]->iterate_motion (dt);
      atoms[i]->f[0] = atoms[i]->f[1] = atoms[i]->f[2] = 0.0;
    }
  for (i = 0; i < term_count; i++)
    {
      terms[i]->add_forces ();
    }
}

void group::
select_subgroup (group * selected,
		 int (*selector) (atom * atm, int index))
{
  int i;
  
  for (i = 0; i < atom_count; i++)
    if ((*selector) (atoms[i], i))
      selected->add_atom (atoms[i]);
}

void group::
apply_to_atoms (int (*do_this) (atom * a))
{
  int i;
  
  for (i = 0; i < atom_count; i++)
    (*do_this) (atoms[i]);
}

void group::
apply_to_terms (int (*do_this) (term * t))
{
  int i;
  
  for (i = 0; i < term_count; i++)
    (*do_this) (terms[i]);
}

#define THRESH  1.8		/* maximum bond length in angstroms */
#define THRESH_SQ  (THRESH * THRESH)

void group::
infer_bonds_from_distances ()
{
  int i, j;
  atom *p, *q;
  double diff, dsq;
  
  /* get rid of any existing bonds */
  for (i = 0; i < bond_count; i++)
    delete bonds[i];
  bond_count = 0;
  
  for (i = 0; i < bond_count; i++)
    {
      p = atoms[i];
      for (j = i + 1; j < bond_count; j++)
	{
	  q = atoms[j];
	  diff = p->x[0] - q->x[0];
	  dsq = diff * diff;
	  diff = p->x[1] - q->x[1];
	  dsq += diff * diff;
	  diff = p->x[2] - q->x[2];
	  dsq += diff * diff;
	  if (dsq <= THRESH_SQ)
	    bonds[bond_count++] = new bond (i, j);
	}
    }
}
Modified: Tue May 20 16:00:00 1997 GMT
Page accessed 3645 times since Sat Apr 17 22:46:19 1999 GMT