/* Calculate the offset from the position of the center of mass */
Vector r = arena->fragment_info[n].pos;
TransformVec(&r, arena->mol->cell->rtr, &r);
- if (ap->symop.alive && ap->symop.sym > 0 && ap->symop.sym <= arena->mol->nsyms) {
+ if (ap->symop.alive && ap->symop.sym > 0 && ap->symop.sym < arena->mol->nsyms) {
/* The translational components of symop are not included */
- TransformVec(&r, arena->mol->syms[ap->symop.sym - 1], &r);
+ TransformVec(&r, SYMMETRY_AT_INDEX(arena->mol->syms, ap->symop.sym - 1), &r);
}
ap->wrap_dx = (arena->periodic_a ? -floor(r.x) : 0);
ap->wrap_dy = (arena->periodic_b ? -floor(r.y) : 0);
cell->axes[1].y = arena->old_cell_pars[4] + arena->cell_vels[4] * lambda;
cell->axes[1].z = arena->old_cell_pars[5] + arena->cell_vels[5] * lambda;
}
- if (arena->periodic_b) {
+ if (arena->periodic_c) {
cell->axes[2].x = arena->old_cell_pars[6] + arena->cell_vels[6] * lambda;
cell->axes[2].y = arena->old_cell_pars[7] + arena->cell_vels[7] * lambda;
cell->axes[2].z = arena->old_cell_pars[8] + arena->cell_vels[8] * lambda;
return 1; /* Gradient is sufficiently small */
/* Proceed along cell_vels[] until the energy increases */
- low_limit = arena->coordinate_convergence / arena->max_gradient;
- high_limit = 0.1 / arena->max_gradient;
+ low_limit = arena->coordinate_convergence / arena->cell_max_gradient;
+ high_limit = 0.1 / arena->cell_max_gradient;
low = 0.0;
low_energy = arena->total_energy;
lambda = high_limit;
rij2 = ATOM_AT_INDEX(arena->mol->atoms, ap2->symbase)->r;
else rij2 = ap2->r;
TransformVec(&rr, cell->rtr, &rij2);
- memmove(symtr, arena->mol->syms[ap2->symop.sym], sizeof(Transform));
+ memmove(symtr, SYMMETRY_AT_INDEX(arena->mol->syms, ap2->symop.sym), sizeof(Transform));
symtr[9] += ap2->symop.dx + vl->symop.dx;
symtr[10] += ap2->symop.dy + vl->symop.dy;
symtr[11] += ap2->symop.dz + vl->symop.dz;
ap = ATOM_AT_INDEX(mview->mol->atoms, ep->index);
an1 = ap->atomicNumber;
r1 = ap->r;
- trp = &(mview->mol->syms[ep->symop]);
+ trp = &(SYMMETRY_AT_INDEX(mview->mol->syms, ep->symop));
if (/* !mview->mol->is_xtal_coord && */ mview->mol->cell != NULL) {
TransformVec(&r1, mview->mol->cell->rtr, &r1);
TransformVec(&r1, *trp, &r1);
ap = ATOM_AT_INDEX(mview->mol->atoms, ep->index);
an[i] = ap->atomicNumber;
r[i] = ap->r;
- TransformVec(&r[i], mview->mol->syms[ep->symop], &r[i]);
+ TransformVec(&r[i], SYMMETRY_AT_INDEX(mview->mol->syms, ep->symop), &r[i]);
VecInc(r[i], ep->dr);
} else {
ap = ATOM_AT_INDEX(mview->mol->atoms, in);
memmove(mp2->cell, mp->cell, sizeof(XtalCell));
}
if (mp->nsyms > 0) {
- mp2->nsyms = mp->nsyms;
- mp2->syms = (Transform *)calloc(sizeof(Transform), mp2->nsyms);
+ NewArray(&(mp2->syms), &(mp2->nsyms), sizeof(Transform), mp->nsyms);
memmove(mp2->syms, mp->syms, sizeof(Transform) * mp2->nsyms);
}
mp2->useFlexibleCell = mp->useFlexibleCell;
Transform t;
if (mp == NULL || mp->cell == NULL)
return -1;
- if (symop.sym >= mp->nsyms)
+ if (symop.sym >= mp->nsyms && symop.sym != 0)
return -2;
- memmove(*tf, mp->syms[symop.sym], sizeof(Transform));
+ memmove(*tf, SYMMETRY_AT_INDEX(mp->syms, symop.sym), sizeof(Transform));
(*tf)[9] += symop.dx;
(*tf)[10] += symop.dy;
(*tf)[11] += symop.dz;
{
if (mp == NULL)
return 1;
- if (symop.sym >= mp->nsyms)
+ if (symop.sym >= mp->nsyms && symop.sym != 0)
return 2;
if (mp->cell != NULL /* && !mp->is_xtal_coord */) {
TransformVec(vpout, mp->cell->rtr, vpin);
- TransformVec(vpout, mp->syms[symop.sym], vpout);
+ TransformVec(vpout, SYMMETRY_AT_INDEX(mp->syms, symop.sym), vpout);
vpout->x += symop.dx;
vpout->y += symop.dy;
vpout->z += symop.dz;
TransformVec(vpout, mp->cell->tr, vpout);
} else {
- TransformVec(vpout, mp->syms[symop.sym], vpin);
+ TransformVec(vpout, SYMMETRY_AT_INDEX(mp->syms, symop.sym), vpin);
vpout->x += symop.dx;
vpout->y += symop.dy;
vpout->z += symop.dz;
memmove(ap->aniso, ap2->aniso, sizeof(Aniso));
return;
}
- memmove(t1, mp->syms[ap->symop.sym], sizeof(Transform));
+ memmove(t1, SYMMETRY_AT_INDEX(mp->syms, ap->symop.sym), sizeof(Transform));
t1[9] = t1[10] = t1[11] = 0.0;
memset(t2, 0, sizeof(Transform));
t2[0] = ap2->aniso->bij[0];
#define ATOM_PREV(p) ((Atom *)((char *)(p) - gSizeOfAtomRecord))
#define SYMOP_ALIVE(s) ((s.dx || s.dy || s.dz || s.sym) != 0)
#define SYMOP_EQUAL(s1, s2) (s1.dx == s2.dx && s1.dy == s2.dy && s1.dz == s2.dz && s1.sym == s2.sym)
+#define SYMMETRY_AT_INDEX(p, i) (*((i) == 0 ? &gIdentityTransform : &p[i]))
/* atom.connects is a union entry, including direct data for nconnects <= ATOM_CONNECTS_LIMIT
and malloc()'ed entry for nconnects > ATOM_CONNECTS_LIMIT. The following functions
return 0;
}
+Transform gIdentityTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0};
+
#pragma mark ==== LAMatrix ====
typedef struct LAMatrixTempRecord {
void **bp = (void *)base;
*bp = NULL;
*count = 0;
- return AssignArray(base, count, item_size, nitems - 1, NULL);
+ if (nitems > 0)
+ return AssignArray(base, count, item_size, nitems - 1, NULL);
+ else return NULL;
}
/* Insert items to an array. */
int TransformForReflection(Transform dst, const Vector *axis, const Vector *center);
int TransformForRotation(Transform dst, const Vector *axis, Double angle, const Vector *center);
+extern Transform gIdentityTransform;
+
/* Wrapper struct for CLAPACK routines */
typedef struct LAMatrix {
__CLPK_integer row, column;