/* * Groups of atoms, and interesting operations on them */ /* This is a cheesy way to do this and should be replaced, but it will do * for now, to place a limit on numbers of atoms, bonds, and terms, and * to declare arrays for them. Later I'll try to think of some more clever * arrangement so that these arrays can grow dynamically, and not have some * fundamental limit on their size. */ #define MAX_NUM_ATOMS 3000 #define MAX_NUM_BONDS 5000 #define MAX_NUM_TERMS 10000 typedef struct { atom *atoms[MAX_NUM_ATOMS]; bond *bonds[MAX_NUM_BONDS]; term *terms[MAX_NUM_TERMS]; int atom_count; int bond_count; int term_count; } group; extern void init_group (group * g); extern void add_atom (group * g, atom * a); extern void add_bond (group * g, bond * b); extern void add_term (group * g, term * t); extern atom *choose_atom (group * g, int index); extern bond *choose_bond (group * g, int index); extern term *choose_term (group * g, int index); /* total group energy is the sum of atoms' kinetic energies and terms' * potential energies. dampers dissipate energy and do not contribute * to this sum. */ extern double energy (group * g); /* iterate atom motions, zero atom forces, compute term forces for new * positions of atoms */ extern void physics_time_step (group * g, double dt); /* apply a test to all the atoms in this group, those that test * true are added to the 'selected' group. 'selector' should return * a boolean. */ extern void select_subgroup (group * g, group * selected, int (*selector) (atom * atm, int index)); extern void apply_to_atoms (group * g, int (*do_this) (atom * a)); extern void apply_to_terms (group * g, int (*do_this) (term * t)); /* this is a slow operation [O(n^2) in number of atoms] so don't * do this very often for large structures */ extern void infer_bonds_from_distances (group * g);