Ejemplo n.º 1
0
def calc_inertia_tensor(atom_iter):
    """Calculate moment of inertia tensor at the centroid
    of the atoms.
    """
    al = Structure.AtomList(atom_iter)
    centroid = al.calc_centroid()

    I = numpy.zeros((3, 3), float)
    for atm in al:
        x = atm.position - centroid

        I[0, 0] += x[1]**2 + x[2]**2
        I[1, 1] += x[0]**2 + x[2]**2
        I[2, 2] += x[0]**2 + x[1]**2

        I[0, 1] += -x[0] * x[1]
        I[1, 0] += -x[0] * x[1]

        I[0, 2] += -x[0] * x[2]
        I[2, 0] += -x[0] * x[2]

        I[1, 2] += -x[1] * x[2]
        I[2, 1] += -x[1] * x[2]

    evals, evecs = numpy.linalg.eig(I)

    elist = [(evals[0], evecs[0]), (evals[1], evecs[1]), (evals[2], evecs[2])]

    elist.sort()

    R = numpy.array((elist[0][1], elist[1][1], elist[2][1]), float)

    ## make sure the tensor uses a right-handed coordinate system
    if numpy.allclose(numpy.linalg.det(R), -1.0):
        I = numpy.identity(3, float)
        I[0, 0] = -1.0
        R = numpy.dot(I, R)
    assert numpy.allclose(numpy.linalg.det(R), 1.0)

    return centroid, R