Advertisement
Guest User

Untitled

a guest
Apr 26th, 2015
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.82 KB | None | 0 0
  1. #!/usr/bin/env python
  2. import numpy
  3.  
  4. AA2AU = 1.0 / 0.529
  5. eps=78.39
  6.  
  7. max_iterations = 50
  8. diis_start_from_iter = 1
  9. diis_vector_threshold = 1.0e-6
  10. inverse = False
  11. surface_area_minimum = 1.0e-6
  12. threshold = 1.0e-9
  13. #k = 1.07
  14. # from Tomasi J, Mennucci B, Cammi R, Chem. Rev. 2005, 105, 2999-3093
  15. # on pp. 3013
  16. k = 1.0694
  17. scal_charges_iter = 0.05 # empirical factor to slowly turn on the charges
  18.  
  19. def CMAT(areas, coords):
  20. n = len(areas)
  21. C = numpy.zeros((n,n))
  22. for its in range(n):
  23. C[its,its] = k * numpy.sqrt( 4 * numpy.pi / areas[its] )
  24. for jts in range(its):
  25. dr = coords[its] - coords[jts]
  26. R = numpy.sqrt(dr.dot(dr))
  27. Ri = 1.0 / R
  28. C[its,jts] = Ri
  29. C[jts,its] = Ri
  30.  
  31. return C
  32.  
  33. f = open("water.surface", "r")
  34. areas = []
  35. coordinates = []
  36. for line in f:
  37. data = line.split()
  38.  
  39. area = float(data[2])
  40. if area < surface_area_minimum:
  41. area = surface_area_minimum
  42. areas.append( area ) #bohr**2
  43.  
  44. coordinates.append( map(float, data[3:6] ) ) # bohr
  45. f.close()
  46.  
  47. areas = numpy.array(areas)
  48. coordinates = numpy.array(coordinates)
  49. nts = len(areas)
  50. vtes = numpy.zeros(nts)
  51.  
  52. # potential on the surface of TIP3P water
  53. qpos = numpy.array([
  54. [1.0849871266, -0.0223279991, 0.0246861362],
  55. [2.0528740514, 0.0086017465, -0.0099440794],
  56. [0.8061379337, 0.5958520619, -0.6674536909]
  57. ]) * AA2AU
  58. nat = len(qpos)
  59. #qval = numpy.array([-0.834, 0.417, 0.417])
  60. #efp water
  61. qval = numpy.array([
  62. -8.5999937120+8.00000,
  63. -0.7000031440+1.00000,
  64. -0.7000031440+1.00000
  65. ])
  66. for iat in range(nat):
  67. for its in range(nts):
  68. dr = qpos[iat] - coordinates[its]
  69. R = numpy.sqrt(dr.dot(dr))
  70. vtes[its] = vtes[its] + qval[iat]/R
  71.  
  72. vtes *= -(eps-1)/eps
  73.  
  74. # get the C-matrix. Let's just invert it for now.
  75. C = CMAT(areas, coordinates)
  76. if inverse:
  77. Ci = numpy.linalg.inv(C)
  78. qout = Ci.dot( vtes )
  79. else:
  80. d0 = 1.0 / numpy.diag(C)
  81. qin = scal_charges_iter * vtes * d0
  82.  
  83. q_storage = []
  84. q_diff_storage = []
  85.  
  86. for k in range(1, max_iterations):
  87. vpot = numpy.zeros(nts)
  88. for its in range(nts):
  89. for jts in range(its):
  90. dr = coordinates[its] - coordinates[jts]
  91. R = numpy.sqrt(dr.dot(dr))
  92. vpot[its] = vpot[its] + qin[jts] / R
  93. vpot[jts] = vpot[jts] + qin[its] / R
  94.  
  95. qout = (vtes - vpot) * d0
  96. dq = qout - qin
  97.  
  98. if k >= diis_start_from_iter:
  99. q_storage.append( qout )
  100. q_diff_storage.append( dq )
  101.  
  102. if len(q_diff_storage) > 1:
  103. n = len(q_diff_storage)
  104. rhs = numpy.zeros(n+1)
  105. rhs[n] = -1
  106.  
  107. # setup system of linear equations
  108. B = numpy.zeros((n + 1, n + 1))
  109. B[:][n] = -1
  110. B = B.transpose()
  111. B[:][n] = -1
  112. B[n][n] = 0
  113.  
  114. for i, qi in enumerate(q_diff_storage):
  115. for j, qj in enumerate(q_diff_storage):
  116. B[i, j] = qi.dot(qj)
  117.  
  118. # solve the system of linear equations
  119. c = numpy.linalg.solve(B, rhs)[:n]
  120.  
  121. # better guess
  122. qout = numpy.zeros(numpy.shape(dq))
  123. for i in range(n):
  124. qout += c[i] * q_storage[i]
  125.  
  126. # remove, if needed, items from the DIIS space
  127. sel = list(numpy.where(numpy.abs(c) < diis_vector_threshold)[0])
  128. sel.reverse()
  129. for i in sel:
  130. q_storage.pop(i)
  131. q_diff_storage.pop(i)
  132.  
  133. abs_err = numpy.sqrt(dq.dot(dq)/nts)
  134. e_q = -0.5 * vtes.dot(qout)
  135. print("iter = {0:3d}, energy = {1:12.8f}, Q = {2:9.5f}, error = {3:16.9f}".format(k, e_q, sum(qout), abs_err))
  136. if abs_err < threshold:
  137. break
  138. qin = qout[:]
  139.  
  140. Q = sum(qout)
  141. G = -0.5 * vtes.dot(qout)
  142. print("ASC = {0:16.9f}".format(Q))
  143. print("Energy = {0:16.9f}".format(G))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement