}
/* Update the anchor positions */
- if (count_anchors > 0) {
- Int *cp, n, j;
- Atom *ap2;
- ap = arena->mol->atoms;
- for (i = 0; i < natoms; i++, ap++) {
- if (ap->anchor == NULL)
- continue;
- cp = AtomConnectData(&ap->anchor->connect);
- n = ap->anchor->connect.count;
- VecZero(ap->r);
- for (j = 0; j < n; j++) {
- Double w = ap->anchor->coeffs[j];
- ap2 = arena->mol->atoms + cp[j];
- VecScaleInc(ap->r, ap2->r, w);
- }
- }
- }
+ if (count_anchors > 0)
+ MoleculeUpdatePiAnchorPositions(arena->mol);
/* Update the abnormal bond parameters */
if (arena->anbond_thres > 0.0) {
Double bk, w1, w2, w3, dump;
Double low, mid, high, low_energy, mid_energy, high_energy, lambda;
Double low_limit, high_limit;
- Int i, j, retval, natoms_movable;
+ Int i, j, retval, natoms_movable, nanchors;
Atom *atoms = arena->mol->atoms;
Atom *ap;
Int natoms = arena->mol->natoms;
w1 = w2 = 0.0;
retval = 0;
natoms_movable = 0;
+ nanchors = 0;
for (i = 0, ap = atoms, vp = arena->old_forces; i < natoms; i++, ap++, vp++) {
if (ap->fix_force < 0)
continue;
+ if (ap->anchor != NULL) {
+ nanchors++;
+ continue;
+ }
w1 += VecLength2(ap->f);
w2 += VecDot(ap->f, *vp);
natoms_movable++;
}
dump = sqrt(dump);
for (i = 0, ap = atoms, vp = arena->old_forces; i < natoms; i++, ap++, vp++) {
- if (ap->fix_force < 0)
+ if (ap->fix_force < 0 || ap->anchor != NULL)
continue;
*vp = ap->f;
*(vp + natoms) = ap->r;
if (w1 > w3)
w3 = w1;
}
+ if (nanchors > 0)
+ MoleculeUpdatePiAnchorPositions(arena->mol);
w3 = sqrt(w3);
arena->max_gradient = w3;
arena->v_len2 = w2;
high = lambda;
while (1) {
for (j = 0, ap = atoms, vp = arena->old_pos, vdr = arena->verlets_dr; j < natoms; j++, ap++, vp++, vdr++) {
- if (ap->fix_force < 0)
+ if (ap->fix_force < 0 || ap->anchor != NULL)
continue;
r = ap->r;
ap->r.x = vp->x + ap->v.x * lambda;
VecDec(r, ap->r);
VecInc(*vdr, r);
}
+ if (nanchors > 0)
+ MoleculeUpdatePiAnchorPositions(arena->mol);
calc_force(arena);
mid = lambda;
mid_energy = arena->total_energy;
/* Cannot find point with lower energy than the starting point */
/* Restore the original position */
for (j = 0, ap = atoms, vp = arena->old_pos, vdr = arena->verlets_dr; j < natoms; j++, ap++, vp++, vdr++) {
- if (ap->fix_force < 0)
+ if (ap->fix_force < 0 || ap->anchor != NULL)
continue;
r = ap->r;
ap->r = *vp;
VecDec(r, ap->r);
VecInc(*vdr, r);
}
+ if (nanchors > 0)
+ MoleculeUpdatePiAnchorPositions(arena->mol);
calc_force(arena);
lambda = 0.0;
if (bk == 0.0)
if (high - mid > mid - low) {
lambda = high - (high - mid) * phi;
for (j = 0, ap = atoms, vp = arena->old_pos, vdr = arena->verlets_dr; j < natoms; j++, ap++, vp++, vdr++) {
- if (ap->fix_force < 0)
+ if (ap->fix_force < 0 || ap->anchor != NULL)
continue;
r = ap->r;
ap->r.x = vp->x + ap->v.x * lambda;
VecDec(r, ap->r);
VecInc(*vdr, r);
}
+ if (nanchors > 0)
+ MoleculeUpdatePiAnchorPositions(arena->mol);
calc_force(arena);
if (arena->total_energy < mid_energy) {
low = mid;
} else {
lambda = mid - (mid - low) * phi;
for (j = 0, ap = atoms, vp = arena->old_pos, vdr = arena->verlets_dr; j < natoms; j++, ap++, vp++, vdr++) {
- if (ap->fix_force < 0)
+ if (ap->fix_force < 0 || ap->anchor != NULL)
continue;
r = ap->r;
ap->r.x = vp->x + ap->v.x * lambda;
VecDec(r, ap->r);
VecInc(*vdr, r);
}
+ if (nanchors > 0)
+ MoleculeUpdatePiAnchorPositions(arena->mol);
calc_force(arena);
if (arena->total_energy < mid_energy) {
high = mid;
#pragma mark ====== Pi Atoms ======
+static inline void
+sMoleculeCalculatePiAnchorPosition(Atom *ap, Atom *atoms)
+{
+ Int *cp, j, n;
+ Atom *ap2;
+ cp = AtomConnectData(&ap->anchor->connect);
+ n = ap->anchor->connect.count;
+ VecZero(ap->r);
+ for (j = 0; j < n; j++) {
+ Double w = ap->anchor->coeffs[j];
+ ap2 = ATOM_AT_INDEX(atoms, cp[j]);
+ VecScaleInc(ap->r, ap2->r, w);
+ }
+}
+
+void
+MoleculeUpdatePiAnchorPositions(Molecule *mol)
+{
+ Int i;
+ Atom *ap;
+ for (i = 0, ap = mol->atoms; i < mol->natoms; i++, ap = ATOM_NEXT(ap)) {
+ if (ap->anchor == NULL)
+ continue;
+ sMoleculeCalculatePiAnchorPosition(ap, mol->atoms);
+ }
+}
+
void
MoleculeCalculatePiAnchorPosition(Molecule *mol, int idx)
{
- Atom *ap, *ap2;
- Int i, n, *ip;
+ Atom *ap;
if (mol == NULL || idx < 0 || idx >= mol->natoms)
return;
ap = ATOM_AT_INDEX(mol->atoms, idx);
if (ap->anchor == NULL)
return;
- ip = AtomConnectData(&ap->anchor->connect);
- n = ap->anchor->connect.count;
- VecZero(ap->r);
- for (i = 0; i < ap->anchor->connect.count; i++) {
- ap2 = ATOM_AT_INDEX(mol->atoms, ip[i]);
- VecScaleInc(ap->r, ap2->r, ap->anchor->coeffs[i]);
- }
+ sMoleculeCalculatePiAnchorPosition(ap, mol->atoms);
}
int