c
|
Makefile,
atom.c,
atom.h,
bond.c,
bond.h,
debug.h,
getword.c,
getword.h,
group.c,
group.h,
main.c,
menu.c,
term.c,
term.h,
|
|
|
/*
* Groups of atoms, and interesting operations on them
*/
#include
#include
#include "atom.h"
#include "bond.h"
#include "term.h"
#include "group.h"
void
init_group (group * g)
{
g->atom_count = g->bond_count = g->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
add_atom (group * g, atom * a)
{
if (g->atom_count < MAX_NUM_ATOMS)
g->atoms[g->atom_count++] = a;
else
fprintf (stderr, "Too many atoms\n");
}
void
add_bond (group * g, bond * b)
{
if (g->bond_count < MAX_NUM_BONDS)
g->bonds[g->bond_count++] = b;
else
fprintf (stderr, "Too many bonds\n");
}
void
add_term (group * g, term * t)
{
if (g->term_count < MAX_NUM_TERMS)
g->terms[g->term_count++] = t;
else
fprintf (stderr, "Too many terms\n");
}
atom *
choose_atom (group * g, int index)
{
return g->atoms[index];
}
bond *
choose_bond (group * g, int index)
{
return g->bonds[index];
}
term *
choose_term (group * g, int index)
{
return g->terms[index];
}
double
energy (group * g)
{
double e;
int i;
for (i = 0, e = 0.0; i < g->atom_count; i++)
e += kinetic_energy (g->atoms[i]);
for (i = 0; i < g->term_count; i++)
e += term_energy (g->terms[i]);
return e;
}
void
physics_time_step (group * g, double dt)
{
int i;
for (i = 0; i < g->atom_count; i++)
{
iterate_motion (g->atoms[i], dt);
g->atoms[i]->f[0] = g->atoms[i]->f[1] = g->atoms[i]->f[2] = 0.0;
}
for (i = 0; i < g->term_count; i++)
{
term_add_forces (g->terms[i]);
}
}
void
select_subgroup (group * g, group * selected,
int (*selector) (atom * atm, int index))
{
int i;
for (i = 0; i < g->atom_count; i++)
if ((*selector) (g->atoms[i], i))
add_atom (selected, g->atoms[i]);
}
void
apply_to_atoms (group * g, int (*do_this) (atom * a))
{
int i;
for (i = 0; i < g->atom_count; i++)
(*do_this) (g->atoms[i]);
}
void
apply_to_terms (group * g, int (*do_this) (term * t))
{
int i;
for (i = 0; i < g->term_count; i++)
(*do_this) (g->terms[i]);
}
#define THRESH 1.8 /* maximum bond length in angstroms */
#define THRESH_SQ (THRESH * THRESH)
void
infer_bonds_from_distances (group * g)
{
int i, j;
atom *p, *q;
double diff, dsq;
for (i = 0; i < g->bond_count; i++)
free (g->bonds[i]);
g->bond_count = 0;
for (i = 0; i < g->bond_count; i++)
{
p = g->atoms[i];
for (j = i + 1; j < g->bond_count; j++)
{
q = g->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)
{
bond *b;
b = malloc (sizeof (bond));
b->first = i;
b->second = j;
g->bonds[g->bond_count++] = b;
}
}
}
}
|