Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from numpy import genfromtxt, fromstring, reshape, zeros, sum as nsum
3from urllib import request as urllibr
4from urllib import error as urlerror
6from mango.io import read_data, separater
7from mango.constants import c
10def initpos(lj_num, sigma, location=None, boxsize=0, xyz=False):
11 """
12 Get the positions of particles.
14 Also can collect magnetisations and momentums
16 Can be user specified with location or downloaded using urllj
18 Downloaded positions from standard LJ stable structures
20 An (extended) xyz file can be specified the last frame in the file
21 will be used
23 Parameters
24 ----------
25 lj_num: int
26 Number of molecules
27 sigma: float
28 distance between particle centres
29 location: string
30 location of file to load
31 boxsize: float
32 periodic boxsize (only required for 2 particle periodic systems)
34 """
35 if isinstance(location, str):
36 molecules, response, xyz = posfile(location, sigma)
37 elif lj_num == 1:
38 response = zeros(3)
39 elif lj_num == 2:
40 response = twoparticlesinabox(boxsize, sigma)
41 elif lj_num > 150:
42 c.Error("{}{}{}".format("F This is only setup for under 150 particles\n",
43 "for larger systems please specify a position file.\n",
44 "Larger structures may be available at http://doye.chem.ox.ac.uk/jon/structures/LJ/"))
45 else:
46 # TODO proper sigma conversion
47 response = urllj(lj_num) * sigma[:, None]
49 return separater(response), xyz
52def twoparticlesinabox(boxsize, sigma):
53 """
54 Set location of 2 particles.
56 put two particles next to each other
57 """
58 response = zeros((2, 3))
59 avdist = nsum(sigma) / 2
60 if boxsize >= nsum(sigma):
61 response[0, :] = [-avdist / 2, 0, 0]
62 response[1, :] = [avdist / 2, 0, 0]
63 else:
64 response[0, :] = [-boxsize / 8, 0, 0]
65 response[1, :] = [boxsize / 8, 0, 0]
66 return response
69def posfile(location, sigma, xyz=False, com=0):
70 """
71 Open position file.
73 Reads first two lines to check
74 if xyz open xyz otherwise read as unscaled coordinates
75 """
76 lines = []
77 try:
78 with open(location, "r") as file:
79 for n, l in enumerate(file): 79 ↛ 89line 79 didn't jump to line 89, because the loop on line 79 didn't complete
80 if l.startswith(("#", "\n")):
81 com += 1
82 elif n < (2 + com):
83 lines += [l.split()]
84 else:
85 break
86 except OSError:
87 c.Error(f"F Unable to find location file '{location}'")
89 if len(lines[0]) != len(lines[1]):
90 # TODO more secure xyz check (check lines[0][0] is int?)
91 molecules, response = read_data(location.rsplit(".", 1)[0], "xyz").xyzread()
92 response = response[-1]
93 xyz = True
94 else:
95 # TODO Currently this doesn't check if the file is prescaled. XYZ is the safe option in this case
96 # TODO Catch errors here from genfromtxt
97 response = genfromtxt(location) * sigma[:, None]
98 molecules = None
100 return molecules, response, xyz
103def urllj(lj_num, url="http://doye.chem.ox.ac.uk/jon/structures/LJ/points/{}"):
104 """
105 Download lj configuration.
107 Default url is http://doye.chem.ox.ac.uk/jon/structures/LJ/
109 Parameters
110 ----------
111 lj_num: int
112 Number of molecules
113 url: str
114 url with formatting {} for lj_num
116 """
117 try:
118 url = url.format(lj_num)
119 response = urllibr.urlopen(url).read().decode('utf-8')
120 response = fromstring(" ".join(response.split("\n")), sep=" ")
121 response = reshape(response, (lj_num, 3))
122 except urlerror.HTTPError:
123 c.Error("F Not found online for {} molecules".format(lj_num))
124 except urlerror.URLError:
125 c.Error("F Internet Connection Error, Particle locations cannot be downloaded")
126 else:
127 return response
130if __name__ == '__main__':
131 pass