|
| 1 | +# MIT License |
| 2 | +# |
| 3 | +# Copyright (c) 2017 Anders Steen Christensen and Felix A. Faber |
| 4 | +# |
| 5 | +# Permission is hereby granted, free of charge, to any person obtaining a copy |
| 6 | +# of this software and associated documentation files (the "Software"), to deal |
| 7 | +# in the Software without restriction, including without limitation the rights |
| 8 | +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 9 | +# copies of the Software, and to permit persons to whom the Software is |
| 10 | +# furnished to do so, subject to the following conditions: |
| 11 | +# |
| 12 | +# The above copyright notice and this permission notice shall be included in all |
| 13 | +# copies or substantial portions of the Software. |
| 14 | +# |
| 15 | +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 17 | +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 18 | +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 19 | +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 20 | +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 21 | +# SOFTWARE. |
| 22 | + |
| 23 | +from __future__ import division |
| 24 | +from __future__ import print_function |
| 25 | + |
| 26 | +import numpy as np |
| 27 | +from copy import copy |
| 28 | + |
| 29 | +PTP = {\ |
| 30 | + 1 :[1,1] ,2: [1,8]#Row1 |
| 31 | + |
| 32 | + ,3 :[2,1] ,4: [2,2]#Row2\ |
| 33 | + ,5 :[2,3] ,6: [2,4] ,7 :[2,5] ,8 :[2,6] ,9 :[2,7] ,10 :[2,8]\ |
| 34 | + |
| 35 | + ,11 :[3,1] ,12: [3,2]#Row3\ |
| 36 | + ,13 :[3,3] ,14: [3,4] ,15 :[3,5] ,16 :[3,6] ,17 :[3,7] ,18 :[3,8]\ |
| 37 | + |
| 38 | + ,19 :[4,1] ,20: [4,2]#Row4\ |
| 39 | + ,31 :[4,3] ,32: [4,4] ,33 :[4,5] ,34 :[4,6] ,35 :[4,7] ,36 :[4,8]\ |
| 40 | + ,21 :[4,9] ,22: [4,10],23 :[4,11],24 :[4,12],25 :[4,13],26 :[4,14],27 :[4,15],28 :[4,16],29 :[4,17],30 :[4,18]\ |
| 41 | + |
| 42 | + ,37 :[5,1] ,38: [5,2]#Row5\ |
| 43 | + ,49 :[5,3] ,50: [5,4] ,51 :[5,5] ,52 :[5,6] ,53 :[5,7] ,54 :[5,8]\ |
| 44 | + ,39 :[5,9] ,40: [5,10],41 :[5,11],42 :[5,12],43 :[5,13],44 :[5,14],45 :[5,15],46 :[5,16],47 :[5,17],48 :[5,18]\ |
| 45 | + |
| 46 | + ,55 :[6,1] ,56: [6,2]#Row6\ |
| 47 | + ,81 :[6,3] ,82: [6,4] ,83 :[6,5] ,84 :[6,6] ,85 :[6,7] ,86 :[6,8] |
| 48 | + ,72: [6,10],73 :[6,11],74 :[6,12],75 :[6,13],76 :[6,14],77 :[6,15],78 :[6,16],79 :[6,17],80 :[6,18]\ |
| 49 | + ,57 :[6,19],58: [6,20],59 :[6,21],60 :[6,22],61 :[6,23],62 :[6,24],63 :[6,25],64 :[6,26],65 :[6,27],66 :[6,28],67 :[6,29],68 :[6,30],69 :[6,31],70 :[6,32],71 :[6,33]\ |
| 50 | + |
| 51 | + ,87 :[7,1] ,88: [7,2]#Row7\ |
| 52 | + ,113:[7,3] ,114:[7,4] ,115:[7,5] ,116:[7,6] ,117:[7,7] ,118:[7,8]\ |
| 53 | + ,104:[7,10],105:[7,11],106:[7,12],107:[7,13],108:[7,14],109:[7,15],110:[7,16],111:[7,17],112:[7,18]\ |
| 54 | + ,89 :[7,19],90: [7,20],91 :[7,21],92 :[7,22],93 :[7,23],94 :[7,24],95 :[7,25],96 :[7,26],97 :[7,27],98 :[7,28],99 :[7,29],100:[7,30],101:[7,31],101:[7,32],102:[7,14],103:[7,33]} |
| 55 | + |
| 56 | +QtNm = { |
| 57 | + #Row1 |
| 58 | + 1 :[1,0,0,1./2.] |
| 59 | + ,2: [1,0,0,-1./2.] |
| 60 | + |
| 61 | + |
| 62 | + #Row2 |
| 63 | + ,3 :[2,0,0,1./2.] |
| 64 | + ,4: [2,0,0,-1./2.] |
| 65 | + |
| 66 | + ,5 :[2,-1,1,1./2.], 6: [2,0,1,1./2.] , 7 : [2,1,1,1./2.] |
| 67 | + ,8 : [2,-1,1,-1./2.] ,9: [2,0,1,-1./2.] ,10 :[2,1,1,-1./2.] |
| 68 | + |
| 69 | + |
| 70 | + #Row3 |
| 71 | + ,11 :[3,0,0,1./2.] |
| 72 | + ,12: [3,0,0,-1./2.] |
| 73 | + |
| 74 | + ,13 :[3,-1,1,1./2.] , 14: [3,0,1,1./2.] , 15 :[3,1,1,1./2.] |
| 75 | + ,16 :[3,-1,1,-1./2.] ,17 :[3,0,1,-1./2.] ,18 :[3,1,1,-1./2.] |
| 76 | + |
| 77 | + |
| 78 | + #Row3 |
| 79 | + ,19 :[4,0,0,1./2.] |
| 80 | + ,20: [4,0,0,-1./2.] |
| 81 | + |
| 82 | + ,31 :[4,-1,2,1./2.] , 32: [4,0,1,1./2.] , 33 :[4,1,1,1./2.] |
| 83 | + ,34 :[4,-1,1,-1./2.] ,35 :[4,0,1,-1./2.] ,36 :[4,1,1,-1./2.] |
| 84 | + |
| 85 | + ,21 :[4,-2,2,1./2.], 22:[4,-1,2,1./2.], 23 :[4,0,2,1./2.], 24 :[4,1,2,1./2.], 25 :[4,2,2,1./2.] |
| 86 | + ,26 :[4,-2,2,-1./2.], 27:[4,-1,2,-1./2.], 28 :[4,0,2,-1./2.],29 :[4,1,2,-1./2.],30 :[4,2,2,-1./2.] |
| 87 | + |
| 88 | + |
| 89 | + #Row5 |
| 90 | + ,37 :[5,0,0,1./2.] |
| 91 | + ,38: [5,0,0,-1./2.] |
| 92 | + |
| 93 | + ,49 :[5,-1,1,1./2.] , 50: [5,0,1,1./2.] , 51 :[5,1,1,1./2.] |
| 94 | + ,52 :[5,-1,1,-1./2.] ,53 :[5,0,1,-1./2.] ,54 :[5,1,1,-1./2.] |
| 95 | + |
| 96 | + |
| 97 | + ,39 :[5,-2,2,1./2.], 40:[5,-1,2,1./2.], 41 :[5,0,2,1./2.], 42 :[5,1,2,1./2.], 43 :[5,2,2,1./2.] |
| 98 | + ,44 :[5,-2,2,-1./2.],45 :[5,-1,2,-1./2.],46 :[5,0,2,-1./2.],47 :[5,1,2,-1./2.],48 :[5,2,2,-1./2.] |
| 99 | + |
| 100 | + |
| 101 | + #Row6 |
| 102 | + ,55 :[6,0,0,1./2.] |
| 103 | + ,56: [6,0,0,-1./2.] |
| 104 | + |
| 105 | + ,81 :[6,-1,1,1./2.] ,82: [6,0,1,1./2.] ,83: [6,1,1,1./2.] |
| 106 | + ,84 :[6,-1,1,-1./2.] ,85 :[6,0,1,-1./2.] ,86 :[6,1,1,-1./2.] |
| 107 | + |
| 108 | + ,71 :[6,-2,2,1./2.], 72: [6,-1,2,1./2.], 73 :[6,0,2,1./2.], 74 :[6,1,2,1./2.], 75 :[6,2,2,1./2.] |
| 109 | + ,76 :[6,-2,2,-1./2.],77 :[6,-1,2,-1./2.],78 :[6,0,2,-1./2.],79 :[6,1,2,-1./2.],80 :[6,2,2,-1./2.] |
| 110 | + |
| 111 | + ,57 :[6,-3,3,1./2.], 58: [6,-2,3,1./2.], 59 :[6,-1,3,1./2.], 60 :[6,0,3,1./2.], 61 :[6,1,3,1./2.], 62 :[6,2,3,1./2.], 63 :[6,3,3,1./2.] |
| 112 | + ,64 :[6,-3,3,-1./2.],65 :[6,-2,3,-1./2.],66 :[6,-1,3,-1./2.],67 :[6,0,3,-1./2.],68 :[6,1,3,-1./2.],69 :[6,2,3,-1./2.],70 :[6,3,3,-1./2.] |
| 113 | + |
| 114 | + |
| 115 | + #Row7 |
| 116 | + ,87 :[7,0,0,1./2.] |
| 117 | + ,88: [7,0,0,-1./2.] |
| 118 | + |
| 119 | + ,113:[7,-1,1,1./2.] , 114:[7,0,1,1./2.] , 115:[7,1,1,1./2.] |
| 120 | + ,116:[7,-1,1,-1./2.] ,117:[7,0,1,-1./2.] ,118:[7,1,1,-1./2.] |
| 121 | + |
| 122 | + ,103:[7,-2,2,1./2.], 104:[7,-1,2,1./2.], 105:[7,0,2,1./2.], 106:[7,1,2,1./2.], 107:[7,2,2,1./2.] |
| 123 | + ,108:[7,-2,2,-1./2.],109:[7,-1,2,-1./2.],110:[7,0,2,-1./2.],111:[7,1,2,-1./2.],112:[7,2,2,-1./2.] |
| 124 | + |
| 125 | + ,89 :[7,-3,3,1./2.], 90: [7,-2,3,1./2.], 91 :[7,-1,3,1./2.], 92 :[7,0,3,1./2.], 93 :[7,1,3,1./2.], 94 :[7,2,3,1./2.], 95 :[7,3,3,1./2.] |
| 126 | + ,96 :[7,-3,3,-1./2.],97 :[7,-2,3,-1./2.],98 :[7,-1,3,-1./2.],99 :[7,0,3,-1./2.],100:[7,1,3,-1./2.],101:[7,2,3,-1./2.],102:[7,3,3,-1./2.]} |
| 127 | + |
| 128 | + |
| 129 | + |
| 130 | + |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | +def QNum_distance(a,b, n_width, m_width, l_width, s_width): |
| 135 | + """ Calculate stochiometric distance |
| 136 | + a -- nuclear charge of element a |
| 137 | + b -- nuclear charge of element b |
| 138 | + r_width -- sigma in row-direction |
| 139 | + c_width -- sigma in column direction |
| 140 | + """ |
| 141 | + |
| 142 | + na = QtNm[int(a)][0] |
| 143 | + nb = QtNm[int(b)][0] |
| 144 | + |
| 145 | + ma = QtNm[int(a)][1] |
| 146 | + mb = QtNm[int(b)][1] |
| 147 | + |
| 148 | + la = QtNm[int(a)][2] |
| 149 | + lb = QtNm[int(b)][2] |
| 150 | + |
| 151 | + sa = QtNm[int(a)][3] |
| 152 | + sb = QtNm[int(b)][3] |
| 153 | + |
| 154 | + return np.exp(-(na - nb)**2/(4 * n_width**2) |
| 155 | + -(ma - mb)**2/(4 * m_width**2) |
| 156 | + -(la - lb)**2/(4 * l_width**2) |
| 157 | + -(sa - sb)**2/(4 * s_width**2)) |
| 158 | + |
| 159 | +def gen_QNum_distances(emax=100, n_width = 0.001, m_width = 0.001, l_width = 0.001, s_width = 0.001): |
| 160 | + """ Generate stochiometric ditance matrix |
| 161 | + emax -- Largest element |
| 162 | + r_width -- sigma in row-direction |
| 163 | + c_width -- sigma in column direction |
| 164 | + """ |
| 165 | + |
| 166 | + pd = np.zeros((emax,emax)) |
| 167 | + |
| 168 | + for i in range(emax): |
| 169 | + for j in range(emax): |
| 170 | + |
| 171 | + pd[i,j] = QNum_distance(i+1, j+1, n_width, m_width, l_width, s_width) |
| 172 | + |
| 173 | + return pd |
| 174 | + |
| 175 | +def periodic_distance(a, b, r_width, c_width): |
| 176 | + """ Calculate stochiometric distance |
| 177 | +
|
| 178 | + a -- nuclear charge of element a |
| 179 | + b -- nuclear charge of element b |
| 180 | + r_width -- sigma in row-direction |
| 181 | + c_width -- sigma in column direction |
| 182 | + """ |
| 183 | + |
| 184 | + ra = PTP[int(a)][0] |
| 185 | + rb = PTP[int(b)][0] |
| 186 | + ca = PTP[int(a)][1] |
| 187 | + cb = PTP[int(b)][1] |
| 188 | + |
| 189 | + # return (r_width**2 * c_width**2) / ((r_width**2 + (ra - rb)**2) * (c_width**2 + (ca - cb)**2)) |
| 190 | + |
| 191 | + return np.exp(-(ra - rb)**2/(4 * r_width**2)-(ca - cb)**2/(4 * c_width**2)) |
| 192 | + |
| 193 | + |
| 194 | +def gen_pd(emax=100, r_width=0.001, c_width=0.001): |
| 195 | + """ Generate stochiometric ditance matrix |
| 196 | +
|
| 197 | + emax -- Largest element |
| 198 | + r_width -- sigma in row-direction |
| 199 | + c_width -- sigma in column direction |
| 200 | + """ |
| 201 | + |
| 202 | + pd = np.zeros((emax,emax)) |
| 203 | + |
| 204 | + for i in range(emax): |
| 205 | + for j in range(emax): |
| 206 | + |
| 207 | + pd[i,j] = periodic_distance(i+1, j+1, r_width, c_width) |
| 208 | + |
| 209 | + return pd |
| 210 | + |
| 211 | + |
| 212 | +def gen_custom(e_vec, emax=100): |
| 213 | + """ Generate stochiometric ditance matrix |
| 214 | + emax -- Largest element |
| 215 | + r_width -- sigma in row-direction |
| 216 | + c_width -- sigma in column direction |
| 217 | + """ |
| 218 | + |
| 219 | + def check_if_unique(iterator): |
| 220 | + return len(set(iterator)) == 1 |
| 221 | + |
| 222 | + num_dims = [] |
| 223 | + |
| 224 | + for k,v in e_vec.items(): |
| 225 | + assert isinstance(k,int), 'Error! Keys need to be int' |
| 226 | + num_dims.append(len(v)) |
| 227 | + |
| 228 | + assert check_if_unique(num_dims), 'Error! Unequal number of dimensions' |
| 229 | + |
| 230 | + |
| 231 | + tmp = np.zeros((emax,num_dims[0])) |
| 232 | + |
| 233 | + for k,v in e_vec.items(): |
| 234 | + tmp[k,:] = copy(v) |
| 235 | + pd = np.dot(tmp,tmp.T) |
| 236 | + |
| 237 | + return pd |
| 238 | + |
| 239 | +def get_alchemy(alchemy, emax=100, r_width=0.001, c_width=0.001, elemental_vectors={}, \ |
| 240 | + n_width = 0.001, m_width = 0.001, l_width = 0.001, s_width = 0.001): |
| 241 | + |
| 242 | + if (alchemy == "off"): |
| 243 | + |
| 244 | + pd = np.eye(emax) |
| 245 | + doalchemy = False |
| 246 | + |
| 247 | + return doalchemy, pd |
| 248 | + |
| 249 | + elif (alchemy == "periodic-table"): |
| 250 | + |
| 251 | + pd = gen_pd(emax=emax, r_width=r_width, c_width=c_width) |
| 252 | + doalchemy = True |
| 253 | + |
| 254 | + return doalchemy, pd |
| 255 | + |
| 256 | + |
| 257 | + elif (alchemy == "quantum-numbers"): |
| 258 | + pd = gen_QNum_distances(emax=emax, n_width = n_width, m_width = m_width, |
| 259 | + l_width = l_width, s_width = s_width) |
| 260 | + doalchemy = True |
| 261 | + |
| 262 | + return doalchemy, pd |
| 263 | + |
| 264 | + elif (alchemy == "custom"): |
| 265 | + |
| 266 | + pd = gen_custom(elemental_vectors,emax) |
| 267 | + doalchemy = True |
| 268 | + |
| 269 | + |
| 270 | + return doalchemy, pd |
| 271 | + |
| 272 | + else: |
| 273 | + |
| 274 | + print("QML ERROR: Unknown alchemical method specified:", alchemy) |
| 275 | + exit(1) |
0 commit comments