/*
* 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);
}
}
}
|