def ra_diff(a, b):
    """Return molecular acceleration difference.
    """
    return VecR(a.ra.x - b.ra.x, a.ra.y - b.ra.y, a.ra.z - b.ra.z)
예제 #2
0
def ComputeForces():
    """Compute the MD forces by evaluating the LJ potential
       using cells subdivisions. The simulation area, i.e., region,
       is divided into a lattice of small cells and the cell edges all exceed
       rcut. For this implementation:
           rca = La/Lca, where Lca = FLOOR(La/rcut) (a = x, y, z), and La is
       simulation box length in the a direction (region).

           +---------------------------------------------+
           |          |                       |          |
           |       -1 | 0                Lcx-1|Lcx       |
           |      +---+---+---+---+---+---+---+---+      |
           |      |   |                       |   |      |
           +------+---+---+---+---+---+---+---+---+------+
    """
    cc: VecI = None
    m1v: VecI = None
    m2v: VecI = None
    # Mapping from cell vector to list index (column-major order):
    #     (c.z * cells.y + c.y) * cells.x + c.x
    #
    # With cells = VecI(3, 3, 3), list indices are:
    vOff = [
        VecI(0, 0, 0),  # (0 * 3 + 0) * 3 + 0 -> 0
        VecI(1, 0, 0),  # (0 * 3 + 0) * 3 + 1 -> 1
        VecI(1, 1, 0),  # (0 * 3 + 1) * 3 + 1 -> 4
        VecI(0, 1, 0),  # (0 * 3 + 1) * 3 + 0 -> 3
        VecI(-1, 1, 0),  # (0 * 3 + 1) * 3 - 1 -> 2
        VecI(0, 0, 1),  # (1 * 3 + 0) * 3 + 0 -> 9
        VecI(1, 0, 1),  # (1 * 3 + 0) * 3 + 1 -> 10
        VecI(1, 1, 1),  # (1 * 3 + 1) * 3 + 1 -> 13
        VecI(0, 1, 1),  # (1 * 3 + 1) * 3 + 0 -> 12
        VecI(-1, 1, 1),  # (1 * 3 + 1) * 3 - 1 -> 11
        VecI(-1, 0, 1),  # (1 * 3 + 0) * 3 - 1 -> 8
        VecI(-1, -1, 1),  # (1 * 3 - 1) * 3 - 1 -> 5
        VecI(0, -1, 1),  # (1 * 3 - 1) * 3 + 0 -> 6
        VecI(1, -1, 1),  # (1 * 3 - 1) * 3 + 1 -> 7
    ]
    c: int = 0
    j1: int = 0
    j2: int = 0

    fcVal: float = 0.
    uVal: float = 0.
    rr: float = 0.
    rrCut: float = 0.
    rri: float = 0.
    rri3: float = 0.

    cells = _mdsim_globals['cells']
    cellList = _mdsim_globals['cellList']
    nCells = cells.vol()

    mol = _mdsim_globals['mol']
    nMol = _mdsim_globals['nMol']
    region = _mdsim_globals['region']
    rrCut = _mdsim_globals['rCut'] * _mdsim_globals['rCut']

    invWid: VecR = cells / region
    for n in range(nMol, nMol + nCells):
        cellList[n] = -1

    for n in range(nMol):
        rs = mol[n].r + (0.5 * region)
        cc = VecI(rs.x * invWid.x, rs.y * invWid.y, rs.z * invWid.z)
        c = cc.vc_to_list_index(cells) + nMol
        cellList[n] = cellList[c]
        cellList[c] = n

    for m in mol:
        m.ra_zero()

    _mdsim_globals['uSum'] = 0.
    _mdsim_globals['virSum'] = 0.

    # Compute cells interactions
    shift = VecR()
    for m1z in range(cells.z):
        for m1y in range(cells.y):
            for m1x in range(cells.x):
                """Vector cell index to which this molecule belongs."""
                m1v = VecI(m1x, m1y, m1z)
                """Translate vector cell index, m1v, to cell list index."""
                m1 = m1v.vc_to_list_index(cells) + nMol
                for offset in range(N_OFFSET):
                    """Vector cell relative to m1v."""
                    m2v = m1v + vOff[offset]
                    """ Periodic boundary-conditions/shift coordinates."""
                    shift.zero()
                    _VCell_wrap_all(m2v, cells, shift, region)
                    """Translate vector cell index, m2v, to cell list index."""
                    m2 = m2v.vc_to_list_index(cells) + nMol
                    j1 = cellList[m1]
                    while j1 >= 0:
                        j2 = cellList[m2]
                        while j2 >= 0:
                            if m1 != m2 or j2 < j1:
                                a = mol[j1]
                                b = mol[j2]
                                dr = a.r_diff(b)
                                dr -= shift
                                rr = vecr_dot(dr, dr)
                                if rr < rrCut:
                                    rri = 1. / rr
                                    rri3 = rri**3
                                    fcVal = 48.0 * rri3 * (rri3 - 0.5) * rri
                                    uVal = 4. * rri3 * (rri3 - 1.) + 1.

                                    # Molecule at: j1
                                    a.ra_sadd(fcVal, dr)
                                    # Molecule at: j2
                                    b.ra_sadd(-fcVal, dr)

                                    _mdsim_globals['uSum'] += uVal
                                    _mdsim_globals['virSum'] += fcVal * rr
                            j2 = cellList[j2]
                        j1 = cellList[j1]
def rv_diff(a, b):
    """Return molecular velocity difference.
    """
    return VecR(a.rv.x - b.rv.x, a.rv.y - b.rv.y, a.rv.z - b.rv.z)