def InitAccels(): """Initialize the molecular accelerations """ mol = _mdsim_globals['mol'] for m in mol: m.ra = VecR() m.ra_zero() m.ra1 = VecR() m.ra2 = VecR()
def EvalProps(): """Evaluate thermodynamic properties """ density = _mdsim_globals['density'] deltaT = _mdsim_globals['deltaT'] mol = _mdsim_globals['mol'] nMol = _mdsim_globals['nMol'] uSum = _mdsim_globals['uSum'] virSum = _mdsim_globals['virSum'] vSum = VecR() vvMax : float = 0. vvSum : float = 0. for m in mol: rv_add(vSum, m) vv = rv_dot(m, m) vvSum += vv vvMax = max([vvMax, vv]) _mdsim_globals['dispHi'] += math.sqrt(vvMax) * deltaT if _mdsim_globals['dispHi'] > 0.5 * _mdsim_globals['rNebrShell']: _mdsim_globals['nebrNow'] = True _mdsim_globals['vSum'] = vSum _mdsim_globals['kinEnergy'].val = 0.5 * vvSum / nMol _mdsim_globals['totEnergy'].val = \ _mdsim_globals['kinEnergy'].val + uSum / nMol _mdsim_globals['pressure'].val = density * (vvSum + virSum) / (nMol * NDIM)
def SetParams(): density = _mdsim_globals['density'] initUcell = _mdsim_globals['initUcell'] nebrTabFac = _mdsim_globals['nebrTabFac'] rNebrShell = _mdsim_globals['rNebrShell'] rCut = math.pow(2., 1./6.) _mdsim_globals['rCut'] = rCut region =\ VecR(x=1. / math.pow(density, 1./3.) * initUcell.x, \ y=1. / math.pow(density, 1./3.) * initUcell.y, \ z=1. / math.pow(density, 1./3.) * initUcell.z) _mdsim_globals['region'] = region # The total number of molecules nMol = initUcell.x * initUcell.y * initUcell.z _mdsim_globals['nMol'] = nMol _mdsim_globals['velMag'] = \ math.sqrt(NDIM * (1. - 1. / nMol) * _mdsim_globals['temperature']) _mdsim_globals['cells'] = \ VecI(x=(1. / (rCut + rNebrShell)) * region.x, \ y=(1. / (rCut + rNebrShell)) * region.y, \ z=(1. / (rCut + rNebrShell)) * region.z) # The neighbor list size _mdsim_globals['nebrTabMax'] = nebrTabFac * nMol # Initialize kinEnery, pressure and totEnergy properties _mdsim_globals['kinEnergy'] = Prop() _mdsim_globals['pressure'] = Prop() _mdsim_globals['totEnergy'] = Prop()
def InitVels(): """Initialize the molecular velocities """ mol = _mdsim_globals['mol'] nMol = _mdsim_globals['nMol'] velMag = _mdsim_globals['velMag'] vSum = VecR(x=0., y=0., z=0.) for m in mol: m.rv = VecR() rv_rand(m) rv_scale(m, velMag) rv_add(vSum, m) _mdsim_globals['vSum'] = vSum # Scale molecular velocities for m in mol: rv_sadd(m, -1. / nMol, vSum)
def InitCoords(): """Initialize the molecular coordinates """ mol = _mdsim_globals['mol'] region = _mdsim_globals['region'] initUcell = _mdsim_globals['initUcell'] # gap = vecr_div(region, initUcell) gap = region / initUcell n = 0 for nz in range(initUcell.z): for ny in range(initUcell.y): for nx in range(initUcell.x): c = VecR(x=nx + 0.5, y=ny + 0.5, z=nz + 0.5) c *= gap c += (-0.5 * region) mol[n].r = c mol[n].ro = VecR() n += 1
def InitCoords(): """Initialize the molecular coordinates """ mol = _mdsim_globals['mol'] region = _mdsim_globals['region'] initUcell = _mdsim_globals['initUcell'] gap = vecr_div(region, initUcell) n = 0 for ny in range(initUcell.y): for nx in range(initUcell.x): c = VecR(x=nx + 0.5, y=ny + 0.5) c = vecr_mul(c, gap) c = vecr_sadd(c, -0.5, region) mol[n].r = c n += 1
def SetParams(): density = _mdsim_globals['density'] initUcell = _mdsim_globals['initUcell'] _mdsim_globals['rCut'] = math.pow(2., 1. / 6.) _mdsim_globals['region'] = \ VecR(x=1. / math.sqrt(density) * initUcell.x, \ y=1. / math.sqrt(density) * initUcell.y) # The total number of molecules nMol = initUcell.x * initUcell.y _mdsim_globals['nMol'] = nMol _mdsim_globals['velMag'] = \ math.sqrt(NDIM * (1. - 1. / nMol) * _mdsim_globals['temperature']) # Initialize kinEnery, pressure and totEnergy properties _mdsim_globals['kinEnergy'] = Prop() _mdsim_globals['pressure'] = Prop() _mdsim_globals['totEnergy'] = Prop()
def EvalProps(): """Evaluate thermodynamic properties """ density= _mdsim_globals['density'] mol = _mdsim_globals['mol'] nMol = _mdsim_globals['nMol'] uSum = _mdsim_globals['uSum'] virSum = _mdsim_globals['virSum'] vSum = VecR() vvSum : float = 0. for m in mol: rv_add(vSum, m) vvSum += rv_dot(m, m) _mdsim_globals['vSum'] = vSum _mdsim_globals['kinEnergy'].val = 0.5 * vvSum / nMol _mdsim_globals['totEnergy'].val = \ _mdsim_globals['kinEnergy'].val + uSum / nMol _mdsim_globals['pressure'].val = density * (vvSum + virSum) / (nMol * NDIM)
def BuildNebrList(): 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 cells = _mdsim_globals['cells'] cellList = _mdsim_globals['cellList'] nCells = cells.vol() mol = _mdsim_globals['mol'] nMol = _mdsim_globals['nMol'] rCut = _mdsim_globals['rCut'] region = _mdsim_globals['region'] rNebrShell = _mdsim_globals['rNebrShell'] nebrTab = _mdsim_globals['nebrTab'] nebrTabMax = _mdsim_globals['nebrTabMax'] rrNebr = (rCut + rNebrShell) * (rCut + rNebrShell) 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 _mdsim_globals['nebrTabLen'] = 0 rshift = 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.""" rshift.zero() _VCell_wrap_all(m2v, cells, rshift, 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 -= rshift rr = vecr_dot(dr, dr) if rr < rrNebr: if _mdsim_globals['nebrTabLen'] >= nebrTabMax: sys.exit(1) nebrTabLen = _mdsim_globals['nebrTabLen'] nebrTab[2 * nebrTabLen] = j1 nebrTab[2 * nebrTabLen + 1] = j2 _mdsim_globals['nebrTabLen'] += 1 j2 = cellList[j2] j1 = cellList[j1]
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 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)
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)