From 619452e63b57546fc0b06826d3738288724c2b56 Mon Sep 17 00:00:00 2001 From: peterli3819 Date: Thu, 1 May 2025 12:55:07 -0600 Subject: [PATCH 1/6] adding proxies and fixing SP2 --- .../graph_adaptive_dm_scf_sp2/coords_1299.pdb | 1305 +++++++++++++++++ examples/graph_adaptive_dm_scf_sp2/input.in | 8 +- examples/graph_adaptive_dm_scf_sp2/main.py | 5 +- examples/graph_adaptive_dm_scf_sp2/vars | 3 +- src/sedacs/driver/graph_adaptive_scf_sp2.py | 329 +++++ 5 files changed, 1642 insertions(+), 8 deletions(-) create mode 100644 examples/graph_adaptive_dm_scf_sp2/coords_1299.pdb create mode 100644 src/sedacs/driver/graph_adaptive_scf_sp2.py diff --git a/examples/graph_adaptive_dm_scf_sp2/coords_1299.pdb b/examples/graph_adaptive_dm_scf_sp2/coords_1299.pdb new file mode 100644 index 0000000..55d5d1a --- /dev/null +++ b/examples/graph_adaptive_dm_scf_sp2/coords_1299.pdb @@ -0,0 +1,1305 @@ +TITLE Built with Packmol +REMARK Packmol generated pdb file +CRYST1 40.230 40.230 40.230 90.00 90.00 90.00 P 1 1 +MODEL 1 +ATOM 1 H HOH 0 24.812 22.184 19.109 1.00 0.00 H +ATOM 2 O HOH 1 24.014 22.044 19.696 1.00 0.00 O +ATOM 3 H HOH 0 23.492 21.337 19.219 1.00 0.00 H +ATOM 4 OW SOL 1 17.915 12.852 12.888 1.00 0.00 O +ATOM 5 HW1 SOL 1 18.247 13.543 12.247 1.00 0.00 H +ATOM 6 HW2 SOL 1 17.565 12.128 12.294 1.00 0.00 H +ATOM 7 OW SOL 2 17.524 28.252 22.152 1.00 0.00 O +ATOM 8 HW1 SOL 2 17.842 29.134 21.806 1.00 0.00 H +ATOM 9 HW2 SOL 2 16.749 28.493 22.736 1.00 0.00 H +ATOM 10 OW SOL 3 18.272 22.452 8.081 1.00 0.00 O +ATOM 11 HW1 SOL 3 18.633 21.922 8.848 1.00 0.00 H +ATOM 12 HW2 SOL 3 17.651 21.814 7.625 1.00 0.00 H +ATOM 13 OW SOL 4 22.430 24.527 31.340 1.00 0.00 O +ATOM 14 HW1 SOL 4 22.675 23.743 31.910 1.00 0.00 H +ATOM 15 HW2 SOL 4 22.090 25.200 31.998 1.00 0.00 H +ATOM 16 OW SOL 5 25.090 23.960 22.405 1.00 0.00 O +ATOM 17 HW1 SOL 5 24.836 23.682 21.479 1.00 0.00 H +ATOM 18 HW2 SOL 5 26.000 23.563 22.529 1.00 0.00 H +ATOM 19 OW SOL 6 24.774 20.640 26.519 1.00 0.00 O +ATOM 20 HW1 SOL 6 24.293 19.797 26.761 1.00 0.00 H +ATOM 21 HW2 SOL 6 24.915 21.092 27.400 1.00 0.00 H +ATOM 22 OW SOL 7 26.990 22.203 21.118 1.00 0.00 O +ATOM 23 HW1 SOL 7 26.249 21.867 21.698 1.00 0.00 H +ATOM 24 HW2 SOL 7 26.681 23.114 20.845 1.00 0.00 H +ATOM 25 OW SOL 8 6.883 20.799 22.990 1.00 0.00 O +ATOM 26 HW1 SOL 8 7.731 20.467 23.403 1.00 0.00 H +ATOM 27 HW2 SOL 8 6.530 21.448 23.664 1.00 0.00 H +ATOM 28 OW SOL 9 22.196 12.513 19.542 1.00 0.00 O +ATOM 29 HW1 SOL 9 21.895 11.768 20.137 1.00 0.00 H +ATOM 30 HW2 SOL 9 22.528 13.206 20.181 1.00 0.00 H +ATOM 31 OW SOL 10 24.367 14.196 27.807 1.00 0.00 O +ATOM 32 HW1 SOL 10 24.759 13.864 26.949 1.00 0.00 H +ATOM 33 HW2 SOL 10 25.039 14.862 28.132 1.00 0.00 H +ATOM 34 OW SOL 11 9.054 23.271 16.103 1.00 0.00 O +ATOM 35 HW1 SOL 11 9.000 23.179 15.109 1.00 0.00 H +ATOM 36 HW2 SOL 11 10.012 23.068 16.307 1.00 0.00 H +ATOM 37 OW SOL 12 13.728 24.315 29.715 1.00 0.00 O +ATOM 38 HW1 SOL 12 14.398 24.828 29.178 1.00 0.00 H +ATOM 39 HW2 SOL 12 13.236 23.780 29.028 1.00 0.00 H +ATOM 40 OW SOL 13 14.471 25.164 21.554 1.00 0.00 O +ATOM 41 HW1 SOL 13 14.885 25.186 22.464 1.00 0.00 H +ATOM 42 HW2 SOL 13 13.759 25.864 21.602 1.00 0.00 H +ATOM 43 OW SOL 14 26.294 31.275 22.228 1.00 0.00 O +ATOM 44 HW1 SOL 14 26.728 31.339 23.126 1.00 0.00 H +ATOM 45 HW2 SOL 14 26.431 30.319 21.968 1.00 0.00 H +ATOM 46 OW SOL 15 26.994 11.521 25.850 1.00 0.00 O +ATOM 47 HW1 SOL 15 26.171 11.436 25.288 1.00 0.00 H +ATOM 48 HW2 SOL 15 27.117 12.509 25.940 1.00 0.00 H +ATOM 49 OW SOL 16 16.539 28.602 27.834 1.00 0.00 O +ATOM 50 HW1 SOL 16 15.693 28.079 27.733 1.00 0.00 H +ATOM 51 HW2 SOL 16 16.972 28.525 26.936 1.00 0.00 H +ATOM 52 OW SOL 17 22.819 23.562 21.747 1.00 0.00 O +ATOM 53 HW1 SOL 17 23.183 24.097 22.509 1.00 0.00 H +ATOM 54 HW2 SOL 17 22.769 22.633 22.114 1.00 0.00 H +ATOM 55 OW SOL 18 19.599 24.838 14.635 1.00 0.00 O +ATOM 56 HW1 SOL 18 20.294 25.205 14.016 1.00 0.00 H +ATOM 57 HW2 SOL 18 18.904 24.470 14.018 1.00 0.00 H +ATOM 58 OW SOL 19 11.460 21.896 29.300 1.00 0.00 O +ATOM 59 HW1 SOL 19 12.202 22.159 29.917 1.00 0.00 H +ATOM 60 HW2 SOL 19 10.878 21.312 29.867 1.00 0.00 H +ATOM 61 OW SOL 20 13.460 8.606 19.737 1.00 0.00 O +ATOM 62 HW1 SOL 20 13.490 8.653 20.735 1.00 0.00 H +ATOM 63 HW2 SOL 20 13.017 7.729 19.555 1.00 0.00 H +ATOM 64 OW SOL 21 26.689 19.633 27.144 1.00 0.00 O +ATOM 65 HW1 SOL 21 25.881 19.410 27.689 1.00 0.00 H +ATOM 66 HW2 SOL 21 27.282 20.115 27.789 1.00 0.00 H +ATOM 67 OW SOL 22 12.680 24.355 15.838 1.00 0.00 O +ATOM 68 HW1 SOL 22 12.330 25.241 16.143 1.00 0.00 H +ATOM 69 HW2 SOL 22 13.173 24.574 14.996 1.00 0.00 H +ATOM 70 OW SOL 23 17.500 25.332 29.830 1.00 0.00 O +ATOM 71 HW1 SOL 23 18.055 26.125 29.579 1.00 0.00 H +ATOM 72 HW2 SOL 23 18.141 24.567 29.772 1.00 0.00 H +ATOM 73 OW SOL 24 24.609 7.817 20.898 1.00 0.00 O +ATOM 74 HW1 SOL 24 25.282 8.251 21.495 1.00 0.00 H +ATOM 75 HW2 SOL 24 23.751 7.908 21.404 1.00 0.00 H +ATOM 76 OW SOL 25 19.438 10.285 16.542 1.00 0.00 O +ATOM 77 HW1 SOL 25 18.832 10.543 15.790 1.00 0.00 H +ATOM 78 HW2 SOL 25 18.857 9.725 17.132 1.00 0.00 H +ATOM 79 OW SOL 26 11.378 19.670 24.247 1.00 0.00 O +ATOM 80 HW1 SOL 26 12.271 19.520 24.670 1.00 0.00 H +ATOM 81 HW2 SOL 26 11.565 20.341 23.530 1.00 0.00 H +ATOM 82 OW SOL 27 19.982 33.490 17.847 1.00 0.00 O +ATOM 83 HW1 SOL 27 20.767 33.113 18.339 1.00 0.00 H +ATOM 84 HW2 SOL 27 19.790 34.344 18.330 1.00 0.00 H +ATOM 85 OW SOL 28 16.937 23.412 19.668 1.00 0.00 O +ATOM 86 HW1 SOL 28 16.821 22.419 19.661 1.00 0.00 H +ATOM 87 HW2 SOL 28 17.719 23.554 20.275 1.00 0.00 H +ATOM 88 OW SOL 29 27.579 22.373 10.254 1.00 0.00 O +ATOM 89 HW1 SOL 29 28.063 21.629 9.795 1.00 0.00 H +ATOM 90 HW2 SOL 29 26.978 22.738 9.543 1.00 0.00 H +ATOM 91 OW SOL 30 12.743 19.748 16.777 1.00 0.00 O +ATOM 92 HW1 SOL 30 12.101 19.822 16.015 1.00 0.00 H +ATOM 93 HW2 SOL 30 13.630 19.635 16.329 1.00 0.00 H +ATOM 94 OW SOL 31 22.687 17.370 21.870 1.00 0.00 O +ATOM 95 HW1 SOL 31 23.080 16.659 22.453 1.00 0.00 H +ATOM 96 HW2 SOL 31 22.590 18.152 22.485 1.00 0.00 H +ATOM 97 OW SOL 32 22.513 10.240 16.651 1.00 0.00 O +ATOM 98 HW1 SOL 32 22.192 10.135 17.592 1.00 0.00 H +ATOM 99 HW2 SOL 32 22.854 11.179 16.622 1.00 0.00 H +ATOM 100 OW SOL 33 10.472 16.762 13.933 1.00 0.00 O +ATOM 101 HW1 SOL 33 9.659 16.888 14.501 1.00 0.00 H +ATOM 102 HW2 SOL 33 10.489 15.777 13.761 1.00 0.00 H +ATOM 103 OW SOL 34 24.723 25.943 21.674 1.00 0.00 O +ATOM 104 HW1 SOL 34 23.754 25.698 21.658 1.00 0.00 H +ATOM 105 HW2 SOL 34 24.933 26.139 20.717 1.00 0.00 H +ATOM 106 OW SOL 35 8.848 23.597 22.834 1.00 0.00 O +ATOM 107 HW1 SOL 35 8.137 23.529 23.534 1.00 0.00 H +ATOM 108 HW2 SOL 35 8.911 22.667 22.471 1.00 0.00 H +ATOM 109 OW SOL 36 25.003 14.221 21.630 1.00 0.00 O +ATOM 110 HW1 SOL 36 25.360 13.898 22.506 1.00 0.00 H +ATOM 111 HW2 SOL 36 25.075 15.216 21.699 1.00 0.00 H +ATOM 112 OW SOL 37 17.024 25.204 21.412 1.00 0.00 O +ATOM 113 HW1 SOL 37 17.045 26.028 20.846 1.00 0.00 H +ATOM 114 HW2 SOL 37 16.331 24.633 20.973 1.00 0.00 H +ATOM 115 OW SOL 38 21.145 21.407 11.963 1.00 0.00 O +ATOM 116 HW1 SOL 38 20.834 22.357 11.979 1.00 0.00 H +ATOM 117 HW2 SOL 38 21.433 21.237 12.905 1.00 0.00 H +ATOM 118 OW SOL 39 22.328 19.648 17.502 1.00 0.00 O +ATOM 119 HW1 SOL 39 21.950 18.759 17.242 1.00 0.00 H +ATOM 120 HW2 SOL 39 22.819 19.945 16.683 1.00 0.00 H +ATOM 121 OW SOL 40 31.232 18.191 16.282 1.00 0.00 O +ATOM 122 HW1 SOL 40 30.255 18.039 16.436 1.00 0.00 H +ATOM 123 HW2 SOL 40 31.500 17.427 15.695 1.00 0.00 H +ATOM 124 OW SOL 41 20.472 22.025 28.044 1.00 0.00 O +ATOM 125 HW1 SOL 41 19.910 21.201 28.114 1.00 0.00 H +ATOM 126 HW2 SOL 41 21.206 21.867 28.705 1.00 0.00 H +ATOM 127 OW SOL 42 29.525 27.024 26.006 1.00 0.00 O +ATOM 128 HW1 SOL 42 29.545 26.084 25.664 1.00 0.00 H +ATOM 129 HW2 SOL 42 30.425 27.384 25.760 1.00 0.00 H +ATOM 130 OW SOL 43 12.572 19.293 19.563 1.00 0.00 O +ATOM 131 HW1 SOL 43 12.235 19.147 18.633 1.00 0.00 H +ATOM 132 HW2 SOL 43 13.127 20.121 19.486 1.00 0.00 H +ATOM 133 OW SOL 44 28.904 25.278 27.929 1.00 0.00 O +ATOM 134 HW1 SOL 44 29.793 25.123 27.500 1.00 0.00 H +ATOM 135 HW2 SOL 44 28.261 25.227 27.165 1.00 0.00 H +ATOM 136 OW SOL 45 18.890 24.136 9.158 1.00 0.00 O +ATOM 137 HW1 SOL 45 18.386 24.659 9.845 1.00 0.00 H +ATOM 138 HW2 SOL 45 19.809 24.063 9.544 1.00 0.00 H +ATOM 139 OW SOL 46 22.411 19.995 11.347 1.00 0.00 O +ATOM 140 HW1 SOL 46 22.844 19.382 10.686 1.00 0.00 H +ATOM 141 HW2 SOL 46 22.765 20.897 11.099 1.00 0.00 H +ATOM 142 OW SOL 47 15.126 24.616 8.500 1.00 0.00 O +ATOM 143 HW1 SOL 47 14.587 24.550 9.339 1.00 0.00 H +ATOM 144 HW2 SOL 47 14.440 24.578 7.774 1.00 0.00 H +ATOM 145 OW SOL 48 19.778 11.195 20.586 1.00 0.00 O +ATOM 146 HW1 SOL 48 19.350 12.051 20.295 1.00 0.00 H +ATOM 147 HW2 SOL 48 20.122 11.403 21.502 1.00 0.00 H +ATOM 148 OW SOL 49 14.611 23.092 15.349 1.00 0.00 O +ATOM 149 HW1 SOL 49 14.685 22.211 14.880 1.00 0.00 H +ATOM 150 HW2 SOL 49 15.054 22.928 16.230 1.00 0.00 H +ATOM 151 OW SOL 50 16.022 14.205 14.111 1.00 0.00 O +ATOM 152 HW1 SOL 50 15.842 15.127 14.455 1.00 0.00 H +ATOM 153 HW2 SOL 50 16.550 14.364 13.276 1.00 0.00 H +ATOM 154 OW SOL 51 30.145 24.475 24.408 1.00 0.00 O +ATOM 155 HW1 SOL 51 30.977 24.710 24.911 1.00 0.00 H +ATOM 156 HW2 SOL 51 29.480 24.281 25.129 1.00 0.00 H +ATOM 157 OW SOL 52 19.974 12.135 30.934 1.00 0.00 O +ATOM 158 HW1 SOL 52 19.765 11.696 31.808 1.00 0.00 H +ATOM 159 HW2 SOL 52 20.496 12.947 31.197 1.00 0.00 H +ATOM 160 OW SOL 53 27.407 10.681 16.793 1.00 0.00 O +ATOM 161 HW1 SOL 53 28.348 10.992 16.659 1.00 0.00 H +ATOM 162 HW2 SOL 53 27.414 9.747 16.436 1.00 0.00 H +ATOM 163 OW SOL 54 20.295 15.208 16.437 1.00 0.00 O +ATOM 164 HW1 SOL 54 20.039 14.270 16.202 1.00 0.00 H +ATOM 165 HW2 SOL 54 20.500 15.626 15.552 1.00 0.00 H +ATOM 166 OW SOL 55 20.140 14.679 26.490 1.00 0.00 O +ATOM 167 HW1 SOL 55 19.541 14.035 26.967 1.00 0.00 H +ATOM 168 HW2 SOL 55 20.592 15.175 27.231 1.00 0.00 H +ATOM 169 OW SOL 56 18.049 18.312 23.379 1.00 0.00 O +ATOM 170 HW1 SOL 56 17.709 18.188 22.447 1.00 0.00 H +ATOM 171 HW2 SOL 56 17.257 18.669 23.874 1.00 0.00 H +ATOM 172 OW SOL 57 23.087 28.689 17.079 1.00 0.00 O +ATOM 173 HW1 SOL 57 22.894 29.416 16.421 1.00 0.00 H +ATOM 174 HW2 SOL 57 22.180 28.392 17.375 1.00 0.00 H +ATOM 175 OW SOL 58 17.652 16.214 32.063 1.00 0.00 O +ATOM 176 HW1 SOL 58 17.465 16.870 31.332 1.00 0.00 H +ATOM 177 HW2 SOL 58 17.266 15.359 31.717 1.00 0.00 H +ATOM 178 OW SOL 59 10.164 21.661 24.153 1.00 0.00 O +ATOM 179 HW1 SOL 59 9.226 21.407 23.917 1.00 0.00 H +ATOM 180 HW2 SOL 59 10.548 21.978 23.286 1.00 0.00 H +ATOM 181 OW SOL 60 20.915 17.894 29.118 1.00 0.00 O +ATOM 182 HW1 SOL 60 20.640 18.563 28.429 1.00 0.00 H +ATOM 183 HW2 SOL 60 21.002 17.043 28.600 1.00 0.00 H +ATOM 184 OW SOL 61 17.367 26.246 23.017 1.00 0.00 O +ATOM 185 HW1 SOL 61 16.659 26.364 23.712 1.00 0.00 H +ATOM 186 HW2 SOL 61 18.116 25.808 23.515 1.00 0.00 H +ATOM 187 OW SOL 62 21.776 22.893 24.986 1.00 0.00 O +ATOM 188 HW1 SOL 62 21.561 22.185 24.313 1.00 0.00 H +ATOM 189 HW2 SOL 62 21.893 23.717 24.431 1.00 0.00 H +ATOM 190 OW SOL 63 25.728 14.610 30.886 1.00 0.00 O +ATOM 191 HW1 SOL 63 26.527 14.773 30.307 1.00 0.00 H +ATOM 192 HW2 SOL 63 25.225 13.898 30.398 1.00 0.00 H +ATOM 193 OW SOL 64 25.135 11.052 12.970 1.00 0.00 O +ATOM 194 HW1 SOL 64 25.032 10.506 12.139 1.00 0.00 H +ATOM 195 HW2 SOL 64 25.610 10.438 13.599 1.00 0.00 H +ATOM 196 OW SOL 65 21.134 31.228 16.691 1.00 0.00 O +ATOM 197 HW1 SOL 65 21.641 31.978 17.115 1.00 0.00 H +ATOM 198 HW2 SOL 65 20.392 31.050 17.337 1.00 0.00 H +ATOM 199 OW SOL 66 15.661 24.773 31.063 1.00 0.00 O +ATOM 200 HW1 SOL 66 15.729 24.124 30.306 1.00 0.00 H +ATOM 201 HW2 SOL 66 15.321 25.607 30.629 1.00 0.00 H +ATOM 202 OW SOL 67 25.005 27.999 10.964 1.00 0.00 O +ATOM 203 HW1 SOL 67 25.289 28.514 10.155 1.00 0.00 H +ATOM 204 HW2 SOL 67 24.617 27.159 10.584 1.00 0.00 H +ATOM 205 OW SOL 68 23.912 25.698 23.933 1.00 0.00 O +ATOM 206 HW1 SOL 68 23.423 25.068 24.535 1.00 0.00 H +ATOM 207 HW2 SOL 68 24.848 25.346 23.932 1.00 0.00 H +ATOM 208 OW SOL 69 7.050 20.594 15.260 1.00 0.00 O +ATOM 209 HW1 SOL 69 6.133 20.372 15.590 1.00 0.00 H +ATOM 210 HW2 SOL 69 7.033 21.590 15.169 1.00 0.00 H +ATOM 211 OW SOL 70 10.707 29.314 23.961 1.00 0.00 O +ATOM 212 HW1 SOL 70 10.092 28.529 24.042 1.00 0.00 H +ATOM 213 HW2 SOL 70 10.103 30.057 23.672 1.00 0.00 H +ATOM 214 OW SOL 71 20.974 26.571 12.738 1.00 0.00 O +ATOM 215 HW1 SOL 71 21.250 26.511 11.779 1.00 0.00 H +ATOM 216 HW2 SOL 71 20.503 27.452 12.792 1.00 0.00 H +ATOM 217 OW SOL 72 19.050 11.882 24.746 1.00 0.00 O +ATOM 218 HW1 SOL 72 18.512 11.125 24.374 1.00 0.00 H +ATOM 219 HW2 SOL 72 19.945 11.769 24.315 1.00 0.00 H +ATOM 220 OW SOL 73 16.829 19.778 32.330 1.00 0.00 O +ATOM 221 HW1 SOL 73 16.123 20.115 32.953 1.00 0.00 H +ATOM 222 HW2 SOL 73 17.160 20.606 31.878 1.00 0.00 H +ATOM 223 OW SOL 74 27.194 11.819 10.655 1.00 0.00 O +ATOM 224 HW1 SOL 74 27.283 11.033 11.266 1.00 0.00 H +ATOM 225 HW2 SOL 74 26.907 12.560 11.262 1.00 0.00 H +ATOM 226 OW SOL 75 9.143 26.922 18.015 1.00 0.00 O +ATOM 227 HW1 SOL 75 9.732 26.265 18.486 1.00 0.00 H +ATOM 228 HW2 SOL 75 8.240 26.494 18.047 1.00 0.00 H +ATOM 229 OW SOL 76 24.798 18.634 30.721 1.00 0.00 O +ATOM 230 HW1 SOL 76 24.248 18.074 30.101 1.00 0.00 H +ATOM 231 HW2 SOL 76 25.641 18.795 30.208 1.00 0.00 H +ATOM 232 OW SOL 77 19.713 11.078 9.455 1.00 0.00 O +ATOM 233 HW1 SOL 77 19.886 10.367 10.137 1.00 0.00 H +ATOM 234 HW2 SOL 77 19.629 11.912 10.000 1.00 0.00 H +ATOM 235 OW SOL 78 19.949 16.434 18.234 1.00 0.00 O +ATOM 236 HW1 SOL 78 20.849 16.785 17.978 1.00 0.00 H +ATOM 237 HW2 SOL 78 19.360 16.720 17.479 1.00 0.00 H +ATOM 238 OW SOL 79 26.100 20.094 24.860 1.00 0.00 O +ATOM 239 HW1 SOL 79 25.929 20.125 23.875 1.00 0.00 H +ATOM 240 HW2 SOL 79 27.079 19.902 24.923 1.00 0.00 H +ATOM 241 OW SOL 80 28.245 23.176 16.401 1.00 0.00 O +ATOM 242 HW1 SOL 80 29.089 23.075 16.928 1.00 0.00 H +ATOM 243 HW2 SOL 80 27.898 22.241 16.330 1.00 0.00 H +ATOM 244 OW SOL 81 23.429 7.658 15.115 1.00 0.00 O +ATOM 245 HW1 SOL 81 23.809 7.098 14.379 1.00 0.00 H +ATOM 246 HW2 SOL 81 22.872 8.334 14.633 1.00 0.00 H +ATOM 247 OW SOL 82 10.552 26.955 16.715 1.00 0.00 O +ATOM 248 HW1 SOL 82 10.884 27.105 15.784 1.00 0.00 H +ATOM 249 HW2 SOL 82 10.537 27.873 17.111 1.00 0.00 H +ATOM 250 OW SOL 83 16.927 19.868 15.041 1.00 0.00 O +ATOM 251 HW1 SOL 83 17.297 20.069 14.134 1.00 0.00 H +ATOM 252 HW2 SOL 83 17.447 19.066 15.335 1.00 0.00 H +ATOM 253 OW SOL 84 13.998 26.748 24.005 1.00 0.00 O +ATOM 254 HW1 SOL 84 13.596 25.972 23.519 1.00 0.00 H +ATOM 255 HW2 SOL 84 13.297 27.458 23.937 1.00 0.00 H +ATOM 256 OW SOL 85 14.352 31.295 25.838 1.00 0.00 O +ATOM 257 HW1 SOL 85 13.403 31.109 25.586 1.00 0.00 H +ATOM 258 HW2 SOL 85 14.735 31.719 25.018 1.00 0.00 H +ATOM 259 OW SOL 86 25.245 18.847 22.053 1.00 0.00 O +ATOM 260 HW1 SOL 86 24.739 19.112 22.874 1.00 0.00 H +ATOM 261 HW2 SOL 86 24.714 18.083 21.686 1.00 0.00 H +ATOM 262 OW SOL 87 18.110 19.707 19.148 1.00 0.00 O +ATOM 263 HW1 SOL 87 18.008 20.702 19.124 1.00 0.00 H +ATOM 264 HW2 SOL 87 17.670 19.405 18.303 1.00 0.00 H +ATOM 265 OW SOL 88 18.407 29.100 15.428 1.00 0.00 O +ATOM 266 HW1 SOL 88 17.629 28.693 15.907 1.00 0.00 H +ATOM 267 HW2 SOL 88 18.057 29.264 14.506 1.00 0.00 H +ATOM 268 OW SOL 89 21.496 27.940 30.924 1.00 0.00 O +ATOM 269 HW1 SOL 89 22.219 28.126 31.589 1.00 0.00 H +ATOM 270 HW2 SOL 89 21.009 27.160 31.317 1.00 0.00 H +ATOM 271 OW SOL 90 21.396 23.151 19.398 1.00 0.00 O +ATOM 272 HW1 SOL 90 22.203 22.959 18.839 1.00 0.00 H +ATOM 273 HW2 SOL 90 21.351 24.150 19.414 1.00 0.00 H +ATOM 274 OW SOL 91 32.625 27.206 21.159 1.00 0.00 O +ATOM 275 HW1 SOL 91 32.437 26.355 21.649 1.00 0.00 H +ATOM 276 HW2 SOL 91 31.757 27.700 21.202 1.00 0.00 H +ATOM 277 OW SOL 92 28.432 18.158 21.287 1.00 0.00 O +ATOM 278 HW1 SOL 92 28.045 18.046 20.373 1.00 0.00 H +ATOM 279 HW2 SOL 92 27.657 17.989 21.895 1.00 0.00 H +ATOM 280 OW SOL 93 21.854 13.532 15.062 1.00 0.00 O +ATOM 281 HW1 SOL 93 22.622 14.072 15.406 1.00 0.00 H +ATOM 282 HW2 SOL 93 21.496 13.083 15.881 1.00 0.00 H +ATOM 283 OW SOL 94 24.782 18.353 11.187 1.00 0.00 O +ATOM 284 HW1 SOL 94 25.623 17.860 10.966 1.00 0.00 H +ATOM 285 HW2 SOL 94 24.721 19.048 10.471 1.00 0.00 H +ATOM 286 OW SOL 95 18.737 27.913 27.854 1.00 0.00 O +ATOM 287 HW1 SOL 95 19.078 27.134 28.380 1.00 0.00 H +ATOM 288 HW2 SOL 95 18.398 28.541 28.555 1.00 0.00 H +ATOM 289 OW SOL 96 18.869 14.640 29.839 1.00 0.00 O +ATOM 290 HW1 SOL 96 17.889 14.819 29.925 1.00 0.00 H +ATOM 291 HW2 SOL 96 19.162 14.476 30.781 1.00 0.00 H +ATOM 292 OW SOL 97 15.633 29.145 19.667 1.00 0.00 O +ATOM 293 HW1 SOL 97 16.374 28.912 20.297 1.00 0.00 H +ATOM 294 HW2 SOL 97 14.874 29.383 20.273 1.00 0.00 H +ATOM 295 OW SOL 98 17.231 13.661 27.274 1.00 0.00 O +ATOM 296 HW1 SOL 98 17.386 14.182 28.113 1.00 0.00 H +ATOM 297 HW2 SOL 98 17.027 12.739 27.603 1.00 0.00 H +ATOM 298 OW SOL 99 22.474 9.875 11.065 1.00 0.00 O +ATOM 299 HW1 SOL 99 22.471 10.847 10.828 1.00 0.00 H +ATOM 300 HW2 SOL 99 23.197 9.495 10.488 1.00 0.00 H +ATOM 301 OW SOL 100 9.546 17.626 27.369 1.00 0.00 O +ATOM 302 HW1 SOL 100 9.197 18.507 27.050 1.00 0.00 H +ATOM 303 HW2 SOL 100 9.858 17.179 26.530 1.00 0.00 H +ATOM 304 OW SOL 101 29.435 20.599 25.289 1.00 0.00 O +ATOM 305 HW1 SOL 101 29.100 21.122 24.506 1.00 0.00 H +ATOM 306 HW2 SOL 101 29.952 19.852 24.871 1.00 0.00 H +ATOM 307 OW SOL 102 16.859 24.623 17.953 1.00 0.00 O +ATOM 308 HW1 SOL 102 16.278 24.398 17.171 1.00 0.00 H +ATOM 309 HW2 SOL 102 17.749 24.814 17.538 1.00 0.00 H +ATOM 310 OW SOL 103 22.411 17.494 8.922 1.00 0.00 O +ATOM 311 HW1 SOL 103 22.525 17.755 7.964 1.00 0.00 H +ATOM 312 HW2 SOL 103 23.034 16.721 9.033 1.00 0.00 H +ATOM 313 OW SOL 104 27.718 17.918 18.028 1.00 0.00 O +ATOM 314 HW1 SOL 104 27.794 18.719 18.621 1.00 0.00 H +ATOM 315 HW2 SOL 104 26.973 17.390 18.437 1.00 0.00 H +ATOM 316 OW SOL 105 19.428 28.867 22.791 1.00 0.00 O +ATOM 317 HW1 SOL 105 20.268 29.090 23.285 1.00 0.00 H +ATOM 318 HW2 SOL 105 18.738 28.811 23.513 1.00 0.00 H +ATOM 319 OW SOL 106 10.198 24.333 21.376 1.00 0.00 O +ATOM 320 HW1 SOL 106 10.435 23.555 21.958 1.00 0.00 H +ATOM 321 HW2 SOL 106 10.262 25.117 21.992 1.00 0.00 H +ATOM 322 OW SOL 107 22.196 18.465 31.449 1.00 0.00 O +ATOM 323 HW1 SOL 107 22.006 17.752 30.774 1.00 0.00 H +ATOM 324 HW2 SOL 107 22.312 19.289 30.895 1.00 0.00 H +ATOM 325 OW SOL 108 19.177 16.695 28.844 1.00 0.00 O +ATOM 326 HW1 SOL 108 18.541 17.348 29.254 1.00 0.00 H +ATOM 327 HW2 SOL 108 18.616 16.205 28.178 1.00 0.00 H +ATOM 328 OW SOL 109 14.256 13.056 21.586 1.00 0.00 O +ATOM 329 HW1 SOL 109 14.417 12.261 21.002 1.00 0.00 H +ATOM 330 HW2 SOL 109 13.308 13.307 21.387 1.00 0.00 H +ATOM 331 OW SOL 110 19.769 17.841 19.874 1.00 0.00 O +ATOM 332 HW1 SOL 110 20.206 17.669 20.757 1.00 0.00 H +ATOM 333 HW2 SOL 110 18.942 18.349 20.116 1.00 0.00 H +ATOM 334 OW SOL 111 19.177 24.021 24.409 1.00 0.00 O +ATOM 335 HW1 SOL 111 18.930 24.860 24.895 1.00 0.00 H +ATOM 336 HW2 SOL 111 19.348 23.365 25.144 1.00 0.00 H +ATOM 337 OW SOL 112 13.128 19.682 21.718 1.00 0.00 O +ATOM 338 HW1 SOL 112 12.916 20.560 21.288 1.00 0.00 H +ATOM 339 HW2 SOL 112 13.991 19.413 21.292 1.00 0.00 H +ATOM 340 OW SOL 113 24.265 10.766 24.493 1.00 0.00 O +ATOM 341 HW1 SOL 113 24.149 11.305 25.328 1.00 0.00 H +ATOM 342 HW2 SOL 113 24.889 10.035 24.769 1.00 0.00 H +ATOM 343 OW SOL 114 15.224 12.544 26.191 1.00 0.00 O +ATOM 344 HW1 SOL 114 14.815 12.639 25.284 1.00 0.00 H +ATOM 345 HW2 SOL 114 15.905 11.822 26.067 1.00 0.00 H +ATOM 346 OW SOL 115 16.171 28.128 25.166 1.00 0.00 O +ATOM 347 HW1 SOL 115 15.398 28.548 25.641 1.00 0.00 H +ATOM 348 HW2 SOL 115 16.066 27.153 25.360 1.00 0.00 H +ATOM 349 OW SOL 116 16.179 7.973 18.838 1.00 0.00 O +ATOM 350 HW1 SOL 116 15.811 8.610 19.516 1.00 0.00 H +ATOM 351 HW2 SOL 116 17.002 7.611 19.277 1.00 0.00 H +ATOM 352 OW SOL 117 14.860 10.741 22.956 1.00 0.00 O +ATOM 353 HW1 SOL 117 14.672 10.505 22.002 1.00 0.00 H +ATOM 354 HW2 SOL 117 14.057 11.269 23.231 1.00 0.00 H +ATOM 355 OW SOL 118 20.264 22.364 7.812 1.00 0.00 O +ATOM 356 HW1 SOL 118 20.097 22.151 6.850 1.00 0.00 H +ATOM 357 HW2 SOL 118 21.123 21.893 8.013 1.00 0.00 H +ATOM 358 OW SOL 119 14.432 13.841 28.501 1.00 0.00 O +ATOM 359 HW1 SOL 119 14.895 13.802 27.616 1.00 0.00 H +ATOM 360 HW2 SOL 119 13.754 13.108 28.445 1.00 0.00 H +ATOM 361 OW SOL 120 23.949 28.612 28.421 1.00 0.00 O +ATOM 362 HW1 SOL 120 23.700 29.051 29.285 1.00 0.00 H +ATOM 363 HW2 SOL 120 23.114 28.673 27.876 1.00 0.00 H +ATOM 364 OW SOL 121 24.860 26.234 15.593 1.00 0.00 O +ATOM 365 HW1 SOL 121 24.021 26.709 15.327 1.00 0.00 H +ATOM 366 HW2 SOL 121 24.678 25.941 16.531 1.00 0.00 H +ATOM 367 OW SOL 122 13.994 20.898 31.066 1.00 0.00 O +ATOM 368 HW1 SOL 122 14.720 21.484 30.705 1.00 0.00 H +ATOM 369 HW2 SOL 122 14.403 20.493 31.884 1.00 0.00 H +ATOM 370 OW SOL 123 19.763 31.059 19.445 1.00 0.00 O +ATOM 371 HW1 SOL 123 18.818 31.118 19.767 1.00 0.00 H +ATOM 372 HW2 SOL 123 20.274 30.793 20.262 1.00 0.00 H +ATOM 373 OW SOL 124 15.319 22.439 27.337 1.00 0.00 O +ATOM 374 HW1 SOL 124 15.956 23.111 27.716 1.00 0.00 H +ATOM 375 HW2 SOL 124 14.687 22.262 28.091 1.00 0.00 H +ATOM 376 OW SOL 125 22.320 32.061 22.179 1.00 0.00 O +ATOM 377 HW1 SOL 125 22.491 31.137 21.839 1.00 0.00 H +ATOM 378 HW2 SOL 125 22.019 32.560 21.367 1.00 0.00 H +ATOM 379 OW SOL 126 27.110 12.879 27.942 1.00 0.00 O +ATOM 380 HW1 SOL 126 26.163 12.568 27.865 1.00 0.00 H +ATOM 381 HW2 SOL 126 27.090 13.507 28.719 1.00 0.00 H +ATOM 382 OW SOL 127 9.308 20.552 15.865 1.00 0.00 O +ATOM 383 HW1 SOL 127 8.830 21.419 15.729 1.00 0.00 H +ATOM 384 HW2 SOL 127 9.870 20.716 16.675 1.00 0.00 H +ATOM 385 OW SOL 128 8.347 18.938 14.159 1.00 0.00 O +ATOM 386 HW1 SOL 128 9.293 18.804 13.864 1.00 0.00 H +ATOM 387 HW2 SOL 128 8.389 18.811 15.149 1.00 0.00 H +ATOM 388 OW SOL 129 24.213 29.125 21.625 1.00 0.00 O +ATOM 389 HW1 SOL 129 23.525 29.555 21.040 1.00 0.00 H +ATOM 390 HW2 SOL 129 25.014 29.053 21.031 1.00 0.00 H +ATOM 391 OW SOL 130 15.833 23.752 32.917 1.00 0.00 O +ATOM 392 HW1 SOL 130 14.936 24.157 32.743 1.00 0.00 H +ATOM 393 HW2 SOL 130 15.904 23.030 32.229 1.00 0.00 H +ATOM 394 OW SOL 131 16.075 23.397 13.754 1.00 0.00 O +ATOM 395 HW1 SOL 131 16.295 24.212 14.289 1.00 0.00 H +ATOM 396 HW2 SOL 131 16.944 22.904 13.705 1.00 0.00 H +ATOM 397 OW SOL 132 20.326 20.875 18.699 1.00 0.00 O +ATOM 398 HW1 SOL 132 20.765 21.712 18.372 1.00 0.00 H +ATOM 399 HW2 SOL 132 20.345 20.271 17.903 1.00 0.00 H +ATOM 400 OW SOL 133 9.929 15.192 16.898 1.00 0.00 O +ATOM 401 HW1 SOL 133 10.630 15.898 16.998 1.00 0.00 H +ATOM 402 HW2 SOL 133 9.460 15.197 17.781 1.00 0.00 H +ATOM 403 OW SOL 134 16.787 20.325 25.209 1.00 0.00 O +ATOM 404 HW1 SOL 134 16.624 20.233 26.192 1.00 0.00 H +ATOM 405 HW2 SOL 134 17.637 20.849 25.159 1.00 0.00 H +ATOM 406 OW SOL 135 17.520 21.373 23.048 1.00 0.00 O +ATOM 407 HW1 SOL 135 16.601 21.519 23.412 1.00 0.00 H +ATOM 408 HW2 SOL 135 17.589 22.039 22.305 1.00 0.00 H +ATOM 409 OW SOL 136 23.555 18.200 32.700 1.00 0.00 O +ATOM 410 HW1 SOL 136 23.865 19.126 32.915 1.00 0.00 H +ATOM 411 HW2 SOL 136 23.912 17.651 33.456 1.00 0.00 H +ATOM 412 OW SOL 137 23.805 17.377 24.654 1.00 0.00 O +ATOM 413 HW1 SOL 137 22.966 16.841 24.563 1.00 0.00 H +ATOM 414 HW2 SOL 137 24.198 17.057 25.515 1.00 0.00 H +ATOM 415 OW SOL 138 26.351 32.443 20.268 1.00 0.00 O +ATOM 416 HW1 SOL 138 25.929 32.467 19.362 1.00 0.00 H +ATOM 417 HW2 SOL 138 26.686 31.505 20.348 1.00 0.00 H +ATOM 418 OW SOL 139 29.387 20.828 17.230 1.00 0.00 O +ATOM 419 HW1 SOL 139 28.756 20.608 17.974 1.00 0.00 H +ATOM 420 HW2 SOL 139 29.627 19.934 16.852 1.00 0.00 H +ATOM 421 OW SOL 140 14.191 23.512 23.343 1.00 0.00 O +ATOM 422 HW1 SOL 140 14.176 23.411 22.348 1.00 0.00 H +ATOM 423 HW2 SOL 140 14.034 22.582 23.676 1.00 0.00 H +ATOM 424 OW SOL 141 15.756 15.625 22.699 1.00 0.00 O +ATOM 425 HW1 SOL 141 15.667 16.593 22.933 1.00 0.00 H +ATOM 426 HW2 SOL 141 15.942 15.186 23.577 1.00 0.00 H +ATOM 427 OW SOL 142 20.510 13.333 11.927 1.00 0.00 O +ATOM 428 HW1 SOL 142 20.283 14.306 11.925 1.00 0.00 H +ATOM 429 HW2 SOL 142 20.679 13.131 12.892 1.00 0.00 H +ATOM 430 OW SOL 143 24.585 21.862 22.891 1.00 0.00 O +ATOM 431 HW1 SOL 143 24.215 21.242 23.583 1.00 0.00 H +ATOM 432 HW2 SOL 143 24.284 21.457 22.027 1.00 0.00 H +ATOM 433 OW SOL 144 19.090 26.889 31.259 1.00 0.00 O +ATOM 434 HW1 SOL 144 18.787 27.543 30.565 1.00 0.00 H +ATOM 435 HW2 SOL 144 19.301 27.464 32.049 1.00 0.00 H +ATOM 436 OW SOL 145 7.500 15.159 18.426 1.00 0.00 O +ATOM 437 HW1 SOL 145 8.026 14.423 18.852 1.00 0.00 H +ATOM 438 HW2 SOL 145 7.359 15.810 19.171 1.00 0.00 H +ATOM 439 OW SOL 146 27.618 20.029 10.797 1.00 0.00 O +ATOM 440 HW1 SOL 146 28.084 19.652 9.998 1.00 0.00 H +ATOM 441 HW2 SOL 146 26.728 19.574 10.788 1.00 0.00 H +ATOM 442 OW SOL 147 11.282 12.159 12.611 1.00 0.00 O +ATOM 443 HW1 SOL 147 11.736 11.951 13.478 1.00 0.00 H +ATOM 444 HW2 SOL 147 10.338 11.869 12.764 1.00 0.00 H +ATOM 445 OW SOL 148 15.008 16.634 8.329 1.00 0.00 O +ATOM 446 HW1 SOL 148 14.565 17.240 8.990 1.00 0.00 H +ATOM 447 HW2 SOL 148 14.744 17.017 7.444 1.00 0.00 H +ATOM 448 OW SOL 149 29.329 17.460 13.545 1.00 0.00 O +ATOM 449 HW1 SOL 149 29.799 16.662 13.921 1.00 0.00 H +ATOM 450 HW2 SOL 149 29.197 18.052 14.340 1.00 0.00 H +ATOM 451 OW SOL 150 11.143 29.847 21.994 1.00 0.00 O +ATOM 452 HW1 SOL 150 11.288 29.066 21.386 1.00 0.00 H +ATOM 453 HW2 SOL 150 11.125 30.629 21.372 1.00 0.00 H +ATOM 454 OW SOL 151 12.115 21.477 18.277 1.00 0.00 O +ATOM 455 HW1 SOL 151 13.049 21.751 18.052 1.00 0.00 H +ATOM 456 HW2 SOL 151 11.688 21.338 17.383 1.00 0.00 H +ATOM 457 OW SOL 152 22.610 13.864 17.470 1.00 0.00 O +ATOM 458 HW1 SOL 152 22.705 12.875 17.359 1.00 0.00 H +ATOM 459 HW2 SOL 152 22.548 13.985 18.461 1.00 0.00 H +ATOM 460 OW SOL 153 29.100 16.537 16.520 1.00 0.00 O +ATOM 461 HW1 SOL 153 28.138 16.665 16.280 1.00 0.00 H +ATOM 462 HW2 SOL 153 29.337 15.667 16.089 1.00 0.00 H +ATOM 463 OW SOL 154 12.381 21.642 14.486 1.00 0.00 O +ATOM 464 HW1 SOL 154 13.077 20.974 14.750 1.00 0.00 H +ATOM 465 HW2 SOL 154 11.884 21.814 15.337 1.00 0.00 H +ATOM 466 OW SOL 155 31.757 13.163 21.010 1.00 0.00 O +ATOM 467 HW1 SOL 155 31.139 13.597 21.665 1.00 0.00 H +ATOM 468 HW2 SOL 155 32.466 12.758 21.587 1.00 0.00 H +ATOM 469 OW SOL 156 21.536 18.257 25.616 1.00 0.00 O +ATOM 470 HW1 SOL 156 21.932 18.565 26.481 1.00 0.00 H +ATOM 471 HW2 SOL 156 22.086 18.726 24.925 1.00 0.00 H +ATOM 472 OW SOL 157 20.543 27.375 25.907 1.00 0.00 O +ATOM 473 HW1 SOL 157 19.895 26.941 26.533 1.00 0.00 H +ATOM 474 HW2 SOL 157 21.169 27.861 26.515 1.00 0.00 H +ATOM 475 OW SOL 158 13.721 27.318 16.382 1.00 0.00 O +ATOM 476 HW1 SOL 158 12.766 27.561 16.555 1.00 0.00 H +ATOM 477 HW2 SOL 158 14.081 27.115 17.292 1.00 0.00 H +ATOM 478 OW SOL 159 11.109 14.336 28.727 1.00 0.00 O +ATOM 479 HW1 SOL 159 10.922 15.263 29.051 1.00 0.00 H +ATOM 480 HW2 SOL 159 11.994 14.116 29.138 1.00 0.00 H +ATOM 481 OW SOL 160 7.998 25.909 14.509 1.00 0.00 O +ATOM 482 HW1 SOL 160 7.826 25.064 14.002 1.00 0.00 H +ATOM 483 HW2 SOL 160 8.506 26.475 13.860 1.00 0.00 H +ATOM 484 OW SOL 161 25.404 24.209 13.944 1.00 0.00 O +ATOM 485 HW1 SOL 161 25.354 23.381 14.502 1.00 0.00 H +ATOM 486 HW2 SOL 161 26.173 24.712 14.336 1.00 0.00 H +ATOM 487 OW SOL 162 24.844 25.891 26.881 1.00 0.00 O +ATOM 488 HW1 SOL 162 25.424 25.089 27.018 1.00 0.00 H +ATOM 489 HW2 SOL 162 24.491 25.772 25.953 1.00 0.00 H +ATOM 490 OW SOL 163 14.619 20.558 23.171 1.00 0.00 O +ATOM 491 HW1 SOL 163 15.041 20.548 24.077 1.00 0.00 H +ATOM 492 HW2 SOL 163 13.641 20.481 23.366 1.00 0.00 H +ATOM 493 OW SOL 164 27.083 10.805 27.618 1.00 0.00 O +ATOM 494 HW1 SOL 164 27.958 10.356 27.439 1.00 0.00 H +ATOM 495 HW2 SOL 164 26.964 10.702 28.606 1.00 0.00 H +ATOM 496 OW SOL 165 23.957 28.645 23.912 1.00 0.00 O +ATOM 497 HW1 SOL 165 23.636 27.724 23.693 1.00 0.00 H +ATOM 498 HW2 SOL 165 24.334 28.551 24.833 1.00 0.00 H +ATOM 499 OW SOL 166 21.857 28.095 24.745 1.00 0.00 O +ATOM 500 HW1 SOL 166 21.651 27.780 23.818 1.00 0.00 H +ATOM 501 HW2 SOL 166 22.393 27.346 25.134 1.00 0.00 H +ATOM 502 OW SOL 167 14.267 8.489 17.721 1.00 0.00 O +ATOM 503 HW1 SOL 167 14.806 9.323 17.839 1.00 0.00 H +ATOM 504 HW2 SOL 167 14.352 8.289 16.745 1.00 0.00 H +ATOM 505 OW SOL 168 15.230 32.590 23.368 1.00 0.00 O +ATOM 506 HW1 SOL 168 15.697 33.435 23.630 1.00 0.00 H +ATOM 507 HW2 SOL 168 15.330 32.564 22.374 1.00 0.00 H +ATOM 508 OW SOL 169 20.692 18.024 12.789 1.00 0.00 O +ATOM 509 HW1 SOL 169 20.383 17.682 13.676 1.00 0.00 H +ATOM 510 HW2 SOL 169 21.344 17.331 12.483 1.00 0.00 H +ATOM 511 OW SOL 170 20.941 14.283 32.482 1.00 0.00 O +ATOM 512 HW1 SOL 170 20.807 15.094 31.913 1.00 0.00 H +ATOM 513 HW2 SOL 170 21.798 13.896 32.144 1.00 0.00 H +ATOM 514 OW SOL 171 20.572 24.087 21.759 1.00 0.00 O +ATOM 515 HW1 SOL 171 20.177 24.703 21.078 1.00 0.00 H +ATOM 516 HW2 SOL 171 21.047 23.401 21.209 1.00 0.00 H +ATOM 517 OW SOL 172 27.011 21.983 12.689 1.00 0.00 O +ATOM 518 HW1 SOL 172 26.589 21.796 13.576 1.00 0.00 H +ATOM 519 HW2 SOL 172 27.502 21.138 12.478 1.00 0.00 H +ATOM 520 OW SOL 173 27.873 21.492 26.173 1.00 0.00 O +ATOM 521 HW1 SOL 173 28.092 21.918 27.051 1.00 0.00 H +ATOM 522 HW2 SOL 173 26.908 21.715 26.036 1.00 0.00 H +ATOM 523 OW SOL 174 18.801 23.348 22.703 1.00 0.00 O +ATOM 524 HW1 SOL 174 18.700 24.180 22.157 1.00 0.00 H +ATOM 525 HW2 SOL 174 19.279 22.720 22.089 1.00 0.00 H +ATOM 526 OW SOL 175 28.842 13.423 18.022 1.00 0.00 O +ATOM 527 HW1 SOL 175 28.740 12.648 18.646 1.00 0.00 H +ATOM 528 HW2 SOL 175 28.519 14.202 18.559 1.00 0.00 H +ATOM 529 OW SOL 176 25.404 27.238 13.894 1.00 0.00 O +ATOM 530 HW1 SOL 176 25.057 28.141 13.642 1.00 0.00 H +ATOM 531 HW2 SOL 176 25.068 26.644 13.164 1.00 0.00 H +ATOM 532 OW SOL 177 13.648 31.004 20.523 1.00 0.00 O +ATOM 533 HW1 SOL 177 14.154 31.859 20.403 1.00 0.00 H +ATOM 534 HW2 SOL 177 13.311 30.798 19.605 1.00 0.00 H +ATOM 535 OW SOL 178 14.229 17.416 17.143 1.00 0.00 O +ATOM 536 HW1 SOL 178 13.948 16.941 16.310 1.00 0.00 H +ATOM 537 HW2 SOL 178 15.227 17.369 17.117 1.00 0.00 H +ATOM 538 OW SOL 179 15.646 10.903 29.696 1.00 0.00 O +ATOM 539 HW1 SOL 179 16.138 11.535 29.097 1.00 0.00 H +ATOM 540 HW2 SOL 179 16.141 10.966 30.562 1.00 0.00 H +ATOM 541 OW SOL 180 19.621 22.063 14.117 1.00 0.00 O +ATOM 542 HW1 SOL 180 19.137 22.720 14.695 1.00 0.00 H +ATOM 543 HW2 SOL 180 19.979 21.395 14.768 1.00 0.00 H +ATOM 544 OW SOL 181 30.397 26.314 19.886 1.00 0.00 O +ATOM 545 HW1 SOL 181 30.779 26.155 20.796 1.00 0.00 H +ATOM 546 HW2 SOL 181 30.028 25.421 19.626 1.00 0.00 H +ATOM 547 OW SOL 182 19.674 13.424 22.478 1.00 0.00 O +ATOM 548 HW1 SOL 182 18.963 12.986 21.929 1.00 0.00 H +ATOM 549 HW2 SOL 182 20.211 13.934 21.806 1.00 0.00 H +ATOM 550 OW SOL 183 18.668 14.883 20.010 1.00 0.00 O +ATOM 551 HW1 SOL 183 18.273 14.187 20.610 1.00 0.00 H +ATOM 552 HW2 SOL 183 19.045 15.557 20.645 1.00 0.00 H +ATOM 553 OW SOL 184 17.034 29.023 9.488 1.00 0.00 O +ATOM 554 HW1 SOL 184 17.506 29.166 10.358 1.00 0.00 H +ATOM 555 HW2 SOL 184 17.634 28.392 8.995 1.00 0.00 H +ATOM 556 OW SOL 185 22.961 20.786 25.713 1.00 0.00 O +ATOM 557 HW1 SOL 185 22.731 20.546 24.770 1.00 0.00 H +ATOM 558 HW2 SOL 185 22.071 20.838 26.166 1.00 0.00 H +ATOM 559 OW SOL 186 26.286 17.329 31.213 1.00 0.00 O +ATOM 560 HW1 SOL 186 26.404 17.825 32.073 1.00 0.00 H +ATOM 561 HW2 SOL 186 26.241 16.371 31.498 1.00 0.00 H +ATOM 562 OW SOL 187 27.580 14.914 14.672 1.00 0.00 O +ATOM 563 HW1 SOL 187 27.811 14.051 15.121 1.00 0.00 H +ATOM 564 HW2 SOL 187 27.719 14.720 13.701 1.00 0.00 H +ATOM 565 OW SOL 188 23.031 33.085 25.667 1.00 0.00 O +ATOM 566 HW1 SOL 188 23.825 32.541 25.398 1.00 0.00 H +ATOM 567 HW2 SOL 188 22.449 33.071 24.854 1.00 0.00 H +ATOM 568 OW SOL 189 15.597 15.370 30.674 1.00 0.00 O +ATOM 569 HW1 SOL 189 15.625 16.152 31.297 1.00 0.00 H +ATOM 570 HW2 SOL 189 15.518 14.583 31.286 1.00 0.00 H +ATOM 571 OW SOL 190 16.883 26.648 31.638 1.00 0.00 O +ATOM 572 HW1 SOL 190 16.297 26.276 32.357 1.00 0.00 H +ATOM 573 HW2 SOL 190 16.832 27.637 31.780 1.00 0.00 H +ATOM 574 OW SOL 191 19.861 24.244 32.586 1.00 0.00 O +ATOM 575 HW1 SOL 191 19.950 23.992 31.623 1.00 0.00 H +ATOM 576 HW2 SOL 191 20.144 25.202 32.606 1.00 0.00 H +ATOM 577 OW SOL 192 15.257 9.758 26.764 1.00 0.00 O +ATOM 578 HW1 SOL 192 14.827 10.581 27.136 1.00 0.00 H +ATOM 579 HW2 SOL 192 16.212 10.027 26.639 1.00 0.00 H +ATOM 580 OW SOL 193 21.738 19.826 33.281 1.00 0.00 O +ATOM 581 HW1 SOL 193 22.076 20.323 32.483 1.00 0.00 H +ATOM 582 HW2 SOL 193 20.856 20.258 33.472 1.00 0.00 H +ATOM 583 OW SOL 194 10.469 18.366 28.899 1.00 0.00 O +ATOM 584 HW1 SOL 194 11.297 18.486 28.352 1.00 0.00 H +ATOM 585 HW2 SOL 194 10.007 19.250 28.826 1.00 0.00 H +ATOM 586 OW SOL 195 19.058 31.288 28.229 1.00 0.00 O +ATOM 587 HW1 SOL 195 18.137 31.553 28.515 1.00 0.00 H +ATOM 588 HW2 SOL 195 19.157 31.712 27.329 1.00 0.00 H +ATOM 589 OW SOL 196 15.716 28.774 16.471 1.00 0.00 O +ATOM 590 HW1 SOL 196 15.871 28.372 17.373 1.00 0.00 H +ATOM 591 HW2 SOL 196 14.924 29.367 16.610 1.00 0.00 H +ATOM 592 OW SOL 197 15.165 21.070 10.861 1.00 0.00 O +ATOM 593 HW1 SOL 197 14.773 20.723 11.713 1.00 0.00 H +ATOM 594 HW2 SOL 197 14.363 21.299 10.309 1.00 0.00 H +ATOM 595 OW SOL 198 18.682 30.296 17.929 1.00 0.00 O +ATOM 596 HW1 SOL 198 18.616 30.245 16.933 1.00 0.00 H +ATOM 597 HW2 SOL 198 19.420 29.658 18.149 1.00 0.00 H +ATOM 598 OW SOL 199 25.446 15.251 13.605 1.00 0.00 O +ATOM 599 HW1 SOL 199 25.367 14.695 12.778 1.00 0.00 H +ATOM 600 HW2 SOL 199 25.061 14.668 14.320 1.00 0.00 H +ATOM 601 OW SOL 200 25.596 23.079 27.017 1.00 0.00 O +ATOM 602 HW1 SOL 200 24.713 23.143 27.480 1.00 0.00 H +ATOM 603 HW2 SOL 200 26.235 22.861 27.754 1.00 0.00 H +ATOM 604 OW SOL 201 23.494 11.771 21.543 1.00 0.00 O +ATOM 605 HW1 SOL 201 23.982 12.630 21.693 1.00 0.00 H +ATOM 606 HW2 SOL 201 24.210 11.143 21.237 1.00 0.00 H +ATOM 607 OW SOL 202 26.800 29.112 25.566 1.00 0.00 O +ATOM 608 HW1 SOL 202 26.671 30.102 25.515 1.00 0.00 H +ATOM 609 HW2 SOL 202 26.164 28.828 26.284 1.00 0.00 H +ATOM 610 OW SOL 203 26.261 24.860 10.711 1.00 0.00 O +ATOM 611 HW1 SOL 203 26.533 25.358 11.534 1.00 0.00 H +ATOM 612 HW2 SOL 203 27.110 24.432 10.402 1.00 0.00 H +ATOM 613 OW SOL 204 9.456 24.988 15.424 1.00 0.00 O +ATOM 614 HW1 SOL 204 10.300 24.942 15.958 1.00 0.00 H +ATOM 615 HW2 SOL 204 8.761 25.229 16.101 1.00 0.00 H +ATOM 616 OW SOL 205 21.383 27.255 22.046 1.00 0.00 O +ATOM 617 HW1 SOL 205 20.602 26.772 21.650 1.00 0.00 H +ATOM 618 HW2 SOL 205 22.099 26.558 22.080 1.00 0.00 H +ATOM 619 OW SOL 206 14.538 22.985 19.831 1.00 0.00 O +ATOM 620 HW1 SOL 206 13.872 23.579 20.283 1.00 0.00 H +ATOM 621 HW2 SOL 206 15.176 22.748 20.563 1.00 0.00 H +ATOM 622 OW SOL 207 12.256 23.724 21.874 1.00 0.00 O +ATOM 623 HW1 SOL 207 12.712 24.484 22.336 1.00 0.00 H +ATOM 624 HW2 SOL 207 12.160 23.034 22.592 1.00 0.00 H +ATOM 625 OW SOL 208 17.301 22.623 16.712 1.00 0.00 O +ATOM 626 HW1 SOL 208 16.786 22.266 15.933 1.00 0.00 H +ATOM 627 HW2 SOL 208 16.708 22.435 17.494 1.00 0.00 H +ATOM 628 OW SOL 209 27.289 17.023 25.562 1.00 0.00 O +ATOM 629 HW1 SOL 209 27.950 17.324 26.250 1.00 0.00 H +ATOM 630 HW2 SOL 209 26.475 16.802 26.098 1.00 0.00 H +ATOM 631 OW SOL 210 12.046 11.028 23.486 1.00 0.00 O +ATOM 632 HW1 SOL 210 12.209 11.923 23.901 1.00 0.00 H +ATOM 633 HW2 SOL 210 11.256 11.184 22.893 1.00 0.00 H +ATOM 634 OW SOL 211 12.971 23.755 12.904 1.00 0.00 O +ATOM 635 HW1 SOL 211 13.462 22.993 13.326 1.00 0.00 H +ATOM 636 HW2 SOL 211 12.946 23.511 11.935 1.00 0.00 H +ATOM 637 OW SOL 212 18.713 14.967 23.853 1.00 0.00 O +ATOM 638 HW1 SOL 212 18.097 15.333 23.155 1.00 0.00 H +ATOM 639 HW2 SOL 212 18.527 13.985 23.839 1.00 0.00 H +ATOM 640 OW SOL 213 17.844 16.429 18.517 1.00 0.00 O +ATOM 641 HW1 SOL 213 17.744 15.500 18.162 1.00 0.00 H +ATOM 642 HW2 SOL 213 16.981 16.870 18.271 1.00 0.00 H +ATOM 643 OW SOL 214 26.348 27.255 19.389 1.00 0.00 O +ATOM 644 HW1 SOL 214 26.764 27.895 18.744 1.00 0.00 H +ATOM 645 HW2 SOL 214 26.129 27.826 20.180 1.00 0.00 H +ATOM 646 OW SOL 215 19.468 25.203 11.319 1.00 0.00 O +ATOM 647 HW1 SOL 215 19.836 25.775 10.587 1.00 0.00 H +ATOM 648 HW2 SOL 215 20.233 24.606 11.560 1.00 0.00 H +ATOM 649 OW SOL 216 24.482 16.998 15.713 1.00 0.00 O +ATOM 650 HW1 SOL 216 23.782 16.352 15.411 1.00 0.00 H +ATOM 651 HW2 SOL 216 23.957 17.723 16.159 1.00 0.00 H +ATOM 652 OW SOL 217 22.863 24.643 26.438 1.00 0.00 O +ATOM 653 HW1 SOL 217 23.205 23.713 26.305 1.00 0.00 H +ATOM 654 HW2 SOL 217 23.295 24.934 27.291 1.00 0.00 H +ATOM 655 OW SOL 218 16.581 23.137 9.018 1.00 0.00 O +ATOM 656 HW1 SOL 218 15.746 22.632 9.233 1.00 0.00 H +ATOM 657 HW2 SOL 218 16.633 23.826 9.740 1.00 0.00 H +ATOM 658 OW SOL 219 12.098 27.383 14.371 1.00 0.00 O +ATOM 659 HW1 SOL 219 11.253 27.822 14.067 1.00 0.00 H +ATOM 660 HW2 SOL 219 12.162 26.569 13.793 1.00 0.00 H +ATOM 661 OW SOL 220 18.497 10.087 28.018 1.00 0.00 O +ATOM 662 HW1 SOL 220 19.198 10.734 28.318 1.00 0.00 H +ATOM 663 HW2 SOL 220 17.867 10.652 27.485 1.00 0.00 H +ATOM 664 OW SOL 221 23.758 24.161 29.453 1.00 0.00 O +ATOM 665 HW1 SOL 221 24.089 23.218 29.494 1.00 0.00 H +ATOM 666 HW2 SOL 221 24.587 24.695 29.288 1.00 0.00 H +ATOM 667 OW SOL 222 21.864 13.608 29.368 1.00 0.00 O +ATOM 668 HW1 SOL 222 21.386 12.750 29.559 1.00 0.00 H +ATOM 669 HW2 SOL 222 21.214 14.121 28.809 1.00 0.00 H +ATOM 670 OW SOL 223 29.881 27.987 21.278 1.00 0.00 O +ATOM 671 HW1 SOL 223 30.280 28.463 22.060 1.00 0.00 H +ATOM 672 HW2 SOL 223 28.896 28.064 21.433 1.00 0.00 H +ATOM 673 OW SOL 224 14.384 27.766 12.575 1.00 0.00 O +ATOM 674 HW1 SOL 224 13.656 27.745 13.259 1.00 0.00 H +ATOM 675 HW2 SOL 224 15.210 27.928 13.114 1.00 0.00 H +ATOM 676 OW SOL 225 17.381 25.415 12.307 1.00 0.00 O +ATOM 677 HW1 SOL 225 16.685 25.906 11.784 1.00 0.00 H +ATOM 678 HW2 SOL 225 17.361 24.493 11.919 1.00 0.00 H +ATOM 679 OW SOL 226 18.771 26.327 16.968 1.00 0.00 O +ATOM 680 HW1 SOL 226 19.165 26.197 17.878 1.00 0.00 H +ATOM 681 HW2 SOL 226 19.149 25.570 16.436 1.00 0.00 H +ATOM 682 OW SOL 227 26.894 25.793 22.690 1.00 0.00 O +ATOM 683 HW1 SOL 227 27.095 26.573 23.283 1.00 0.00 H +ATOM 684 HW2 SOL 227 26.892 25.014 23.317 1.00 0.00 H +ATOM 685 OW SOL 228 29.615 14.551 22.456 1.00 0.00 O +ATOM 686 HW1 SOL 228 29.405 13.573 22.445 1.00 0.00 H +ATOM 687 HW2 SOL 228 29.346 14.860 21.544 1.00 0.00 H +ATOM 688 OW SOL 229 14.566 25.605 27.425 1.00 0.00 O +ATOM 689 HW1 SOL 229 14.245 25.596 26.478 1.00 0.00 H +ATOM 690 HW2 SOL 229 15.214 24.844 27.462 1.00 0.00 H +ATOM 691 OW SOL 230 20.391 25.772 30.067 1.00 0.00 O +ATOM 692 HW1 SOL 230 21.375 25.748 29.888 1.00 0.00 H +ATOM 693 HW2 SOL 230 20.078 24.864 29.790 1.00 0.00 H +ATOM 694 OW SOL 231 23.233 14.897 21.299 1.00 0.00 O +ATOM 695 HW1 SOL 231 22.260 14.863 21.070 1.00 0.00 H +ATOM 696 HW2 SOL 231 23.269 14.533 22.230 1.00 0.00 H +ATOM 697 OW SOL 232 13.951 14.271 26.024 1.00 0.00 O +ATOM 698 HW1 SOL 232 13.866 15.163 26.468 1.00 0.00 H +ATOM 699 HW2 SOL 232 13.345 13.682 26.559 1.00 0.00 H +ATOM 700 OW SOL 233 28.373 27.959 24.651 1.00 0.00 O +ATOM 701 HW1 SOL 233 27.950 28.614 24.025 1.00 0.00 H +ATOM 702 HW2 SOL 233 28.738 27.253 24.044 1.00 0.00 H +ATOM 703 OW SOL 234 25.500 16.383 23.895 1.00 0.00 O +ATOM 704 HW1 SOL 234 25.500 17.138 23.239 1.00 0.00 H +ATOM 705 HW2 SOL 234 24.639 15.909 23.710 1.00 0.00 H +ATOM 706 OW SOL 235 28.002 12.440 13.022 1.00 0.00 O +ATOM 707 HW1 SOL 235 28.815 12.998 12.852 1.00 0.00 H +ATOM 708 HW2 SOL 235 28.343 11.502 12.958 1.00 0.00 H +ATOM 709 OW SOL 236 18.282 22.984 28.431 1.00 0.00 O +ATOM 710 HW1 SOL 236 17.839 22.956 27.535 1.00 0.00 H +ATOM 711 HW2 SOL 236 17.744 22.345 28.980 1.00 0.00 H +ATOM 712 OW SOL 237 15.334 10.807 19.052 1.00 0.00 O +ATOM 713 HW1 SOL 237 16.230 10.739 18.613 1.00 0.00 H +ATOM 714 HW2 SOL 237 15.543 10.729 20.027 1.00 0.00 H +ATOM 715 OW SOL 238 26.453 20.193 17.035 1.00 0.00 O +ATOM 716 HW1 SOL 238 27.285 19.738 16.718 1.00 0.00 H +ATOM 717 HW2 SOL 238 26.145 20.706 16.234 1.00 0.00 H +ATOM 718 OW SOL 239 10.845 27.204 26.439 1.00 0.00 O +ATOM 719 HW1 SOL 239 11.492 26.526 26.787 1.00 0.00 H +ATOM 720 HW2 SOL 239 10.226 27.356 27.209 1.00 0.00 H +ATOM 721 OW SOL 240 23.318 20.552 29.910 1.00 0.00 O +ATOM 722 HW1 SOL 240 23.322 19.973 29.095 1.00 0.00 H +ATOM 723 HW2 SOL 240 24.208 20.374 30.330 1.00 0.00 H +ATOM 724 OW SOL 241 12.360 11.799 19.506 1.00 0.00 O +ATOM 725 HW1 SOL 241 11.587 12.232 19.969 1.00 0.00 H +ATOM 726 HW2 SOL 241 12.913 11.439 20.258 1.00 0.00 H +ATOM 727 OW SOL 242 10.015 16.482 23.582 1.00 0.00 O +ATOM 728 HW1 SOL 242 9.278 17.021 23.174 1.00 0.00 H +ATOM 729 HW2 SOL 242 10.842 16.856 23.162 1.00 0.00 H +ATOM 730 OW SOL 243 24.378 12.205 18.326 1.00 0.00 O +ATOM 731 HW1 SOL 243 24.260 11.939 19.283 1.00 0.00 H +ATOM 732 HW2 SOL 243 24.465 11.331 17.848 1.00 0.00 H +ATOM 733 OW SOL 244 27.338 13.664 23.454 1.00 0.00 O +ATOM 734 HW1 SOL 244 28.230 13.837 23.870 1.00 0.00 H +ATOM 735 HW2 SOL 244 27.455 13.969 22.509 1.00 0.00 H +ATOM 736 OW SOL 245 16.940 13.384 31.601 1.00 0.00 O +ATOM 737 HW1 SOL 245 17.109 13.112 30.654 1.00 0.00 H +ATOM 738 HW2 SOL 245 17.669 12.928 32.111 1.00 0.00 H +ATOM 739 OW SOL 246 32.005 13.657 23.624 1.00 0.00 O +ATOM 740 HW1 SOL 246 32.257 13.911 24.558 1.00 0.00 H +ATOM 741 HW2 SOL 246 31.963 14.533 23.145 1.00 0.00 H +ATOM 742 OW SOL 247 28.888 16.640 31.052 1.00 0.00 O +ATOM 743 HW1 SOL 247 28.877 16.525 30.058 1.00 0.00 H +ATOM 744 HW2 SOL 247 28.475 17.540 31.190 1.00 0.00 H +ATOM 745 OW SOL 248 30.517 21.634 27.971 1.00 0.00 O +ATOM 746 HW1 SOL 248 30.413 20.686 27.671 1.00 0.00 H +ATOM 747 HW2 SOL 248 29.614 21.868 28.330 1.00 0.00 H +ATOM 748 OW SOL 249 29.278 25.405 14.874 1.00 0.00 O +ATOM 749 HW1 SOL 249 30.211 25.764 14.901 1.00 0.00 H +ATOM 750 HW2 SOL 249 28.781 25.992 15.513 1.00 0.00 H +ATOM 751 OW SOL 250 28.968 21.899 14.796 1.00 0.00 O +ATOM 752 HW1 SOL 250 28.346 22.644 14.559 1.00 0.00 H +ATOM 753 HW2 SOL 250 28.495 21.082 14.467 1.00 0.00 H +ATOM 754 OW SOL 251 14.191 11.981 16.094 1.00 0.00 O +ATOM 755 HW1 SOL 251 14.407 12.074 15.122 1.00 0.00 H +ATOM 756 HW2 SOL 251 14.275 10.999 16.261 1.00 0.00 H +ATOM 757 OW SOL 252 17.788 32.955 15.832 1.00 0.00 O +ATOM 758 HW1 SOL 252 17.315 32.902 14.953 1.00 0.00 H +ATOM 759 HW2 SOL 252 18.279 33.824 15.785 1.00 0.00 H +ATOM 760 OW SOL 253 14.053 32.614 18.037 1.00 0.00 O +ATOM 761 HW1 SOL 253 14.707 32.156 18.638 1.00 0.00 H +ATOM 762 HW2 SOL 253 13.297 32.849 18.647 1.00 0.00 H +ATOM 763 OW SOL 254 15.162 6.761 17.608 1.00 0.00 O +ATOM 764 HW1 SOL 254 16.124 6.787 17.336 1.00 0.00 H +ATOM 765 HW2 SOL 254 15.183 6.326 18.508 1.00 0.00 H +ATOM 766 OW SOL 255 23.403 24.435 19.289 1.00 0.00 O +ATOM 767 HW1 SOL 255 22.966 24.938 20.034 1.00 0.00 H +ATOM 768 HW2 SOL 255 24.203 24.019 19.721 1.00 0.00 H +ATOM 769 OW SOL 256 11.933 18.281 8.865 1.00 0.00 O +ATOM 770 HW1 SOL 256 12.169 18.288 7.894 1.00 0.00 H +ATOM 771 HW2 SOL 256 11.288 17.520 8.945 1.00 0.00 H +ATOM 772 OW SOL 257 17.352 17.223 12.875 1.00 0.00 O +ATOM 773 HW1 SOL 257 17.075 17.788 12.098 1.00 0.00 H +ATOM 774 HW2 SOL 257 16.594 16.579 12.980 1.00 0.00 H +ATOM 775 OW SOL 258 20.845 31.014 24.506 1.00 0.00 O +ATOM 776 HW1 SOL 258 21.494 30.971 23.747 1.00 0.00 H +ATOM 777 HW2 SOL 258 21.299 31.607 25.171 1.00 0.00 H +ATOM 778 OW SOL 259 16.173 30.639 14.579 1.00 0.00 O +ATOM 779 HW1 SOL 259 17.087 31.003 14.755 1.00 0.00 H +ATOM 780 HW2 SOL 259 15.597 31.456 14.545 1.00 0.00 H +ATOM 781 OW SOL 260 26.861 14.882 24.781 1.00 0.00 O +ATOM 782 HW1 SOL 260 27.331 15.619 24.295 1.00 0.00 H +ATOM 783 HW2 SOL 260 27.066 15.066 25.742 1.00 0.00 H +ATOM 784 OW SOL 261 20.147 18.767 8.642 1.00 0.00 O +ATOM 785 HW1 SOL 261 19.932 18.177 7.865 1.00 0.00 H +ATOM 786 HW2 SOL 261 19.754 18.282 9.423 1.00 0.00 H +ATOM 787 OW SOL 262 16.330 11.853 15.027 1.00 0.00 O +ATOM 788 HW1 SOL 262 16.561 11.180 15.729 1.00 0.00 H +ATOM 789 HW2 SOL 262 16.187 12.696 15.546 1.00 0.00 H +ATOM 790 OW SOL 263 19.998 14.127 14.342 1.00 0.00 O +ATOM 791 HW1 SOL 263 19.093 13.932 13.964 1.00 0.00 H +ATOM 792 HW2 SOL 263 20.377 14.802 13.709 1.00 0.00 H +ATOM 793 OW SOL 264 15.286 6.974 21.690 1.00 0.00 O +ATOM 794 HW1 SOL 264 14.490 6.733 21.134 1.00 0.00 H +ATOM 795 HW2 SOL 264 15.987 7.198 21.013 1.00 0.00 H +ATOM 796 OW SOL 265 22.572 20.878 22.776 1.00 0.00 O +ATOM 797 HW1 SOL 265 22.895 20.110 22.224 1.00 0.00 H +ATOM 798 HW2 SOL 265 21.659 21.062 22.413 1.00 0.00 H +ATOM 799 OW SOL 266 13.021 22.353 8.271 1.00 0.00 O +ATOM 800 HW1 SOL 266 13.103 21.539 7.695 1.00 0.00 H +ATOM 801 HW2 SOL 266 12.965 23.103 7.612 1.00 0.00 H +ATOM 802 OW SOL 267 29.306 12.539 20.816 1.00 0.00 O +ATOM 803 HW1 SOL 267 29.850 13.011 20.123 1.00 0.00 H +ATOM 804 HW2 SOL 267 29.587 11.583 20.726 1.00 0.00 H +ATOM 805 OW SOL 268 27.591 8.306 19.715 1.00 0.00 O +ATOM 806 HW1 SOL 268 26.981 8.960 20.162 1.00 0.00 H +ATOM 807 HW2 SOL 268 28.102 7.902 20.473 1.00 0.00 H +ATOM 808 OW SOL 269 14.625 19.150 27.877 1.00 0.00 O +ATOM 809 HW1 SOL 269 14.905 19.901 28.474 1.00 0.00 H +ATOM 810 HW2 SOL 269 14.485 18.387 28.507 1.00 0.00 H +ATOM 811 OW SOL 270 15.053 18.138 11.940 1.00 0.00 O +ATOM 812 HW1 SOL 270 14.083 18.294 12.126 1.00 0.00 H +ATOM 813 HW2 SOL 270 15.179 18.501 11.017 1.00 0.00 H +ATOM 814 OW SOL 271 20.480 10.066 25.281 1.00 0.00 O +ATOM 815 HW1 SOL 271 20.492 10.653 26.090 1.00 0.00 H +ATOM 816 HW2 SOL 271 20.115 9.200 25.622 1.00 0.00 H +ATOM 817 OW SOL 272 16.687 16.821 21.152 1.00 0.00 O +ATOM 818 HW1 SOL 272 17.392 17.113 20.506 1.00 0.00 H +ATOM 819 HW2 SOL 272 16.033 16.326 20.580 1.00 0.00 H +ATOM 820 OW SOL 273 20.496 9.997 18.857 1.00 0.00 O +ATOM 821 HW1 SOL 273 19.529 9.992 19.113 1.00 0.00 H +ATOM 822 HW2 SOL 273 20.580 10.799 18.267 1.00 0.00 H +ATOM 823 OW SOL 274 25.891 27.591 29.791 1.00 0.00 O +ATOM 824 HW1 SOL 274 25.008 27.972 30.067 1.00 0.00 H +ATOM 825 HW2 SOL 274 26.443 27.649 30.622 1.00 0.00 H +ATOM 826 OW SOL 275 10.510 26.690 23.469 1.00 0.00 O +ATOM 827 HW1 SOL 275 9.710 26.679 24.068 1.00 0.00 H +ATOM 828 HW2 SOL 275 11.238 27.046 24.054 1.00 0.00 H +ATOM 829 OW SOL 276 25.856 13.235 20.210 1.00 0.00 O +ATOM 830 HW1 SOL 276 26.425 12.798 19.514 1.00 0.00 H +ATOM 831 HW2 SOL 276 25.294 13.876 19.686 1.00 0.00 H +ATOM 832 OW SOL 277 10.188 21.626 13.254 1.00 0.00 O +ATOM 833 HW1 SOL 277 10.108 20.717 12.847 1.00 0.00 H +ATOM 834 HW2 SOL 277 10.441 21.439 14.203 1.00 0.00 H +ATOM 835 OW SOL 278 13.376 16.662 19.239 1.00 0.00 O +ATOM 836 HW1 SOL 278 12.555 16.358 18.757 1.00 0.00 H +ATOM 837 HW2 SOL 278 13.509 17.597 18.911 1.00 0.00 H +ATOM 838 OW SOL 279 19.716 33.214 25.227 1.00 0.00 O +ATOM 839 HW1 SOL 279 20.555 33.286 25.766 1.00 0.00 H +ATOM 840 HW2 SOL 279 18.992 33.211 25.917 1.00 0.00 H +ATOM 841 OW SOL 280 21.318 16.043 23.168 1.00 0.00 O +ATOM 842 HW1 SOL 280 20.740 15.644 22.456 1.00 0.00 H +ATOM 843 HW2 SOL 280 21.291 15.365 23.902 1.00 0.00 H +ATOM 844 OW SOL 281 29.072 25.241 18.007 1.00 0.00 O +ATOM 845 HW1 SOL 281 29.017 24.363 18.482 1.00 0.00 H +ATOM 846 HW2 SOL 281 28.392 25.159 17.279 1.00 0.00 H +ATOM 847 OW SOL 282 16.906 12.470 24.437 1.00 0.00 O +ATOM 848 HW1 SOL 282 16.760 13.426 24.688 1.00 0.00 H +ATOM 849 HW2 SOL 282 17.418 12.526 23.580 1.00 0.00 H +ATOM 850 OW SOL 283 11.005 16.545 20.975 1.00 0.00 O +ATOM 851 HW1 SOL 283 11.185 17.280 20.321 1.00 0.00 H +ATOM 852 HW2 SOL 283 11.645 15.826 20.704 1.00 0.00 H +ATOM 853 OW SOL 284 19.808 19.268 16.414 1.00 0.00 O +ATOM 854 HW1 SOL 284 18.955 18.964 16.838 1.00 0.00 H +ATOM 855 HW2 SOL 284 19.515 19.632 15.530 1.00 0.00 H +ATOM 856 OW SOL 285 19.928 17.083 32.305 1.00 0.00 O +ATOM 857 HW1 SOL 285 19.062 17.537 32.093 1.00 0.00 H +ATOM 858 HW2 SOL 285 20.282 16.821 31.407 1.00 0.00 H +ATOM 859 OW SOL 286 21.167 10.656 13.563 1.00 0.00 O +ATOM 860 HW1 SOL 286 22.068 10.422 13.199 1.00 0.00 H +ATOM 861 HW2 SOL 286 20.751 11.196 12.831 1.00 0.00 H +ATOM 862 OW SOL 287 25.467 23.335 16.932 1.00 0.00 O +ATOM 863 HW1 SOL 287 25.022 24.043 16.383 1.00 0.00 H +ATOM 864 HW2 SOL 287 25.864 22.722 16.249 1.00 0.00 H +ATOM 865 OW SOL 288 11.779 10.659 26.429 1.00 0.00 O +ATOM 866 HW1 SOL 288 11.727 9.775 25.964 1.00 0.00 H +ATOM 867 HW2 SOL 288 11.701 11.322 25.684 1.00 0.00 H +ATOM 868 OW SOL 289 20.631 25.552 23.948 1.00 0.00 O +ATOM 869 HW1 SOL 289 20.171 26.439 23.917 1.00 0.00 H +ATOM 870 HW2 SOL 289 21.576 25.768 23.702 1.00 0.00 H +ATOM 871 OW SOL 290 31.043 16.337 17.275 1.00 0.00 O +ATOM 872 HW1 SOL 290 31.810 15.800 17.627 1.00 0.00 H +ATOM 873 HW2 SOL 290 30.548 16.609 18.100 1.00 0.00 H +ATOM 874 OW SOL 291 12.491 25.394 18.555 1.00 0.00 O +ATOM 875 HW1 SOL 291 11.721 25.934 18.215 1.00 0.00 H +ATOM 876 HW2 SOL 291 12.354 24.497 18.136 1.00 0.00 H +ATOM 877 OW SOL 292 25.292 13.571 16.035 1.00 0.00 O +ATOM 878 HW1 SOL 292 25.055 12.601 16.090 1.00 0.00 H +ATOM 879 HW2 SOL 292 24.754 13.987 16.769 1.00 0.00 H +ATOM 880 OW SOL 293 9.792 18.248 17.146 1.00 0.00 O +ATOM 881 HW1 SOL 293 10.249 17.869 17.951 1.00 0.00 H +ATOM 882 HW2 SOL 293 9.494 17.438 16.641 1.00 0.00 H +ATOM 883 OW SOL 294 17.876 26.066 14.738 1.00 0.00 O +ATOM 884 HW1 SOL 294 18.251 26.859 15.218 1.00 0.00 H +ATOM 885 HW2 SOL 294 17.107 26.444 14.222 1.00 0.00 H +ATOM 886 OW SOL 295 13.351 26.592 29.897 1.00 0.00 O +ATOM 887 HW1 SOL 295 13.162 26.831 30.850 1.00 0.00 H +ATOM 888 HW2 SOL 295 12.534 26.092 29.613 1.00 0.00 H +ATOM 889 OW SOL 296 12.037 28.641 18.185 1.00 0.00 O +ATOM 890 HW1 SOL 296 12.138 29.311 18.919 1.00 0.00 H +ATOM 891 HW2 SOL 296 11.798 27.798 18.666 1.00 0.00 H +ATOM 892 OW SOL 297 13.949 14.903 14.018 1.00 0.00 O +ATOM 893 HW1 SOL 297 13.391 14.944 14.846 1.00 0.00 H +ATOM 894 HW2 SOL 297 13.286 15.029 13.280 1.00 0.00 H +ATOM 895 OW SOL 298 24.441 9.774 18.896 1.00 0.00 O +ATOM 896 HW1 SOL 298 24.484 8.795 18.698 1.00 0.00 H +ATOM 897 HW2 SOL 298 23.461 9.959 18.959 1.00 0.00 H +ATOM 898 OW SOL 299 24.825 20.625 13.710 1.00 0.00 O +ATOM 899 HW1 SOL 299 24.699 19.834 13.111 1.00 0.00 H +ATOM 900 HW2 SOL 299 24.759 21.405 13.087 1.00 0.00 H +ATOM 901 OW SOL 300 30.311 15.797 23.908 1.00 0.00 O +ATOM 902 HW1 SOL 300 30.013 16.347 23.128 1.00 0.00 H +ATOM 903 HW2 SOL 300 31.248 16.106 24.070 1.00 0.00 H +ATOM 904 OW SOL 301 14.689 25.210 19.062 1.00 0.00 O +ATOM 905 HW1 SOL 301 14.868 24.486 18.395 1.00 0.00 H +ATOM 906 HW2 SOL 301 15.310 25.943 18.787 1.00 0.00 H +ATOM 907 OW SOL 302 25.131 30.384 14.211 1.00 0.00 O +ATOM 908 HW1 SOL 302 25.229 30.043 15.146 1.00 0.00 H +ATOM 909 HW2 SOL 302 24.835 31.331 14.335 1.00 0.00 H +ATOM 910 OW SOL 303 26.817 28.630 15.931 1.00 0.00 O +ATOM 911 HW1 SOL 303 26.854 29.598 16.177 1.00 0.00 H +ATOM 912 HW2 SOL 303 27.762 28.323 16.039 1.00 0.00 H +ATOM 913 OW SOL 304 25.870 28.779 23.498 1.00 0.00 O +ATOM 914 HW1 SOL 304 26.007 28.035 24.152 1.00 0.00 H +ATOM 915 HW2 SOL 304 26.345 28.462 22.677 1.00 0.00 H +ATOM 916 OW SOL 305 21.224 20.028 20.919 1.00 0.00 O +ATOM 917 HW1 SOL 305 20.868 19.663 20.059 1.00 0.00 H +ATOM 918 HW2 SOL 305 21.455 19.210 21.445 1.00 0.00 H +ATOM 919 OW SOL 306 23.951 18.581 19.460 1.00 0.00 O +ATOM 920 HW1 SOL 306 24.755 18.081 19.139 1.00 0.00 H +ATOM 921 HW2 SOL 306 23.703 19.155 18.679 1.00 0.00 H +ATOM 922 OW SOL 307 14.745 23.638 10.984 1.00 0.00 O +ATOM 923 HW1 SOL 307 14.721 24.346 11.689 1.00 0.00 H +ATOM 924 HW2 SOL 307 14.730 22.785 11.506 1.00 0.00 H +ATOM 925 OW SOL 308 20.995 28.107 28.584 1.00 0.00 O +ATOM 926 HW1 SOL 308 21.030 29.030 28.201 1.00 0.00 H +ATOM 927 HW2 SOL 308 20.408 28.206 29.388 1.00 0.00 H +ATOM 928 OW SOL 309 21.468 30.225 29.577 1.00 0.00 O +ATOM 929 HW1 SOL 309 22.120 30.435 28.848 1.00 0.00 H +ATOM 930 HW2 SOL 309 20.824 30.989 29.546 1.00 0.00 H +ATOM 931 OW SOL 310 24.896 27.982 17.390 1.00 0.00 O +ATOM 932 HW1 SOL 310 25.409 28.790 17.677 1.00 0.00 H +ATOM 933 HW2 SOL 310 24.781 28.112 16.405 1.00 0.00 H +ATOM 934 OW SOL 311 10.694 13.902 19.257 1.00 0.00 O +ATOM 935 HW1 SOL 311 9.883 14.455 19.452 1.00 0.00 H +ATOM 936 HW2 SOL 311 11.300 14.094 20.029 1.00 0.00 H +ATOM 937 OW SOL 312 12.486 10.419 18.077 1.00 0.00 O +ATOM 938 HW1 SOL 312 11.824 11.058 17.686 1.00 0.00 H +ATOM 939 HW2 SOL 312 12.027 10.075 18.896 1.00 0.00 H +ATOM 940 OW SOL 313 21.726 12.250 26.675 1.00 0.00 O +ATOM 941 HW1 SOL 313 21.308 12.626 25.848 1.00 0.00 H +ATOM 942 HW2 SOL 313 21.836 13.048 27.268 1.00 0.00 H +ATOM 943 OW SOL 314 20.056 23.431 18.133 1.00 0.00 O +ATOM 944 HW1 SOL 314 19.555 24.081 17.561 1.00 0.00 H +ATOM 945 HW2 SOL 314 19.366 23.106 18.780 1.00 0.00 H +ATOM 946 OW SOL 315 8.353 22.549 12.108 1.00 0.00 O +ATOM 947 HW1 SOL 315 7.981 23.298 12.656 1.00 0.00 H +ATOM 948 HW2 SOL 315 8.381 21.780 12.747 1.00 0.00 H +ATOM 949 OW SOL 316 23.066 24.865 12.477 1.00 0.00 O +ATOM 950 HW1 SOL 316 23.923 24.801 11.966 1.00 0.00 H +ATOM 951 HW2 SOL 316 22.364 24.788 11.770 1.00 0.00 H +ATOM 952 OW SOL 317 21.609 21.802 31.335 1.00 0.00 O +ATOM 953 HW1 SOL 317 20.981 21.226 30.812 1.00 0.00 H +ATOM 954 HW2 SOL 317 22.229 22.167 30.639 1.00 0.00 H +ATOM 955 OW SOL 318 11.152 12.741 16.477 1.00 0.00 O +ATOM 956 HW1 SOL 318 10.489 13.482 16.374 1.00 0.00 H +ATOM 957 HW2 SOL 318 11.749 12.847 15.682 1.00 0.00 H +ATOM 958 OW SOL 319 16.479 19.355 30.032 1.00 0.00 O +ATOM 959 HW1 SOL 319 15.718 19.991 30.156 1.00 0.00 H +ATOM 960 HW2 SOL 319 17.195 19.922 29.624 1.00 0.00 H +ATOM 961 OW SOL 320 16.511 25.983 28.210 1.00 0.00 O +ATOM 962 HW1 SOL 320 15.788 26.358 28.790 1.00 0.00 H +ATOM 963 HW2 SOL 320 17.095 26.773 28.022 1.00 0.00 H +ATOM 964 OW SOL 321 11.555 9.180 21.060 1.00 0.00 O +ATOM 965 HW1 SOL 321 11.639 8.600 21.869 1.00 0.00 H +ATOM 966 HW2 SOL 321 12.093 9.990 21.293 1.00 0.00 H +ATOM 967 OW SOL 322 29.258 22.693 23.080 1.00 0.00 O +ATOM 968 HW1 SOL 322 28.713 23.180 23.763 1.00 0.00 H +ATOM 969 HW2 SOL 322 28.812 22.924 22.215 1.00 0.00 H +ATOM 970 OW SOL 323 15.293 7.604 25.247 1.00 0.00 O +ATOM 971 HW1 SOL 323 15.848 8.208 24.676 1.00 0.00 H +ATOM 972 HW2 SOL 323 14.580 7.280 24.626 1.00 0.00 H +ATOM 973 OW SOL 324 16.703 32.803 18.354 1.00 0.00 O +ATOM 974 HW1 SOL 324 16.126 33.380 18.931 1.00 0.00 H +ATOM 975 HW2 SOL 324 17.349 32.396 18.999 1.00 0.00 H +ATOM 976 OW SOL 325 13.842 12.645 18.127 1.00 0.00 O +ATOM 977 HW1 SOL 325 14.323 13.243 17.486 1.00 0.00 H +ATOM 978 HW2 SOL 325 12.897 12.662 17.801 1.00 0.00 H +ATOM 979 OW SOL 326 14.556 13.983 8.009 1.00 0.00 O +ATOM 980 HW1 SOL 326 14.206 14.169 8.926 1.00 0.00 H +ATOM 981 HW2 SOL 326 14.445 14.854 7.532 1.00 0.00 H +ATOM 982 OW SOL 327 27.488 22.281 18.419 1.00 0.00 O +ATOM 983 HW1 SOL 327 26.914 22.997 18.815 1.00 0.00 H +ATOM 984 HW2 SOL 327 27.033 21.434 18.693 1.00 0.00 H +ATOM 985 OW SOL 328 20.380 31.224 13.120 1.00 0.00 O +ATOM 986 HW1 SOL 328 20.139 30.588 13.853 1.00 0.00 H +ATOM 987 HW2 SOL 328 20.743 32.019 13.608 1.00 0.00 H +ATOM 988 OW SOL 329 28.233 19.659 23.418 1.00 0.00 O +ATOM 989 HW1 SOL 329 27.999 19.815 22.459 1.00 0.00 H +ATOM 990 HW2 SOL 329 28.599 18.729 23.424 1.00 0.00 H +ATOM 991 OW SOL 330 27.613 9.786 25.228 1.00 0.00 O +ATOM 992 HW1 SOL 330 28.516 9.582 25.605 1.00 0.00 H +ATOM 993 HW2 SOL 330 27.816 10.233 24.357 1.00 0.00 H +ATOM 994 OW SOL 331 26.953 11.666 23.287 1.00 0.00 O +ATOM 995 HW1 SOL 331 27.240 10.967 22.632 1.00 0.00 H +ATOM 996 HW2 SOL 331 26.091 12.004 22.908 1.00 0.00 H +ATOM 997 OW SOL 332 17.325 7.120 22.392 1.00 0.00 O +ATOM 998 HW1 SOL 332 17.426 8.040 22.770 1.00 0.00 H +ATOM 999 HW2 SOL 332 17.048 6.571 23.181 1.00 0.00 H +ATOM 1000 OW SOL 333 11.304 17.823 11.869 1.00 0.00 O +ATOM 1001 HW1 SOL 333 11.740 18.013 12.749 1.00 0.00 H +ATOM 1002 HW2 SOL 333 10.327 17.871 12.075 1.00 0.00 H +ATOM 1003 OW SOL 334 30.392 14.897 18.837 1.00 0.00 O +ATOM 1004 HW1 SOL 334 30.071 15.409 19.634 1.00 0.00 H +ATOM 1005 HW2 SOL 334 31.097 14.295 19.212 1.00 0.00 H +ATOM 1006 OW SOL 335 20.738 13.693 19.175 1.00 0.00 O +ATOM 1007 HW1 SOL 335 19.925 13.716 18.593 1.00 0.00 H +ATOM 1008 HW2 SOL 335 20.469 14.225 19.977 1.00 0.00 H +ATOM 1009 OW SOL 336 22.146 8.872 20.606 1.00 0.00 O +ATOM 1010 HW1 SOL 336 22.323 8.101 19.994 1.00 0.00 H +ATOM 1011 HW2 SOL 336 21.919 9.621 19.984 1.00 0.00 H +ATOM 1012 OW SOL 337 17.898 29.877 12.282 1.00 0.00 O +ATOM 1013 HW1 SOL 337 18.653 29.401 12.733 1.00 0.00 H +ATOM 1014 HW2 SOL 337 17.369 30.254 13.042 1.00 0.00 H +ATOM 1015 OW SOL 338 9.579 23.791 27.081 1.00 0.00 O +ATOM 1016 HW1 SOL 338 9.173 24.458 27.705 1.00 0.00 H +ATOM 1017 HW2 SOL 338 8.955 23.789 26.299 1.00 0.00 H +ATOM 1018 OW SOL 339 18.804 7.349 14.881 1.00 0.00 O +ATOM 1019 HW1 SOL 339 18.160 6.979 15.551 1.00 0.00 H +ATOM 1020 HW2 SOL 339 19.408 7.927 15.429 1.00 0.00 H +ATOM 1021 OW SOL 340 17.958 31.886 24.386 1.00 0.00 O +ATOM 1022 HW1 SOL 340 18.675 31.220 24.183 1.00 0.00 H +ATOM 1023 HW2 SOL 340 18.213 32.682 23.837 1.00 0.00 H +ATOM 1024 OW SOL 341 25.496 25.147 30.905 1.00 0.00 O +ATOM 1025 HW1 SOL 341 25.379 25.434 31.855 1.00 0.00 H +ATOM 1026 HW2 SOL 341 26.139 25.816 30.533 1.00 0.00 H +ATOM 1027 OW SOL 342 22.647 25.090 16.394 1.00 0.00 O +ATOM 1028 HW1 SOL 342 22.824 25.814 17.061 1.00 0.00 H +ATOM 1029 HW2 SOL 342 22.426 25.589 15.557 1.00 0.00 H +ATOM 1030 OW SOL 343 7.347 20.812 17.781 1.00 0.00 O +ATOM 1031 HW1 SOL 343 7.132 20.349 18.640 1.00 0.00 H +ATOM 1032 HW2 SOL 343 7.366 20.070 17.111 1.00 0.00 H +ATOM 1033 OW SOL 344 15.251 10.366 24.890 1.00 0.00 O +ATOM 1034 HW1 SOL 344 14.474 9.836 24.551 1.00 0.00 H +ATOM 1035 HW2 SOL 344 16.010 10.071 24.309 1.00 0.00 H +ATOM 1036 OW SOL 345 13.711 29.075 24.741 1.00 0.00 O +ATOM 1037 HW1 SOL 345 12.999 28.666 25.312 1.00 0.00 H +ATOM 1038 HW2 SOL 345 13.198 29.521 24.008 1.00 0.00 H +ATOM 1039 OW SOL 346 12.199 23.930 24.988 1.00 0.00 O +ATOM 1040 HW1 SOL 346 12.707 23.203 25.448 1.00 0.00 H +ATOM 1041 HW2 SOL 346 12.905 24.433 24.490 1.00 0.00 H +ATOM 1042 OW SOL 347 30.271 18.583 18.904 1.00 0.00 O +ATOM 1043 HW1 SOL 347 29.513 19.052 19.356 1.00 0.00 H +ATOM 1044 HW2 SOL 347 30.661 18.013 19.627 1.00 0.00 H +ATOM 1045 OW SOL 348 18.452 13.467 15.734 1.00 0.00 O +ATOM 1046 HW1 SOL 348 18.745 13.009 16.573 1.00 0.00 H +ATOM 1047 HW2 SOL 348 18.019 14.306 16.061 1.00 0.00 H +ATOM 1048 OW SOL 349 27.608 25.406 21.006 1.00 0.00 O +ATOM 1049 HW1 SOL 349 28.239 25.387 20.230 1.00 0.00 H +ATOM 1050 HW2 SOL 349 26.879 26.019 20.703 1.00 0.00 H +ATOM 1051 OW SOL 350 29.293 13.162 26.803 1.00 0.00 O +ATOM 1052 HW1 SOL 350 28.984 12.418 27.395 1.00 0.00 H +ATOM 1053 HW2 SOL 350 28.454 13.670 26.605 1.00 0.00 H +ATOM 1054 OW SOL 351 25.367 16.306 20.113 1.00 0.00 O +ATOM 1055 HW1 SOL 351 25.891 17.140 20.287 1.00 0.00 H +ATOM 1056 HW2 SOL 351 24.438 16.548 20.392 1.00 0.00 H +ATOM 1057 OW SOL 352 30.822 27.105 23.424 1.00 0.00 O +ATOM 1058 HW1 SOL 352 31.202 27.871 23.943 1.00 0.00 H +ATOM 1059 HW2 SOL 352 30.581 26.439 24.130 1.00 0.00 H +ATOM 1060 OW SOL 353 23.941 14.747 25.295 1.00 0.00 O +ATOM 1061 HW1 SOL 353 24.843 15.162 25.416 1.00 0.00 H +ATOM 1062 HW2 SOL 353 23.374 15.211 25.975 1.00 0.00 H +ATOM 1063 OW SOL 354 13.604 17.251 21.190 1.00 0.00 O +ATOM 1064 HW1 SOL 354 12.826 17.862 21.334 1.00 0.00 H +ATOM 1065 HW2 SOL 354 13.569 16.634 21.976 1.00 0.00 H +ATOM 1066 OW SOL 355 18.949 7.925 24.760 1.00 0.00 O +ATOM 1067 HW1 SOL 355 19.061 8.403 23.889 1.00 0.00 H +ATOM 1068 HW2 SOL 355 17.959 7.917 24.900 1.00 0.00 H +ATOM 1069 OW SOL 356 8.916 14.706 23.338 1.00 0.00 O +ATOM 1070 HW1 SOL 356 9.277 14.271 24.163 1.00 0.00 H +ATOM 1071 HW2 SOL 356 8.325 15.430 23.693 1.00 0.00 H +ATOM 1072 OW SOL 357 26.796 12.444 17.183 1.00 0.00 O +ATOM 1073 HW1 SOL 357 27.461 12.928 16.616 1.00 0.00 H +ATOM 1074 HW2 SOL 357 26.186 13.168 17.503 1.00 0.00 H +ATOM 1075 OW SOL 358 13.234 9.422 15.555 1.00 0.00 O +ATOM 1076 HW1 SOL 358 12.639 9.431 16.359 1.00 0.00 H +ATOM 1077 HW2 SOL 358 12.597 9.516 14.790 1.00 0.00 H +ATOM 1078 OW SOL 359 16.066 17.405 24.928 1.00 0.00 O +ATOM 1079 HW1 SOL 359 15.432 17.970 24.400 1.00 0.00 H +ATOM 1080 HW2 SOL 359 15.787 17.561 25.875 1.00 0.00 H +ATOM 1081 OW SOL 360 18.659 24.815 26.775 1.00 0.00 O +ATOM 1082 HW1 SOL 360 19.219 24.209 27.339 1.00 0.00 H +ATOM 1083 HW2 SOL 360 18.065 25.272 27.437 1.00 0.00 H +ATOM 1084 OW SOL 361 10.600 13.243 25.686 1.00 0.00 O +ATOM 1085 HW1 SOL 361 11.333 13.874 25.432 1.00 0.00 H +ATOM 1086 HW2 SOL 361 10.318 12.846 24.812 1.00 0.00 H +ATOM 1087 OW SOL 362 10.012 29.575 16.524 1.00 0.00 O +ATOM 1088 HW1 SOL 362 9.500 29.086 15.818 1.00 0.00 H +ATOM 1089 HW2 SOL 362 10.877 29.798 16.075 1.00 0.00 H +ATOM 1090 OW SOL 363 23.586 27.355 19.055 1.00 0.00 O +ATOM 1091 HW1 SOL 363 24.502 26.964 18.967 1.00 0.00 H +ATOM 1092 HW2 SOL 363 23.752 28.341 19.077 1.00 0.00 H +ATOM 1093 OW SOL 364 9.635 19.206 24.800 1.00 0.00 O +ATOM 1094 HW1 SOL 364 9.097 19.827 25.370 1.00 0.00 H +ATOM 1095 HW2 SOL 364 10.251 18.762 25.452 1.00 0.00 H +ATOM 1096 OW SOL 365 14.658 26.293 14.899 1.00 0.00 O +ATOM 1097 HW1 SOL 365 14.872 25.976 13.975 1.00 0.00 H +ATOM 1098 HW2 SOL 365 15.201 27.127 14.994 1.00 0.00 H +ATOM 1099 OW SOL 366 13.759 14.754 20.145 1.00 0.00 O +ATOM 1100 HW1 SOL 366 13.554 14.035 19.482 1.00 0.00 H +ATOM 1101 HW2 SOL 366 14.756 14.731 20.219 1.00 0.00 H +ATOM 1102 OW SOL 367 12.001 14.814 10.866 1.00 0.00 O +ATOM 1103 HW1 SOL 367 12.869 14.379 10.626 1.00 0.00 H +ATOM 1104 HW2 SOL 367 11.604 15.053 9.980 1.00 0.00 H +ATOM 1105 OW SOL 368 18.668 20.118 8.220 1.00 0.00 O +ATOM 1106 HW1 SOL 368 17.814 20.193 8.735 1.00 0.00 H +ATOM 1107 HW2 SOL 368 18.404 19.611 7.399 1.00 0.00 H +ATOM 1108 OW SOL 369 23.926 13.005 24.371 1.00 0.00 O +ATOM 1109 HW1 SOL 369 23.334 13.133 23.575 1.00 0.00 H +ATOM 1110 HW2 SOL 369 24.838 12.905 23.974 1.00 0.00 H +ATOM 1111 OW SOL 370 23.517 7.462 17.110 1.00 0.00 O +ATOM 1112 HW1 SOL 370 24.488 7.690 17.189 1.00 0.00 H +ATOM 1113 HW2 SOL 370 23.088 8.336 16.880 1.00 0.00 H +ATOM 1114 OW SOL 371 26.357 18.637 14.769 1.00 0.00 O +ATOM 1115 HW1 SOL 371 26.316 19.578 14.433 1.00 0.00 H +ATOM 1116 HW2 SOL 371 27.258 18.319 14.472 1.00 0.00 H +ATOM 1117 OW SOL 372 21.116 28.517 20.056 1.00 0.00 O +ATOM 1118 HW1 SOL 372 20.534 27.824 19.631 1.00 0.00 H +ATOM 1119 HW2 SOL 372 21.533 28.985 19.277 1.00 0.00 H +ATOM 1120 OW SOL 373 27.604 11.145 20.199 1.00 0.00 O +ATOM 1121 HW1 SOL 373 27.072 11.634 20.889 1.00 0.00 H +ATOM 1122 HW2 SOL 373 28.093 10.450 20.726 1.00 0.00 H +ATOM 1123 OW SOL 374 11.692 16.705 31.095 1.00 0.00 O +ATOM 1124 HW1 SOL 374 10.808 16.892 30.666 1.00 0.00 H +ATOM 1125 HW2 SOL 374 12.254 16.366 30.340 1.00 0.00 H +ATOM 1126 OW SOL 375 17.350 29.821 30.443 1.00 0.00 O +ATOM 1127 HW1 SOL 375 17.988 29.961 29.686 1.00 0.00 H +ATOM 1128 HW2 SOL 375 17.740 29.048 30.941 1.00 0.00 H +ATOM 1129 OW SOL 376 16.689 13.349 21.122 1.00 0.00 O +ATOM 1130 HW1 SOL 376 16.772 12.656 21.838 1.00 0.00 H +ATOM 1131 HW2 SOL 376 16.237 14.113 21.584 1.00 0.00 H +ATOM 1132 OW SOL 377 15.870 18.012 32.581 1.00 0.00 O +ATOM 1133 HW1 SOL 377 15.987 18.011 31.588 1.00 0.00 H +ATOM 1134 HW2 SOL 377 16.784 17.796 32.926 1.00 0.00 H +ATOM 1135 OW SOL 378 18.304 16.070 15.111 1.00 0.00 O +ATOM 1136 HW1 SOL 378 18.299 17.006 14.760 1.00 0.00 H +ATOM 1137 HW2 SOL 378 17.907 15.536 14.364 1.00 0.00 H +ATOM 1138 OW SOL 379 18.903 20.198 10.486 1.00 0.00 O +ATOM 1139 HW1 SOL 379 19.030 19.297 10.901 1.00 0.00 H +ATOM 1140 HW2 SOL 379 19.667 20.733 10.846 1.00 0.00 H +ATOM 1141 OW SOL 380 22.502 15.710 17.837 1.00 0.00 O +ATOM 1142 HW1 SOL 380 22.313 15.970 18.784 1.00 0.00 H +ATOM 1143 HW2 SOL 380 22.606 16.588 17.368 1.00 0.00 H +ATOM 1144 OW SOL 381 29.683 30.062 19.831 1.00 0.00 O +ATOM 1145 HW1 SOL 381 29.674 29.784 20.792 1.00 0.00 H +ATOM 1146 HW2 SOL 381 28.829 30.570 19.724 1.00 0.00 H +ATOM 1147 OW SOL 382 26.170 27.205 27.204 1.00 0.00 O +ATOM 1148 HW1 SOL 382 26.836 26.494 27.429 1.00 0.00 H +ATOM 1149 HW2 SOL 382 25.555 27.210 27.993 1.00 0.00 H +ATOM 1150 OW SOL 383 16.106 13.386 18.542 1.00 0.00 O +ATOM 1151 HW1 SOL 383 16.962 13.868 18.728 1.00 0.00 H +ATOM 1152 HW2 SOL 383 15.997 12.785 19.334 1.00 0.00 H +ATOM 1153 OW SOL 384 18.518 21.201 17.289 1.00 0.00 O +ATOM 1154 HW1 SOL 384 18.236 20.768 16.433 1.00 0.00 H +ATOM 1155 HW2 SOL 384 19.194 21.879 17.000 1.00 0.00 H +ATOM 1156 OW SOL 385 27.338 17.916 28.534 1.00 0.00 O +ATOM 1157 HW1 SOL 385 27.345 17.201 29.232 1.00 0.00 H +ATOM 1158 HW2 SOL 385 27.179 18.754 29.056 1.00 0.00 H +ATOM 1159 OW SOL 386 22.872 26.440 9.393 1.00 0.00 O +ATOM 1160 HW1 SOL 386 22.770 25.847 10.192 1.00 0.00 H +ATOM 1161 HW2 SOL 386 22.487 27.312 9.696 1.00 0.00 H +ATOM 1162 OW SOL 387 26.300 16.482 16.316 1.00 0.00 O +ATOM 1163 HW1 SOL 387 25.677 16.528 17.097 1.00 0.00 H +ATOM 1164 HW2 SOL 387 25.909 15.761 15.744 1.00 0.00 H +ATOM 1165 OW SOL 388 25.715 22.803 30.761 1.00 0.00 O +ATOM 1166 HW1 SOL 388 26.272 21.975 30.708 1.00 0.00 H +ATOM 1167 HW2 SOL 388 26.349 23.531 30.501 1.00 0.00 H +ATOM 1168 OW SOL 389 24.335 9.089 13.169 1.00 0.00 O +ATOM 1169 HW1 SOL 389 24.710 8.808 14.052 1.00 0.00 H +ATOM 1170 HW2 SOL 389 24.584 8.337 12.558 1.00 0.00 H +ATOM 1171 OW SOL 390 19.492 13.050 28.693 1.00 0.00 O +ATOM 1172 HW1 SOL 390 18.690 12.532 28.990 1.00 0.00 H +ATOM 1173 HW2 SOL 390 19.954 12.428 28.062 1.00 0.00 H +ATOM 1174 OW SOL 391 15.319 18.192 20.811 1.00 0.00 O +ATOM 1175 HW1 SOL 391 15.078 18.658 19.960 1.00 0.00 H +ATOM 1176 HW2 SOL 391 16.106 18.708 21.148 1.00 0.00 H +ATOM 1177 OW SOL 392 10.011 10.867 21.045 1.00 0.00 O +ATOM 1178 HW1 SOL 392 10.224 10.284 20.261 1.00 0.00 H +ATOM 1179 HW2 SOL 392 9.590 11.674 20.630 1.00 0.00 H +ATOM 1180 OW SOL 393 29.350 11.459 25.227 1.00 0.00 O +ATOM 1181 HW1 SOL 393 30.300 11.760 25.311 1.00 0.00 H +ATOM 1182 HW2 SOL 393 29.123 11.659 24.275 1.00 0.00 H +ATOM 1183 OW SOL 394 12.469 18.947 30.412 1.00 0.00 O +ATOM 1184 HW1 SOL 394 11.739 19.586 30.172 1.00 0.00 H +ATOM 1185 HW2 SOL 394 12.924 18.769 29.540 1.00 0.00 H +ATOM 1186 OW SOL 395 27.922 15.175 20.298 1.00 0.00 O +ATOM 1187 HW1 SOL 395 27.229 15.856 20.059 1.00 0.00 H +ATOM 1188 HW2 SOL 395 27.389 14.420 20.680 1.00 0.00 H +ATOM 1189 OW SOL 396 16.812 9.336 28.303 1.00 0.00 O +ATOM 1190 HW1 SOL 396 16.960 9.171 29.278 1.00 0.00 H +ATOM 1191 HW2 SOL 396 16.286 8.540 28.006 1.00 0.00 H +ATOM 1192 OW SOL 397 15.418 29.692 28.828 1.00 0.00 O +ATOM 1193 HW1 SOL 397 16.073 30.447 28.800 1.00 0.00 H +ATOM 1194 HW2 SOL 397 15.156 29.643 29.792 1.00 0.00 H +ATOM 1195 OW SOL 398 27.811 30.191 14.603 1.00 0.00 O +ATOM 1196 HW1 SOL 398 27.420 31.110 14.628 1.00 0.00 H +ATOM 1197 HW2 SOL 398 27.684 29.906 13.653 1.00 0.00 H +ATOM 1198 OW SOL 399 11.736 20.569 9.793 1.00 0.00 O +ATOM 1199 HW1 SOL 399 11.736 20.456 8.800 1.00 0.00 H +ATOM 1200 HW2 SOL 399 10.834 20.237 10.069 1.00 0.00 H +ATOM 1201 OW SOL 400 15.485 14.225 11.483 1.00 0.00 O +ATOM 1202 HW1 SOL 400 15.008 14.268 10.605 1.00 0.00 H +ATOM 1203 HW2 SOL 400 16.443 14.371 11.237 1.00 0.00 H +ATOM 1204 OW SOL 401 12.709 30.471 13.919 1.00 0.00 O +ATOM 1205 HW1 SOL 401 11.788 30.503 14.307 1.00 0.00 H +ATOM 1206 HW2 SOL 401 13.084 29.615 14.272 1.00 0.00 H +ATOM 1207 OW SOL 402 31.111 20.994 19.932 1.00 0.00 O +ATOM 1208 HW1 SOL 402 31.576 21.475 20.675 1.00 0.00 H +ATOM 1209 HW2 SOL 402 30.467 20.394 20.407 1.00 0.00 H +ATOM 1210 OW SOL 403 24.062 30.747 23.377 1.00 0.00 O +ATOM 1211 HW1 SOL 403 24.332 31.552 23.905 1.00 0.00 H +ATOM 1212 HW2 SOL 403 24.483 30.900 22.483 1.00 0.00 H +ATOM 1213 OW SOL 404 18.431 11.951 18.140 1.00 0.00 O +ATOM 1214 HW1 SOL 404 17.742 11.640 17.485 1.00 0.00 H +ATOM 1215 HW2 SOL 404 17.895 12.194 18.948 1.00 0.00 H +ATOM 1216 OW SOL 405 16.283 31.157 26.623 1.00 0.00 O +ATOM 1217 HW1 SOL 405 16.910 31.868 26.305 1.00 0.00 H +ATOM 1218 HW2 SOL 405 16.305 30.478 25.890 1.00 0.00 H +ATOM 1219 OW SOL 406 18.803 21.710 12.232 1.00 0.00 O +ATOM 1220 HW1 SOL 406 18.994 22.675 12.415 1.00 0.00 H +ATOM 1221 HW2 SOL 406 17.880 21.581 12.593 1.00 0.00 H +ATOM 1222 OW SOL 407 11.286 24.629 11.978 1.00 0.00 O +ATOM 1223 HW1 SOL 407 10.390 25.020 12.189 1.00 0.00 H +ATOM 1224 HW2 SOL 407 11.927 25.339 12.271 1.00 0.00 H +ATOM 1225 OW SOL 408 25.149 18.535 17.370 1.00 0.00 O +ATOM 1226 HW1 SOL 408 25.862 18.381 16.686 1.00 0.00 H +ATOM 1227 HW2 SOL 408 24.761 19.420 17.110 1.00 0.00 H +ATOM 1228 OW SOL 409 19.328 20.068 13.042 1.00 0.00 O +ATOM 1229 HW1 SOL 409 18.576 19.495 12.717 1.00 0.00 H +ATOM 1230 HW2 SOL 409 19.812 19.477 13.687 1.00 0.00 H +ATOM 1231 OW SOL 410 21.237 25.471 27.521 1.00 0.00 O +ATOM 1232 HW1 SOL 410 21.435 24.646 28.050 1.00 0.00 H +ATOM 1233 HW2 SOL 410 20.625 25.992 28.116 1.00 0.00 H +ATOM 1234 OW SOL 411 12.074 20.398 27.067 1.00 0.00 O +ATOM 1235 HW1 SOL 411 12.603 19.796 27.664 1.00 0.00 H +ATOM 1236 HW2 SOL 411 11.489 20.905 27.700 1.00 0.00 H +ATOM 1237 OW SOL 412 13.812 21.589 25.906 1.00 0.00 O +ATOM 1238 HW1 SOL 412 12.974 21.098 25.669 1.00 0.00 H +ATOM 1239 HW2 SOL 412 14.451 20.860 26.151 1.00 0.00 H +ATOM 1240 OW SOL 413 25.688 30.704 27.010 1.00 0.00 O +ATOM 1241 HW1 SOL 413 25.097 30.864 26.221 1.00 0.00 H +ATOM 1242 HW2 SOL 413 25.225 31.186 27.754 1.00 0.00 H +ATOM 1243 OW SOL 414 13.208 18.032 32.434 1.00 0.00 O +ATOM 1244 HW1 SOL 414 14.078 18.249 31.993 1.00 0.00 H +ATOM 1245 HW2 SOL 414 12.655 18.852 32.282 1.00 0.00 H +ATOM 1246 OW SOL 415 7.108 16.434 22.080 1.00 0.00 O +ATOM 1247 HW1 SOL 415 7.484 17.358 22.011 1.00 0.00 H +ATOM 1248 HW2 SOL 415 7.761 15.875 21.567 1.00 0.00 H +ATOM 1249 OW SOL 416 14.774 20.761 17.474 1.00 0.00 O +ATOM 1250 HW1 SOL 416 14.703 19.946 18.048 1.00 0.00 H +ATOM 1251 HW2 SOL 416 15.365 20.469 16.722 1.00 0.00 H +ATOM 1252 OW SOL 417 25.788 20.505 20.425 1.00 0.00 O +ATOM 1253 HW1 SOL 417 24.806 20.348 20.318 1.00 0.00 H +ATOM 1254 HW2 SOL 417 26.199 19.650 20.108 1.00 0.00 H +ATOM 1255 OW SOL 418 9.167 20.054 18.678 1.00 0.00 O +ATOM 1256 HW1 SOL 418 8.771 19.152 18.849 1.00 0.00 H +ATOM 1257 HW2 SOL 418 10.121 19.854 18.456 1.00 0.00 H +ATOM 1258 OW SOL 419 9.447 26.979 21.497 1.00 0.00 O +ATOM 1259 HW1 SOL 419 9.976 26.656 20.713 1.00 0.00 H +ATOM 1260 HW2 SOL 419 8.504 26.750 21.255 1.00 0.00 H +ATOM 1261 OW SOL 420 18.650 8.256 26.647 1.00 0.00 O +ATOM 1262 HW1 SOL 420 19.333 8.559 27.311 1.00 0.00 H +ATOM 1263 HW2 SOL 420 18.178 9.099 26.392 1.00 0.00 H +ATOM 1264 OW SOL 421 15.908 15.453 17.743 1.00 0.00 O +ATOM 1265 HW1 SOL 421 15.775 14.632 17.188 1.00 0.00 H +ATOM 1266 HW2 SOL 421 15.282 15.322 18.512 1.00 0.00 H +ATOM 1267 OW SOL 422 11.188 23.471 19.185 1.00 0.00 O +ATOM 1268 HW1 SOL 422 11.046 23.246 18.221 1.00 0.00 H +ATOM 1269 HW2 SOL 422 10.980 22.615 19.659 1.00 0.00 H +ATOM 1270 OW SOL 423 29.510 25.440 22.026 1.00 0.00 O +ATOM 1271 HW1 SOL 423 28.759 25.853 22.540 1.00 0.00 H +ATOM 1272 HW2 SOL 423 29.659 24.566 22.487 1.00 0.00 H +ATOM 1273 OW SOL 424 15.725 17.515 14.579 1.00 0.00 O +ATOM 1274 HW1 SOL 424 15.688 18.487 14.813 1.00 0.00 H +ATOM 1275 HW2 SOL 424 16.285 17.119 15.307 1.00 0.00 H +ATOM 1276 OW SOL 425 18.623 29.156 26.325 1.00 0.00 O +ATOM 1277 HW1 SOL 425 18.714 29.852 25.612 1.00 0.00 H +ATOM 1278 HW2 SOL 425 18.470 28.311 25.812 1.00 0.00 H +ATOM 1279 OW SOL 426 21.211 9.001 15.334 1.00 0.00 O +ATOM 1280 HW1 SOL 426 20.960 8.753 14.399 1.00 0.00 H +ATOM 1281 HW2 SOL 426 21.147 9.998 15.339 1.00 0.00 H +ATOM 1282 OW SOL 427 19.904 17.241 23.554 1.00 0.00 O +ATOM 1283 HW1 SOL 427 19.290 16.757 22.932 1.00 0.00 H +ATOM 1284 HW2 SOL 427 19.962 16.637 24.348 1.00 0.00 H +ATOM 1285 OW SOL 428 21.748 11.771 22.640 1.00 0.00 O +ATOM 1286 HW1 SOL 428 21.852 12.618 22.120 1.00 0.00 H +ATOM 1287 HW2 SOL 428 21.788 12.072 23.593 1.00 0.00 H +ATOM 1288 OW SOL 429 24.392 10.424 15.644 1.00 0.00 O +ATOM 1289 HW1 SOL 429 25.310 10.820 15.617 1.00 0.00 H +ATOM 1290 HW2 SOL 429 23.962 10.771 14.811 1.00 0.00 H +ATOM 1291 OW SOL 430 10.495 24.796 24.754 1.00 0.00 O +ATOM 1292 HW1 SOL 430 9.585 25.143 24.981 1.00 0.00 H +ATOM 1293 HW2 SOL 430 11.113 25.458 25.178 1.00 0.00 H +ATOM 1294 OW SOL 431 25.149 15.809 11.203 1.00 0.00 O +ATOM 1295 HW1 SOL 431 24.365 15.298 10.851 1.00 0.00 H +ATOM 1296 HW2 SOL 431 24.776 16.298 11.992 1.00 0.00 H +ATOM 1297 OW SOL 432 22.707 30.090 25.598 1.00 0.00 O +ATOM 1298 HW1 SOL 432 22.038 29.827 26.292 1.00 0.00 H +ATOM 1299 HW2 SOL 432 23.157 30.890 25.995 1.00 0.00 H +TER +ENDMDL diff --git a/examples/graph_adaptive_dm_scf_sp2/input.in b/examples/graph_adaptive_dm_scf_sp2/input.in index 76da89e..fadc183 100644 --- a/examples/graph_adaptive_dm_scf_sp2/input.in +++ b/examples/graph_adaptive_dm_scf_sp2/input.in @@ -2,10 +2,10 @@ Verbosity= True Threshold= 1.0E-7 -#CoordsFile= coords_1299.pdb +CoordsFile= coords_1299.pdb #CoordsFile= wat.xyz #CoordsFile= algo.xyz -CoordsFile= coords_2955.pdb +#CoordsFile= coords_2955.pdb GraphThreshold= 0.01 MaxDeg= 500 #Max graph degree Rcut= 4.0 #Radius cutoff @@ -17,8 +17,8 @@ SCFTol= 1.0E-1 Overlap= False ElectronicTemperature= 0 MuCalculationType= #FromParts, Dynamical, None -Orbitals= {"H":1,"O":4} #This has to be know for each engine +Orbitals= {"O":4,"H":1} #This has to be know for each engine NumAdaptiveIter= 100 #Number of graph adaptive iterations -Engine= {"Name":"ProxyAPython","InterfaceType":"Module","Path":"/home/cnegre/sedacs-Qi/proxies/python/","Executable":"/home/cnegre/","RhoSolverMethod":"SP2","Accelerator":"TC","AcceleratorPath":"/home/finkeljo/vescratch/sedacs-gpmdsp2/src/sedacs/gpu/nvda"} #The name of the external code +Engine= {"Name":"ProxyAPython","InterfaceType":"Module","Path":"/home/cnegre/sedacs-Qi/proxies/python/","Executable":"/home/cnegre/","RhoSolverMethod":"SP2","Accelerator":"No","AcceleratorPath":"/home/cheng-hanli/github/sedacs_to_merge/src/sedacs/gpu/nvda"} #The name of the external code #Engine= {"Name":"ProxyAFortran","InterfaceType":"Module","Path":"/home/cnegre/sedacs-Qi/proxies/fortran/","Executable":"/home/cnegre/"} #The name of the external code diff --git a/examples/graph_adaptive_dm_scf_sp2/main.py b/examples/graph_adaptive_dm_scf_sp2/main.py index 74d1cb4..75d20a1 100644 --- a/examples/graph_adaptive_dm_scf_sp2/main.py +++ b/examples/graph_adaptive_dm_scf_sp2/main.py @@ -6,7 +6,7 @@ import sys import numpy as np -from sedacs.driver.graph_adaptive_scf import get_adaptiveSCFDM +from sedacs.driver.graph_adaptive_scf_sp2 import get_adaptiveSCFDM from sedacs.driver.init import get_args, init from sedacs.charges import get_charges import sedacs.globals as gl @@ -23,8 +23,9 @@ sdc.verb = True +mu = 0.0 # Perform a graph-adaptive calculation of the density matrix -graphDH,sy.charges,parts,subSysOnRank = get_adaptiveSCFDM(sdc, eng, comm, rank, numranks, sy, hindex, graphNL) +graphDH,sy.charges,parts,subSysOnRank = get_adaptiveSCFDM(sdc, eng, comm, rank, numranks, sy, hindex, graphNL, mu) #sy.energy,sy.forces = get_energy_and_forces(sdc, eng, comm, rank, numranks, sy, hindex, graphDH) diff --git a/examples/graph_adaptive_dm_scf_sp2/vars b/examples/graph_adaptive_dm_scf_sp2/vars index c611679..4609046 100644 --- a/examples/graph_adaptive_dm_scf_sp2/vars +++ b/examples/graph_adaptive_dm_scf_sp2/vars @@ -1,7 +1,6 @@ #!/bin/bash THIS_PATH=`pwd` export PYTHONPATH="" -MOD_PATH=$THIS_PATH/../../src/sedacs/ MOD_PATH1=$THIS_PATH/../../src/ MOD_PATH2=$THIS_PATH/../../src/sedacs/driver PROXYA_FORTRAN_PATH=$THIS_PATH/../../proxies/fortran/build/ @@ -11,7 +10,7 @@ PROGRESS_PATH=$HOME/qmd-progress/install/lib64/ BML_PATH=$HOME/bml/install/lib64/ export PROXYA_FORTRAN_PATH=$PROXYA_FORTRAN_PATH export PROXYA_PYTHON_PATH=$PROXYA_PYTHON_PATH -export PYTHONPATH=$PYTHONPATH:$MOD_PATH:$MOD_PATH1:$MOD_PATH2:$PROGRESS_PATH:$BML_PATH:$PROXYA_PYTHON_FOLDER:$PROXYA_PYTHON_FILES:$PROXYA_FORTRAN_PATH +export PYTHONPATH=$PYTHONPATH:$MOD_PATH1:$MOD_PATH2:$PROGRESS_PATH:$BML_PATH:$PROXYA_PYTHON_FOLDER:$PROXYA_PYTHON_FILES:$PROXYA_FORTRAN_PATH export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PROGRESS_PATH:$BML_PATH export PYTHONWARNINGS="ignore:Unverified HTTPS request" diff --git a/src/sedacs/driver/graph_adaptive_scf_sp2.py b/src/sedacs/driver/graph_adaptive_scf_sp2.py new file mode 100644 index 0000000..206cf0f --- /dev/null +++ b/src/sedacs/driver/graph_adaptive_scf_sp2.py @@ -0,0 +1,329 @@ +""" +graph_adaptive_scf.py +==================================== +Graph adaptive self-consistent charge solver + +""" + +import time +import numpy as np +from pathlib import Path +import pickle + +from sedacs.graph import add_graphs, collect_graph_from_rho, print_graph, multiply_graphs +from sedacs.graph_partition import get_coreHaloIndices, graph_partition +from sedacs.sdc_hamiltonian import get_hamiltonian +from sedacs.sdc_density_matrix import get_density_matrix +from sedacs.sdc_evals_dvals import get_evals_dvals +from sedacs.file_io import write_pdb_coordinates, write_xyz_coordinates +from sedacs.mpi import ( + collect_and_sum_matrices, + collect_and_sum_vectors_float, + collect_and_concatenate_vectors, +) +from sedacs.system import System, extract_subsystem, get_hindex +from sedacs.coulombic import get_PME_coulvs, build_coul_ham +from sedacs.charges import get_charges, collect_charges +from sedacs.evals_dvals import collect_evals, collect_dvals +from sedacs.message import status_at, error_at, warning_at +from sedacs.mixer import diis_mix, linear_mix +from sedacs.chemical_potential import get_mu +from sedacs.file_io import read_latte_tbparams + +try: + from mpi4py import MPI + + is_mpi_available = True +except ModuleNotFoundError as e: + is_mpi_available = False + error_at( + "get_adaptiveSCFDM_scf", + "mpi4py not found, parallelization will not be available", + ) + raise e + +__all__ = ["get_singlePoint_charges", "get_adaptiveSCFDM"] + + +def get_singlePoint_charges( + sdc, eng, rank, numranks, comm, parts, partsCoreHalo, sy, hindex, gscf, mu=0.0 +): + """ + Get the single point charges for the full system from graph-partitioned subsystems. + This function is called from the graph adaptive SCF loop. + For each SCF iteration, it follows the following steps: + 1. For each subsystem: + a. Extract the subsystem from the full system. + b. Compute the Hamiltonian matrix for the subsystem. + c. Compute the evals and dvals from the Hamiltonian matrix for the subsystem. + 2. Collect the full evals and dvals across all subsystems. + 3. Compute the global chemical potential for the full system using the collected full evals and dvals. + 4. For each subsystem: + a. Compute the density matrix for the subsystem. + b. Compute the charges for the subsystem. + 5. Collect the full graph and charges across all subsystems. + + Parameters + ---------- + sdc : sedacs driver object + Refer to driver/init.py for detailed information. + eng : engine object + Refer to engine.py for detailed information. + rank: int + Rank of the current process in the MPI communicator. + numranks: int + Total number of processes in the MPI communicator. + comm: MPI communicator + MPI communicator for parallelization. + parts: list of lists of int + List of partitions of the full system. + partsCoreHalo: list of lists of int + List of core and halo indices for each partition. + sy: System object + Refer to system.py for detailed information. + hindex: list of int + Orbital index for each atom in the system. The orbital indices for orbital i goes from `hindex[i]` to `hindex[i+1]-1`. + gscf: int + Graph adaptive SCF iteration number. + mu: float + Chemical potential for the full system. Default is 0.0. + + Returns + ------- + fullGraphRho: 2D numpy array, dtype: float + The full graph collected from all subsystems. + fullCharges: 1D numpy array, dtype: float + The mulliken charges for the full system. + subSysOnRank: list of System objects + List of subsystem objects for each partition on the current rank. + mu: float + The chemical potential for the full system. + """ + partsPerRank = int(sdc.nparts / numranks) + partIndex1 = rank * partsPerRank + partIndex2 = (rank + 1) * partsPerRank + graphOnRank = None + chargesOnRank = None + evalsOnRank = None + dvalsOnRank = None + subSysOnRank = [] + + for partIndex in range(partIndex1, partIndex2): + numberOfCoreAtoms = len(parts[partIndex]) + subSy = System(len(partsCoreHalo[partIndex])) + subSy.symbols = sy.symbols + tic = time.perf_counter() + subSy.coords, subSy.types = extract_subsystem( + sy.coords, sy.types, sy.symbols, partsCoreHalo[partIndex] + ) + subSy.ncores = len(parts[partIndex]) + toc = time.perf_counter() + print("Time for extract_subsystem", toc - tic, "(s)") + partFileName = "subSy" + str(rank) + "_" + str(partIndex) + ".pdb" + write_pdb_coordinates(partFileName, subSy.coords, subSy.types, subSy.symbols) + write_xyz_coordinates( + "subSy" + str(rank) + "_" + str(partIndex) + ".xyz", + subSy.coords, + subSy.types, + subSy.symbols, + ) + tic = time.perf_counter() + + # Get some electronic structure elements for the sybsystem + # This could eventually be computed in the engine if no basis set is + # provided in the SEDACS input file. + subSy.norbs, subSy.orbs, subSy.hindex, subSy.numel, subSy.znuc = get_hindex( + sdc.orbs, subSy.symbols, subSy.types, verb=True + ) + + norbs = subSy.norbs # We have as many orbitals as columns in the Hamiltonian + tmpArray = np.zeros(numberOfCoreAtoms) + tmpArray[:] = subSy.orbs[subSy.types[0:numberOfCoreAtoms]] + norbsInCore = int(np.sum(tmpArray)) + print("Number of orbitals in the core =", norbsInCore) + nocc = int(float(subSy.numel) / 2.0) # Get the total occupied orbitals + + ham, over, zmat = get_hamiltonian( + eng, + partIndex, + sdc.nparts, + norbs, + sy.latticeVectors, + subSy.coords, + subSy.types, + subSy.symbols, + verb=False, + get_overlap=True, + newsystem=True, + ) + + toc = time.perf_counter() + print("Time for get_hamiltonian", toc - tic, "(s)") + + tic = time.perf_counter() + + rho = get_density_matrix( + eng, + partIndex, + sdc.nparts, + norbs, + sy.latticeVectors, + subSy.coords, + subSy.types, + subSy.symbols, + ham, + sy.coulvs[partsCoreHalo[partIndex]], + nocc=nocc, + norbsInCore=norbsInCore, + mu=mu, + etemp=sdc.etemp, + overlap=over, + full_data=False, + verb=False, + newsystem=True, + keepmem=True, + ) + + chargesInPart = get_charges(rho,subSy.znuc,subSy.types,parts[partIndex],subSy.hindex,over=over,verb=True) + + chargesInPart = chargesInPart[: len(parts[partIndex])] + subSy.charges = chargesInPart + + # Save the subsystems list for returning them + subSysOnRank.append(subSy) + + print("TotalCharge in part", partIndex, sum(chargesInPart)) + # print("Charges in part", chargesInPart) + + toc = time.perf_counter() + print("Time to get_densityMatrix and get_charges", toc - tic, "(s)") + # Building a graph from DMs + graphOnRank = collect_graph_from_rho( + graphOnRank, + rho, + sdc.gthresh, + sy.nats, + sdc.maxDeg, + partsCoreHalo[partIndex], + len(parts[partIndex]), + hindex, + ) + + chargesOnRank = collect_charges( + chargesOnRank, chargesInPart, parts[partIndex], sy.nats, verb=True + ) + + if is_mpi_available and numranks > 1: + fullGraphRho = collect_and_sum_matrices(graphOnRank, rank, numranks, comm) + fullCharges = collect_and_sum_vectors_float(chargesOnRank, rank, numranks, comm) + comm.Barrier() + else: + fullGraphRho = graphOnRank + fullCharges = chargesOnRank + + # print_graph(fullGraphRho) + return fullGraphRho, fullCharges, subSysOnRank, mu + + +def get_adaptiveSCFDM(sdc, eng, comm, rank, numranks, sy, hindex, graphNL, mu): + fullGraph = graphNL + + # Iitial guess for the excess ocupation vector. This is the negative of + # the charge! + charges = sy.charges + chargesOld = None + chargesIn = None + chargesOld = None + chargesOut = None + # Get the path of the current file + curr_file_path = Path(__file__) + # Get the directory of the current file + curr_dir = curr_file_path.parent + # Get the path of latte parameters + latte_param_path = curr_dir / Path( + "../../../parameters/latte/TBparam/electrons.dat" + ) + latte_tbparams = read_latte_tbparams(latte_param_path) + hubbard_u = [latte_tbparams[symbol]["HubbardU"] for symbol in sy.symbols] + hubbard_u = np.array(hubbard_u)[sy.types] + # Partition the graph + parts = graph_partition( + sdc, eng, fullGraph, sdc.partitionType, sdc.nparts, sy.coords, True + ) + for gscf in range(sdc.numAdaptIter): + msg = "Graph-adaptive iteration" + str(gscf) + status_at("get_adaptiveSCFDM", msg) + + njumps = 1 + partsCoreHalo = [] + numCores = [] + # print("\nCore and halos indices for every part:") + for i in range(sdc.nparts): + coreHalo, nc, nh = get_coreHaloIndices(parts[i], fullGraph, njumps) + partsCoreHalo.append(coreHalo) + numCores.append(nc) + print("core,halo size:", i, "=", nc, nh) + # print("coreHalo for part", i, "=", coreHalo) + if gscf == 0 and sum(charges == 0) != 0: + sy.coulvs = np.zeros(len(charges)) + else: + sy.coulvs, ewald_e = get_PME_coulvs( + charges, hubbard_u, sy.coords, sy.types, sy.latticeVectors + ) + fullGraphRho, charges, subSysOnRank, mu = get_singlePoint_charges( + sdc, eng, rank, numranks, comm, parts, partsCoreHalo, sy, hindex, gscf, mu + ) + # print("Collected charges", charges) + + scfError, charges, chargesOld, chargesIn, chargesOut = diis_mix( + charges, chargesOld, chargesIn, chargesOut, gscf, verb=True + ) + # scfError,charges,chargesOld = linear_mix(0.25,charges,chargesOld,gscf) + # if gscf == 0: + # scfError = sy.numel + + # print_graph(fullGraphRho) + # fullGraph = add_graphs(fullGraphRho, graphNL) + fullGraph = multiply_graphs(fullGraphRho, graphNL) + # with open('graphNL.pkl', 'wb') as f: + # pickle.dump(graphNL, f) + # with open('fullGraphRho.pkl', 'wb') as f: + # pickle.dump(fullGraphRho, f) + # with open('fullGraph.pkl', 'wb') as f: + # pickle.dump(fullGraph, f) + # if gscf == 1: + # breakpoint() + for i in range(sy.nats): + print("Charges:", i, sy.symbols[sy.types[i]], charges[i]) + print("SCF ERR =", scfError) + print("TotalCharge", sum(charges)) + + if scfError < sdc.scfTol: + status_at( + "get_adaptiveSCFDM", "SCF converged with SCF error = " + str(scfError) + ) + break + + if gscf == sdc.numAdaptIter - 1: + warning_at("get_adaptiveSCFDM", "SCF did not converged ... ") + + AtToPrint = 0 + + subSy = System(fullGraphRho[AtToPrint, 0]) + subSy.symbols = sy.symbols + subSy.coords, subSy.types = extract_subsystem( + sy.coords, + sy.types, + sy.symbols, + fullGraph[AtToPrint, 1 : fullGraph[AtToPrint, 0] + 1], + ) + + if rank == 0: + write_pdb_coordinates( + "subSyG_fin.pdb", subSy.coords, subSy.types, subSy.symbols + ) + write_xyz_coordinates( + "subSyG_fin.xyz", subSy.coords, subSy.types, subSy.symbols + ) + + return fullGraph, charges, mu, parts, partsCoreHalo, subSysOnRank From c69d534a6e20fd4ed07d8a0f9b4fcfdd990cf2aa Mon Sep 17 00:00:00 2001 From: peterli3819 Date: Thu, 1 May 2025 14:32:12 -0600 Subject: [PATCH 2/6] adding proxy codes --- proxies/c/README.md | 1 + proxies/c/build.sh | 2 + proxies/c/proxy_a.c | 48 ++ proxies/c/proxy_a.h | 14 + proxies/c/proxy_a_lib.c | 253 +++++++ proxies/fortran/CMakeLists.txt | 107 +++ proxies/fortran/compile.sh | 1 + proxies/fortran/compile_with_cmake.sh | 24 + proxies/fortran/proxy_a.F90 | 31 + proxies/fortran/proxy_a_lib.F90 | 113 +++ proxies/fortran/proxy_a_mod.F90 | 232 ++++++ proxies/matlab/AtomicDensityMatrix.m | 36 + proxies/matlab/BondIntegral.m | 18 + proxies/matlab/COORD.m | 51 ++ proxies/matlab/CoulombMatrix.m | 16 + proxies/matlab/DM_Fermi.m | 37 + proxies/matlab/DM_PRT_Fermi.m | 43 ++ proxies/matlab/DensityMatrix.m | 13 + proxies/matlab/DensityMatrixPRT.m | 34 + proxies/matlab/Energy.m | 34 + proxies/matlab/Energy_save_00.m | 34 + proxies/matlab/Ewald_Real_Space.m | 97 +++ proxies/matlab/Ewald_k_Space.m | 108 +++ proxies/matlab/Forces.m | 109 +++ proxies/matlab/Forces_save_00.m | 108 +++ proxies/matlab/Get_q.m | 9 + proxies/matlab/GetdC.m | 86 +++ proxies/matlab/GetdH.m | 38 + proxies/matlab/GetdS.m | 37 + proxies/matlab/H0_and_S.m | 95 +++ proxies/matlab/LoadBondIntegralParameters_H.m | 261 +++++++ proxies/matlab/LoadBondIntegralParameters_S.m | 123 ++++ proxies/matlab/Main.m | 145 ++++ proxies/matlab/Main_save_00.m | 85 +++ proxies/matlab/Main_save_01.m | 110 +++ proxies/matlab/PBC_Coulomb.m | 11 + proxies/matlab/PBC_CoulombPot.m | 29 + proxies/matlab/PBC_Energy.m | 30 + proxies/matlab/PBC_Forces.m | 36 + proxies/matlab/PBC_Hamiltonian.m | 12 + proxies/matlab/PBC_SCF.m | 21 + proxies/matlab/PBC_SCF_PRT.m | 43 ++ proxies/matlab/PBC_SCF_PRT_0.m | 42 ++ proxies/matlab/PBC_SCF_PRT_X.m | 48 ++ proxies/matlab/PBC_main.m | 101 +++ proxies/matlab/SCF.m | 50 ++ proxies/matlab/SCF_save_00.m | 50 ++ proxies/matlab/ScaleTail.m | 26 + proxies/matlab/Slater_Koster_Block.m | 104 +++ proxies/matlab/Slater_Koster_Pair.m | 94 +++ proxies/matlab/Thresh.m | 10 + proxies/matlab/nearestneighborlist.m | 67 ++ proxies/python/aosa_hamiltonian.py | 130 ++++ proxies/python/chemical_potential.py | 211 ++++++ proxies/python/coordinates.py | 58 ++ proxies/python/density_matrix.py | 309 ++++++++ proxies/python/dnnprt.py | 279 ++++++++ proxies/python/energy_and_forces.py | 664 ++++++++++++++++++ proxies/python/first_level.py | 441 ++++++++++++ proxies/python/first_level_gpu.py | 303 ++++++++ proxies/python/hamiltonian.py | 182 +++++ proxies/python/hamiltonian_elements.py | 309 ++++++++ proxies/python/hamiltonian_random.py | 57 ++ proxies/python/init_proxy.py | 107 +++ proxies/python/nonortho.py | 35 + proxies/python/proxy_global.py | 106 +++ proxies/python/random_numbers.py | 69 ++ proxies/vars | 11 + 68 files changed, 6598 insertions(+) create mode 100644 proxies/c/README.md create mode 100644 proxies/c/build.sh create mode 100644 proxies/c/proxy_a.c create mode 100644 proxies/c/proxy_a.h create mode 100644 proxies/c/proxy_a_lib.c create mode 100644 proxies/fortran/CMakeLists.txt create mode 100644 proxies/fortran/compile.sh create mode 100644 proxies/fortran/compile_with_cmake.sh create mode 100644 proxies/fortran/proxy_a.F90 create mode 100644 proxies/fortran/proxy_a_lib.F90 create mode 100644 proxies/fortran/proxy_a_mod.F90 create mode 100644 proxies/matlab/AtomicDensityMatrix.m create mode 100644 proxies/matlab/BondIntegral.m create mode 100644 proxies/matlab/COORD.m create mode 100644 proxies/matlab/CoulombMatrix.m create mode 100644 proxies/matlab/DM_Fermi.m create mode 100644 proxies/matlab/DM_PRT_Fermi.m create mode 100644 proxies/matlab/DensityMatrix.m create mode 100644 proxies/matlab/DensityMatrixPRT.m create mode 100644 proxies/matlab/Energy.m create mode 100644 proxies/matlab/Energy_save_00.m create mode 100644 proxies/matlab/Ewald_Real_Space.m create mode 100644 proxies/matlab/Ewald_k_Space.m create mode 100644 proxies/matlab/Forces.m create mode 100644 proxies/matlab/Forces_save_00.m create mode 100644 proxies/matlab/Get_q.m create mode 100644 proxies/matlab/GetdC.m create mode 100644 proxies/matlab/GetdH.m create mode 100644 proxies/matlab/GetdS.m create mode 100644 proxies/matlab/H0_and_S.m create mode 100644 proxies/matlab/LoadBondIntegralParameters_H.m create mode 100644 proxies/matlab/LoadBondIntegralParameters_S.m create mode 100644 proxies/matlab/Main.m create mode 100644 proxies/matlab/Main_save_00.m create mode 100644 proxies/matlab/Main_save_01.m create mode 100644 proxies/matlab/PBC_Coulomb.m create mode 100644 proxies/matlab/PBC_CoulombPot.m create mode 100644 proxies/matlab/PBC_Energy.m create mode 100644 proxies/matlab/PBC_Forces.m create mode 100644 proxies/matlab/PBC_Hamiltonian.m create mode 100644 proxies/matlab/PBC_SCF.m create mode 100644 proxies/matlab/PBC_SCF_PRT.m create mode 100644 proxies/matlab/PBC_SCF_PRT_0.m create mode 100644 proxies/matlab/PBC_SCF_PRT_X.m create mode 100644 proxies/matlab/PBC_main.m create mode 100644 proxies/matlab/SCF.m create mode 100644 proxies/matlab/SCF_save_00.m create mode 100644 proxies/matlab/ScaleTail.m create mode 100644 proxies/matlab/Slater_Koster_Block.m create mode 100644 proxies/matlab/Slater_Koster_Pair.m create mode 100644 proxies/matlab/Thresh.m create mode 100644 proxies/matlab/nearestneighborlist.m create mode 100644 proxies/python/aosa_hamiltonian.py create mode 100644 proxies/python/chemical_potential.py create mode 100644 proxies/python/coordinates.py create mode 100644 proxies/python/density_matrix.py create mode 100644 proxies/python/dnnprt.py create mode 100644 proxies/python/energy_and_forces.py create mode 100644 proxies/python/first_level.py create mode 100644 proxies/python/first_level_gpu.py create mode 100644 proxies/python/hamiltonian.py create mode 100644 proxies/python/hamiltonian_elements.py create mode 100644 proxies/python/hamiltonian_random.py create mode 100644 proxies/python/init_proxy.py create mode 100644 proxies/python/nonortho.py create mode 100644 proxies/python/proxy_global.py create mode 100644 proxies/python/random_numbers.py create mode 100644 proxies/vars diff --git a/proxies/c/README.md b/proxies/c/README.md new file mode 100644 index 0000000..d0f81a0 --- /dev/null +++ b/proxies/c/README.md @@ -0,0 +1 @@ +Placeholder for C version of proxy_a code diff --git a/proxies/c/build.sh b/proxies/c/build.sh new file mode 100644 index 0000000..540edab --- /dev/null +++ b/proxies/c/build.sh @@ -0,0 +1,2 @@ +gcc-mp-12 -c proxy_a_lib.c -I/opt/local/include +gcc-mp-12 proxy_a.c -o proxy_a proxy_a_lib.o -L/opt/local/lib -lopenblas diff --git a/proxies/c/proxy_a.c b/proxies/c/proxy_a.c new file mode 100644 index 0000000..b5f5d81 --- /dev/null +++ b/proxies/c/proxy_a.c @@ -0,0 +1,48 @@ +#include "proxy_a.h" + +int main(int argc, char *argv[]) +{ + double + *coords = NULL, + *H = NULL, + *D = NULL; + + int + *types, + nats, + nocc, + i, + j; + + nats = 2; + + coords = (double *)malloc(3*nats*sizeof(double)); + get_random_coordinates(nats,coords); + + for (i=0; i < nats; i++) { + printf("%30.18g\n",coords[3*i]); + } + types = (int *)malloc(nats*sizeof(int)); + for (i = 0; i < nats; i++) types[i] = 1; + + H = (double *)malloc(nats*nats*sizeof(double)); + get_hamiltonian(nats,coords, types, H, true); + printf("Hamiltonian matrix\n"); + for (i = 0; i < nats; i++) { + size_t ofst = nats * i; + for (j = 0; j < nats; j++) { + printf("%g\n",H[ofst + j]); + } + } + + D = (double *)malloc(nats*nats*sizeof(double)); + nocc = (int)((double)nats/2.0); + get_densityMatrix(nats,H, nocc, D, true); + printf("Density matrix:\n"); + for (i = 0; i < nats; i++) { + size_t ofst = nats * i; + for (j = 0; j < nats; j++) { + printf("%g\n",D[ofst + j]); + } + } +} diff --git a/proxies/c/proxy_a.h b/proxies/c/proxy_a.h new file mode 100644 index 0000000..a0368ba --- /dev/null +++ b/proxies/c/proxy_a.h @@ -0,0 +1,14 @@ +#ifndef PROXY_A_H +#define PROXY_A_H + +#include +#include +#include +#include +#include + +int get_random_coordinates(int nats, double *coords); +int get_hamiltonian(int nats, double *coords, int *atomTypes, double *H, bool verb); +int get_densityMatrix(int nats, double *H, int Nocc, double *D, bool verb); + +#endif diff --git a/proxies/c/proxy_a_lib.c b/proxies/c/proxy_a_lib.c new file mode 100644 index 0000000..e5a4ed6 --- /dev/null +++ b/proxies/c/proxy_a_lib.c @@ -0,0 +1,253 @@ +/* + proxy_a_lib.c + + A prototype engine that: + - Reads the total number of atoms + - Constructs a set of random coordinates + - Constructs a simple Hamiltonian + - Computes the Density matrix from the Hamiltonian + + Translated from C to Fortran by Michael E. Wall, LANL + +*/ + +#include "proxy_a.h" +#include "lapack.h" + +/* + Simple random number generator + This is important in order to compare across codes + written in different languages. + + To initialize: + \verbatim + myRand = rand(123) + \endverbatim + where the argument of rand is the seed. + + To get a random number between "low" and "high": + \verbatim + rnd = myRand.get_rand(low,high) + \endverbatim +*/ + +double proxy_rand(double low, double high, int seed,bool init) +{ + static int + stat, + a = 321, + b = 231, + c = 13; + + double + w, + rnd; + + int + place; + + if (init) { + stat = seed * 1000; + rnd = 0.0;; + } + else { + w = high - low; + place = a * stat; + place = (int)(place/b); + rnd = ((double)(place % c))/((double)c); + place = rnd * 1000000; + stat = place; + rnd = low + w*rnd; + } + + return(rnd); +} + +/* + Generating random coordinates + @brief Creates a system of size "nats = Number of atoms" with coordindates having + a random (-1,1) displacement from a simple cubic lattice with parameter 2.0 Ang. + + @param nats The total number of atoms + @return coordinates Position for every atom. z-coordinate of atom 1 = coords[0,2] +*/ + +int get_random_coordinates(int nats, double *coords) +{ + int + *seedin, + ssize, + length, + atomsCounter, + i, + j, + k; + + double + rnd, + latticeParam; + + length = (int)(pow((double)nats,1./3.)) + 1; + latticeParam = 2.0; + atomsCounter = 0; + rnd = proxy_rand(0.,0.,111,true); // set the random number seed + for (i = 0; i < length; i++) { + for (j = 0; j < length; j++) { + for (k = 0; k < length; k++) { + atomsCounter = atomsCounter + 1; + size_t ofst = (atomsCounter - 1) * 3; + if (atomsCounter > nats) break; + rnd = proxy_rand(-1.,1.,0,false); + coords[ofst + 0] = i * latticeParam + rnd; + printf("%lg\n",coords[ofst + 0]); + rnd = proxy_rand(-1.,1.,0,false); + coords[ofst + 1] = j * latticeParam + rnd; + rnd = proxy_rand(-1.,1.,0,false); + coords[ofst + 2] = k * latticeParam + rnd; + } + } + } + return(0); +} + +/* + Computes a Hamiltonian based on a single "s-like" orbitals per atom. + @author Anders Niklasson + @brief Computes a hamiltonian \f$ H_{ij} = (x/m)\exp(-(y/n + decay_{min}) |R_{ij}|^2))\f$, based on distances + \f$ R_{ij} \f$. \f$ x,m,y,n,decay_{min} \f$ are fixed parameters. + + @param coords Position for every atoms. z-coordinate of atom 1 = coords[0,2] + @param types Index type for each atom in the system. Type for first atom = type[0] (not used yet) + @return H 2D numpy array of Hamiltonian elements + @param verb Verbosity. If True is passed, information is printed. +*/ + +int get_hamiltonian(int nats, double *coords, int *atomTypes, double *H, bool verb) +{ + int + *N, + Nocc, + m, + n, + hdim, + i, + j, + k, + cnt; + + double + *xx, + a, + c, + x, + b, + d, + y, + tmp, + dvec[3], + dist2, + eps, + decay_min; + + hdim = nats; + Nocc = (int)((double)hdim/4.0); + eps = 1.0e-9; + decay_min = 0.1; + m = 78; + a = 3.817632; c = 0.816371; x = 1.029769; n = 13; + b = 1.927947; d = 3.386142; y = 2.135545; + if (H == NULL) { + perror("get_hamiltonian requires allocated H\n"); + exit(1); + } + if (verb) printf("Constructing a simple Hamiltonian for the full system\n"); + cnt = 0; + for (i = 0; i < hdim; i++) { + size_t iofst = i * 3; + x = fmod((a * x + c), (double)m); + y = fmod((b * y + d), (double)n); + for (j = i; j < hdim; j++) { + size_t jofst = j * 3; + dist2 = 0.0; + for (k = 0; k < 3; k++) { + dvec[k] = coords[iofst + k] - coords[jofst + k]; + dist2 += dvec[k]*dvec[k]; + } + tmp = (x/(double)m) * exp(-(y/(double)n + decay_min)*dist2); + H[i*nats + j] = tmp; + H[j*nats + i] = tmp; + } + } + return(0); +} +/* + Computes the Density matrix from a given Hamiltonian. + @author Anders Niklasson + @brief This will create a "zero-temperature" Density matrix \f$ \rho \f$ + \f[ \rho = \sum^{nocc} v_k v_k^T \f] + where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ + + @param H Hamiltonian mtrix + @param Nocc Number of occupied orbitals + @param verb Verbosity. If True is passed, information is printed. + + @return D Density matrix + +*/ + +int get_densityMatrix(int nats, double *H, int Nocc, double *D, bool verb) +{ + double + *Q, + *E, + mu, + *work; + + int + info, + lwork, + i, + j, + k, + hdim, + homoIndex, + lumoIndex; + + char + jobz = 'V', + uplo = 'U'; + + if (verb) printf("Computing the Density matrix"); + + hdim = nats; + lwork = 3*hdim - 1; + + Q = (double *)malloc(hdim*hdim*sizeof(double)); + work = (double *)malloc(lwork*sizeof(double)); + E = (double *)malloc(hdim*sizeof(double)); + memcpy(Q,H,hdim*hdim*sizeof(double)); + LAPACK_dsyev(&jobz,&uplo,&hdim,Q,&hdim,E,work,&lwork,&info); + if (verb) { + printf("Eigenvalues:\n"); + for (i = 0; i < hdim; i++) { + printf("%g\n",E[i]); + } + homoIndex = Nocc; + lumoIndex = Nocc + 1; + mu = 0.5*(E[homoIndex] + E[lumoIndex]); + memset(D,0,hdim*hdim*sizeof(double)); + for (i = 0; i < hdim; i++) { + size_t iofst = i * hdim; + for (j = 0; j < hdim; j++) { + size_t jofst = j * hdim; + for (k = 0; k < hdim; k++) { + if (E[k] < mu) { + D[iofst + j] = D[iofst + j] + Q[iofst + k]*Q[jofst + k]; + } + } + } + } + if (verb) printf("Chemical potential = %g\n",mu); + return(0); + } +} diff --git a/proxies/fortran/CMakeLists.txt b/proxies/fortran/CMakeLists.txt new file mode 100644 index 0000000..0c81ac0 --- /dev/null +++ b/proxies/fortran/CMakeLists.txt @@ -0,0 +1,107 @@ +cmake_minimum_required(VERSION 3.10.0) +project(appendix C CXX Fortran) + +set(dir ${CMAKE_CURRENT_SOURCE_DIR}/build/) +set(CMAKE_BUILD_DIRECTORY ${dir}) +set(CMAKE_CURRENT_BINARY_DIR ${dir}) + +include(FindPkgConfig) + +find_package(BML CONFIG QUIET) +pkg_check_modules(BML REQUIRED bml) +list(APPEND LINK_LIBRARIES BML::bml) +list(APPEND LINK_LIBRARIES ${BML_LDFLAGS}) +message(STATUS "Found bml: ${BML_LDFLAGS}") + +find_package(PROGRESS CONFIG QUIET) +pkg_check_modules(PROGRESS REQUIRED progress) +message(STATUS "Found progress: ${PROGRESS_LDFLAGS}") +list(APPEND LINK_LIBRARIES ${PROGRESS_LDFLAGS}) + +find_library(FOUND_METIS metis) + if(NOT FOUND_METIS) + message(FATAL_ERROR "Could not find metis library") + endif() + message(STATUS "Found metis: ${FOUND_METIS}") + add_definitions(-DDO_GRAPHLIB) + list(APPEND LINK_LIBRARIES ${FOUND_METIS}) + + get_filename_component(METIS_LIB ${FOUND_METIS} DIRECTORY) + list(APPEND LINK_LIBRARIES "-L/${METIS_LIB} -lmetis") + +if(PROGRESS_MPI) + message(STATUS "Will build with MPI") + add_definitions(-DDO_MPI) +endif() + +if(PROGRESS) + message(STATUS "Will build with MPI") + add_definitions(-DUSEPROGRESS) +endif() + +if(SANITY_CHECK) + message(STATUS "Will build with SANITY CHECK") + add_definitions(-DSANITY_CHECK) +endif() + +message(STATUS "Extra FC Flags ${EXTRA_FCFLAGS}") + +if(DEFINED EXTRA_FCFLAGS) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${EXTRA_FCFLAGS}") +endif() + + +if(LIB) + list(APPEND SHAREDLIB "-fPIC -shared") + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${EXTRA_FCFLAGS} ${SHAREDLIB}") +endif() + +message(STATUS "Project sources = " ${PROJECT_SOURCE_DIR} ) +include_directories(${CMAKE_BINARY_DIR}/) +include_directories(${BML_INCLUDEDIR}) +include_directories(${PROGRESS_INCLUDEDIR}) + +list( + APPEND common_sources +"proxy_a_lib.F90" +"proxy_a_mod.F90" + ) + + +function(progress_appendix myappendix main_and_srcs) +list(GET main_and_srcs 0 main) +include_directories(${PROGRESS_INCLUDEDIR}) +add_executable(${myappendix} ${main} ${common_sources} ${extras}) +target_sources(${myappendix} PRIVATE ${ARGN}) +target_link_libraries(${myappendix} PUBLIC + ${LINK_LIBRARIES}) + set_target_properties(${myappendix} + PROPERTIES + LINK_FLAGS "") + #add_subdirectory(hamiltonian) +endfunction(progress_appendix) + +function(progress_appendix_library myappendix main_and_srcs) +list(GET main_and_srcs 0 main) +include_directories(${PROGRESS_INCLUDEDIR}) +add_library(${myappendix} SHARED ${main} ${common_sources} ${extras}) +target_sources(${myappendix} PRIVATE ${ARGN}) +target_link_libraries(${myappendix} PUBLIC + ${LINK_LIBRARIES}) + set_target_properties(${myappendix} + PROPERTIES + LINK_FLAGS "") +endfunction(progress_appendix_library) + +if(LIB) + progress_appendix_library( proxya_fortran proxy_a_lib.F90 proxy_a_mod.F90 ) + #progress_appendix( gpmd_a gpmd_secuential.F90 gpmdcov_lib_mod.F90) +else() + progress_appendix( proxya proxy_a.F90 ) +endif() + +SET(DESTINATION ${PROJECT_BINARY_DIR}) +install(FILES ${CMAKE_BINARY_DIR}/progress.pc + DESTINATION ${PROJECT_BINARY_DIR}) + +SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}) diff --git a/proxies/fortran/compile.sh b/proxies/fortran/compile.sh new file mode 100644 index 0000000..65bce24 --- /dev/null +++ b/proxies/fortran/compile.sh @@ -0,0 +1 @@ +gfortran proxy_a_mod.F90 proxy_a.F90 -o proxy_a -llapack -lblas diff --git a/proxies/fortran/compile_with_cmake.sh b/proxies/fortran/compile_with_cmake.sh new file mode 100644 index 0000000..97624cd --- /dev/null +++ b/proxies/fortran/compile_with_cmake.sh @@ -0,0 +1,24 @@ +# Remove the build directory and create a new one +rm -rf build +mkdir build +# Move into the build directory +cd build +METIS_LIB="$HOME/metis-5.1.0/build/Linux-x86_64/libmetis" +METIS_INC="$HOME/metis-5.1.0/build/Linux-x86_64/include" +PROGRESS_LIB="$HOME/qmd-progress/install/" +PROGRESS_INC="$HOME/qmd-progress/install/include" +BML_LIB="$HOME/bml/install/" +BML_INC="$HOME/bml/install/include" + + +cmake -DPROGRESS="yes" -DCMAKE_Fortran_COMPILER="gfortran" -DPROGRESS_MPI="no" \ + -DEXTRA_FCFLAGS="-Wall -Wunused -fopenmp -lm -fPIC -g -O0 -fcheck=all --check=bounds -lmetis -lm -fPIC" \ + -DLIB="yes" -DLATTE_PREC="DOUBLE" \ + -DCMAKE_PREFIX_PATH="$PROGRESS_LIB;$PROGRESS_INC;$BML_LIB;$BML_INC;$METIS_LIB;$METIS_INC" ../ +make + +cp libproxya_fortran.so proxya_fortran.so + + + + diff --git a/proxies/fortran/proxy_a.F90 b/proxies/fortran/proxy_a.F90 new file mode 100644 index 0000000..41286a9 --- /dev/null +++ b/proxies/fortran/proxy_a.F90 @@ -0,0 +1,31 @@ +program proxy_a + use proxy_a_mod + implicit none + real(dp),allocatable :: coords(:,:) + integer,allocatable :: types(:) + real(dp), allocatable :: H(:,:),D(:,:) + integer :: nats,nocc,i,j + + nats = 2 + + call get_random_coordinates(nats,coords) + do i = 1,nats + write(*,*)coords(1,i) + enddo + allocate(types(nats)); types = 1 + allocate(H(nats,nats)) + call get_hamiltonian(coords,types,H,.true.) + write(*,*)"Hamiltonian matrix" + do i=1,nats + do j=1,nats + write(*,*)H(i,j) + enddo + enddo + + allocate(D(nats,nats)) + nocc = int(real(nats,dp)/2.0_dp) + call get_densityMatrix(H,nocc,D,.true.) + write(*,*)"Density matrix=",D + +end program proxy_a + diff --git a/proxies/fortran/proxy_a_lib.F90 b/proxies/fortran/proxy_a_lib.F90 new file mode 100644 index 0000000..9723abb --- /dev/null +++ b/proxies/fortran/proxy_a_lib.F90 @@ -0,0 +1,113 @@ +!> Library interface +!! \brief This file is used to interface to python via iso_c_binding +!! library. + +!> Get Hamiltonian +!! \brief General fortran proxy function to get the Hamiltonian +!! \param nats Number of atoms +!! \param norbs Number of atoms +!! \param coords_in Positions for all the atoms +!! \param atomTypes Atom types indices for every atom in the system +!! \param H_out Hamiltonian matrix +!! \param S_out Overlap matrix +!! \param verb_in Verbosity level +!! +function proxya_get_hamiltonian(nats,norbs,coords_in,atomTypes_in,H_out,S_out,verb_in) & + & result(err) bind(c, name='proxya_get_hamiltonian') + use iso_c_binding, only: c_char, c_double, c_int, c_bool + use proxy_a_mod + implicit none + integer(c_int), intent(in), value :: nats + integer(c_int), intent(in), value :: norbs + real(c_double), intent(in) :: coords_in(3*nats) + integer(c_int), intent(in) :: atomTypes_in(nats) + logical(c_bool), intent(in), value :: verb_in + logical(c_bool) :: err + real(c_double), intent(inout) :: H_out(norbs,norbs) + real(c_double), intent(inout) :: S_out(norbs,norbs) + + real(dp), allocatable :: coords(:,:) + integer, allocatable :: atomTypes(:) + integer :: i + real(dp), allocatable :: H(:,:) + real(dp), allocatable :: S(:,:) + logical :: verb + + err = .true. + + allocate(coords(3,nats)) !indices will need to be flipped + allocate(atomTypes(nats)) + allocate(H(norbs,norbs)) + allocate(S(norbs,norbs)) + + !Note that arrays appear in another order. We need to rearange + !the data. This is because of the column mayor (in python) vs. + !row mayor in fortran. + do i = 1, nats + coords(1,i) = coords_in((i-1)*3 + 1) + coords(2,i) = coords_in((i-1)*3 + 2) + coords(3,i) = coords_in((i-1)*3 + 3) + enddo + + atomTypes = atomTypes_in + + !A workaround to avoid fortran to c (one bit) boolean issues + if(verb_in .eqv. (1 == 1))then + verb = .true. + else + verb = .false. + endif + + call get_hamiltonian(coords,atomTypes,H,S,verb) + + H_out = H + S_out = S + + err = .false. + +end function proxya_get_hamiltonian + + +!> Get density matrix +!! \brief General fortran proxy function to get the density matrix +!! \param norbs Number of atoms +!! \param nocc Number of occupied orbitals +!! \param ham_in Hamiltonian matrix input +!! \param D_out Density matrix output +!! \param verb_in Verbosity level +!! +function proxya_get_density_matrix(norbs,nocc,ham_in,D_out,verb_in) & + & result(err) bind(c, name='proxya_get_density_matrix') + use iso_c_binding, only: c_char, c_double, c_int, c_bool + use proxy_a_mod + implicit none + integer(c_int), intent(in), value :: norbs + integer(c_int), intent(in), value :: nocc + real(c_double), intent(in) :: ham_in(norbs*norbs) + logical(c_bool), intent(in), value :: verb_in + logical(c_bool) :: err + real(c_double), intent(inout) :: D_out(norbs*norbs) + + real(dp), allocatable :: coords(:,:) + integer, allocatable :: atomTypes(:) + integer :: i + real(dp), allocatable :: D(:,:) + real(dp), allocatable :: ham(:,:) + logical :: verb + + err = .true. + + allocate(D(norbs,norbs)) + allocate(ham(norbs,norbs)) + !From flatt to matrix + do i = 1,norbs + ham(i,:) = ham_in(((i-1)*norbs + 1):i*norbs) + enddo + + call get_densityMatrix(ham,Nocc,D,verb) + !From matrix to faltt + do i = 1,norbs + D_out(((i-1)*norbs + 1):i*norbs) = D(i,:) + enddo + +end function proxya_get_density_matrix diff --git a/proxies/fortran/proxy_a_mod.F90 b/proxies/fortran/proxy_a_mod.F90 new file mode 100644 index 0000000..bf9ed99 --- /dev/null +++ b/proxies/fortran/proxy_a_mod.F90 @@ -0,0 +1,232 @@ +!!> proxy code a +!! A prototype engine that: +!! - Reads the total number of atoms +!! - Constructs a set of random coordinates +!! - Constructs a simple Hamiltonian +!! - Computes the Density matrix from the Hamiltonian +!! +module proxy_a_mod + + implicit none + + integer, parameter :: dp = kind(1.0D0) !Precision + public :: get_random_coordinates, get_densityMatrix + +!!> Simple random number generator +!! This is important in order to compare across codes +!! written in different languages. +!! +!! To initialize: +!! \verbatim +!! myRand = rand(123) +!! \endverbatim +!! where the argument of rand is the seed. +!! +!! To get a random number between "low" and "high": +!! \verbatim +!! rnd = myRand.get_rand(low,high) +!! \endverbatim +!! +type, public :: rand + integer :: a = 321 + integer :: b = 231 + integer :: c = 13 + integer :: seed + integer :: stat + contains + procedure :: init => rand_init + procedure :: get_rand => rand_get_rand +end type rand +contains + + subroutine rand_init(self,seed) + implicit none + class(rand), intent(inout) :: self + integer, intent(in) :: seed + self%seed = seed + self%stat = seed*1000 + end subroutine rand_init + + function rand_get_rand(self,low,high) result(rnd) + implicit none + class(rand), intent(inout) :: self + real(dp) :: w + real(dp) :: rnd + real(dp), intent(in) :: low, high + integer :: place + w = high - low + place = self%a*self%stat + place = int(place/self%b) + rnd = real(mod(place,self%c))/real(self%c) + place = rnd*1000000 + self%stat = place + rnd = low + w*rnd + end function rand_get_rand + + + !!> Generating random coordinates + !! @brief Creates a system of size "nats = Number of atoms" with coordindates having + !! a random (-1,1) displacement from a simple cubic lattice with parameter 2.0 Ang. + !! + !! @param nats The total number of atoms + !! @return coordinates Position for every atom. z-coordinate of atom 1 = coords[0,2] + !! + subroutine get_random_coordinates(nats,coords) + implicit none + integer :: nats,ssize,length,atomsCounter + integer :: i,j,k + integer, allocatable :: seedin(:) + real(dp), allocatable :: coords(:,:) + real(dp) :: rnd,latticeParam + type(rand) :: myrand + !Get random coordinates + length = int(real(nats)**(1.0/3.0)) + 1 + allocate(coords(3,nats)) + latticeParam = 2.0 + atomsCounter = 0 + call myrand%init(111) + do i = 1,length + do j = 1,length + do k = 1,length + atomsCounter = atomsCounter + 1 + if(atomsCounter > nats) exit + rnd = myrand%get_rand(-1.0_dp,1.0_dp) + coords(1,atomsCounter) = (i-1)*latticeParam + rnd + write(*,*)coords(1,atomsCounter) + rnd = myrand%get_rand(-1.0_dp,1.0_dp) + coords(2,atomsCounter) = (j-1)*latticeParam + rnd + rnd = myrand%get_rand(-1.0_dp,1.0_dp) + coords(3,atomsCounter) = (k-1)*latticeParam + rnd + enddo + enddo + enddo + return + end subroutine get_random_coordinates + + !! Computes a Hamiltonian based on a single "s-like" orbitals per atom. + ! @author Anders Niklasson + ! @brief Computes a hamiltonian \f$ H_{ij} = (x/m)\exp(-(y/n + decay_{min}) |R_{ij}|^2))\f$, based on distances + ! \f$ R_{ij} \f$. \f$ x,m,y,n,decay_{min} \f$ are fixed parameters. + ! + ! @param coords Position for every atoms. z-coordinate of atom 1 = coords[0,2] + ! @param types Index type for each atom in the system. Type for first atom = type[0] (not used yet) + ! @return H 2D numpy array of Hamiltonian elements + ! @param verb Verbosity. If True is passed, information is printed. + ! + subroutine get_hamiltonian(coords,atomTypes,H,S,verb) + implicit none + integer :: n,Nocc,m,hdim + logical, intent(in) :: verb + real(dp), allocatable :: xx(:) + real(dp), allocatable, intent(in) :: coords(:,:) + integer, allocatable, intent(in) :: atomTypes(:) + real(dp), allocatable, intent(out) :: H(:,:) + real(dp), allocatable, intent(out) :: S(:,:) + real(dp) :: a,c,x,b,d,y,tmp,dist,eps,decay_min + integer :: i,j,k,cnt + + hdim = size(coords,dim=2); Nocc = int(real(hdim)/4.0); eps = 1e-9; decay_min = 0.1; m = 78; + a = 3.817632; c = 0.816371; x = 1.029769; n = 13; + b = 1.927947; d = 3.386142; y = 2.135545; + if(.not. allocated(H)) allocate(H(hdim,hdim)) + if(verb) write(*,*)"Constructing a simple Hamiltonian for the full system" + cnt = 0 + do i = 1,hdim + x = mod((a*x+c),real(m)) + y = mod((b*y+d),real(n)) + do j = i,hdim + dist = norm2(coords(:,i)-coords(:,j)) + tmp = (x/real(m))*exp(-(y/real(n) + decay_min)*dist**2) + H(i,j) = tmp + H(j,i) = tmp + enddo + enddo + return + end subroutine get_hamiltonian + + !!> Computes the Density matrix from a given Hamiltonian. + !! @author Anders Niklasson + !! @brief This will create a "zero-temperature" Density matrix \f$ \rho \f$ + !! \f[ \rho = \sum^{nocc} v_k v_k^T \f] + !! where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ + !! + !! @param H Hamiltonian mtrix + !! @param Nocc Number of occupied orbitals + !! @param verb Verbosity. If True is passed, information is printed. + !! + !! @return D Density matrix + !! + subroutine get_densityMatrix(H,Nocc,D,verb) +#ifdef USEPROGRESS + use bml + use prg_densitymatrix_mod +#endif + + implicit none + integer :: Nocc + logical, intent(in) :: verb + real(dp), allocatable, intent(in) :: H(:,:) + real(dp), allocatable, intent(out) :: D(:,:) + real(dp), allocatable :: Q(:,:), E(:),tmpmat(:,:),f(:,:) + real(dp) :: mu + integer :: info, lwork,i,j,k,norbs,homoIndex,lumoIndex + real(dp), allocatable :: work(:) + real(dp) :: bndfil + character(LEN=1), parameter :: jobz = 'V', uplo = 'U' + +#ifdef USEPROGRESS + type(bml_matrix_t) :: D_bml,H_bml +#endif + if(verb) write(*,*)"Computing the Density matrix" + + norbs = size(H,dim=1) + +#ifdef USEPROGRESS + bndfil = real(nocc)/real(norbs) + call bml_zero_matrix(bml_matrix_dense,bml_element_real,& + &dp,norbs,norbs,D_bml) + call bml_zero_matrix(bml_matrix_dense,bml_element_real,& + &dp,norbs,norbs,H_bml) + call bml_import_from_dense(bml_matrix_dense,H,H_bml,0.0_dp,norbs) + call prg_build_density_t0(H_bml,D_bml,0.0_dp,bndfil,E) + call bml_export_to_dense(D_bml,D) + call bml_deallocate(D_bml) + call bml_deallocate(H_bml) +#else + lwork = 3*norbs - 1 + allocate(Q(norbs,norbs)) + allocate(work(lwork)) + allocate(E(norbs)) + Q = H + call dsyev(jobz,uplo,norbs,Q,norbs,E,work,lwork,info) + if(verb)write(*,*)"Eigenvalues",E + homoIndex = Nocc + lumoIndex = Nocc + 1 + mu = 0.5*(E(homoIndex) + E(lumoIndex)) + allocate(D(norbs,norbs)) + allocate(f(norbs,norbs)) + allocate(tmpmat(norbs,norbs)) + D = 0.0_dp + f = 0.0_dp + + do i = 1,norbs + if (E(i) < mu) then + f(i,i) = 1.0_dp + endif + enddo + + CALL DGEMM('N', 'N', norbs, norbs, norbs, 1.0_dp, & + tmpmat, norbs, Q, norbs, 0.0_dp, f, norbs) !Q*f + CALL DGEMM('N', 'T', norbs, norbs, norbs, 1.0_dp, & + tmpmat, norbs, Q, norbs, 0.0_dp, D, norbs) !(Q*f)*Qt + +#endif + + return + + end subroutine get_densityMatrix + + +end module proxy_a_mod + + diff --git a/proxies/matlab/AtomicDensityMatrix.m b/proxies/matlab/AtomicDensityMatrix.m new file mode 100644 index 0000000..3b54d65 --- /dev/null +++ b/proxies/matlab/AtomicDensityMatrix.m @@ -0,0 +1,36 @@ +function [D_atomic] = AtomicDensityMatrix(Nr_atoms,H_INDEX_START,H_INDEX_END,HDIM,Znuc); + +D_atomic = zeros(1,HDIM); + +INDEX = 0; +for I = 1:Nr_atoms + N_orb = H_INDEX_END(I)-H_INDEX_START(I) + 1; + if N_orb == 1 + INDEX = INDEX + 1; + D_atomic(INDEX) = Znuc(I); + else + if Znuc(I) <= 2 + INDEX = INDEX + 1; + D_atomic(INDEX) = Znuc(I); + + INDEX = INDEX + 1; + D_atomic(INDEX) = 0; + INDEX = INDEX + 1; + D_atomic(INDEX) = 0; + INDEX = INDEX + 1; + D_atomic(INDEX) = 0; + + else + INDEX = INDEX + 1; + D_atomic(INDEX) = 2; + + INDEX = INDEX + 1; + OCC = (Znuc(I)-2)/3; + D_atomic(INDEX) = OCC; + INDEX = INDEX + 1; + D_atomic(INDEX) = OCC; + INDEX = INDEX + 1; + D_atomic(INDEX) = OCC; + end + end +end diff --git a/proxies/matlab/BondIntegral.m b/proxies/matlab/BondIntegral.m new file mode 100644 index 0000000..af89ff0 --- /dev/null +++ b/proxies/matlab/BondIntegral.m @@ -0,0 +1,18 @@ +function h = BondIntegral(dR,f) + +%%% dR: distance between atoms +%%% f: paramters/coefficeints for the bond integral + + if (dR <= f(7)) + RMOD = dR - f(6); + POLYNOM = RMOD*(f(2) + RMOD*(f(3) + RMOD*(f(4) + f(5)*RMOD))); + X = exp(POLYNOM); + elseif (dR > f(7)) & (dR < f(8)) + RMINUSR1 = dR - f(7); + X = f(9) + RMINUSR1*(f(10) + RMINUSR1*(f(11) + RMINUSR1*(f(12) + RMINUSR1*(f(13) + RMINUSR1*f(14))))); + else + X = 0; + end + h = f(1)*X; + + diff --git a/proxies/matlab/COORD.m b/proxies/matlab/COORD.m new file mode 100644 index 0000000..996dec8 --- /dev/null +++ b/proxies/matlab/COORD.m @@ -0,0 +1,51 @@ +C 4.420001 4.520000 4.580000 +H 3.952899 3.984296 3.748600 +H 5.071440 5.306013 4.187320 +H 5.011723 3.820633 5.177613 +H 3.643938 4.969059 5.206467 +C 8.306417 8.922489 11.058251 +H 7.865654 8.396639 10.200538 +H 8.992247 9.727094 10.639195 +H 8.904344 8.233497 11.656443 +H 7.543664 9.375350 11.675742 +C 6.610673 10.624374 6.001819 +H 6.160123 10.106479 5.151284 +H 7.268551 11.425549 5.588731 +H 7.221693 9.947533 6.581240 +H 5.823319 11.071655 6.587968 +C 9.366899 6.173791 5.081823 +H 8.933342 5.638478 4.223453 +H 10.058373 6.941235 4.689739 +H 9.968428 5.474563 5.664468 +H 8.613620 6.610354 5.691975 +C 9.478122 12.338314 9.397453 +H 9.018586 11.787411 8.593005 +H 10.173401 13.102222 9.043487 +H 10.104399 11.631090 9.991622 +H 8.723496 12.779712 10.032465 +C 12.611055 8.972684 9.821024 +H 12.157151 8.430239 8.991073 +H 13.272277 9.726794 9.406545 +H 13.215367 8.258123 10.422758 +H 11.851780 9.389042 10.460303 +C 5.504395 5.739892 10.170246 +H 4.984621 5.201157 9.328596 +H 6.132797 6.531114 9.786514 +H 6.033806 5.041772 10.791585 +H 4.701655 6.239441 10.792016 +C 10.749151 9.799286 5.751812 +H 10.273222 9.228897 4.965396 +H 11.415380 10.553758 5.355932 +H 11.355674 9.087793 6.356916 +H 9.991911 10.216903 6.404219 +C 6.563228 7.033042 6.958737 +H 6.129016 6.519083 6.097352 +H 7.207507 7.808931 6.574565 +H 7.165189 6.313190 7.581883 +H 5.799429 7.501422 7.567627 +C 12.912482 12.239536 7.755493 +H 12.460887 11.708290 6.915681 +H 13.592325 13.037021 7.373497 +H 13.532606 11.558002 8.323343 +H 12.185690 12.735960 8.374372 +~ diff --git a/proxies/matlab/CoulombMatrix.m b/proxies/matlab/CoulombMatrix.m new file mode 100644 index 0000000..c0bf4cc --- /dev/null +++ b/proxies/matlab/CoulombMatrix.m @@ -0,0 +1,16 @@ +function [CC] = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nr_atoms,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); + + dq_J = zeros(1,Nr_atoms); + CC = zeros(Nr_atoms); + Coulomb_Pot_k = 0; + for J = 1:Nr_atoms + dq_J(J) = 1; + for I = 1:Nr_atoms + [Coulomb_Pot_Real(I),Coulomb_Force_Real(:,I)] = Ewald_Real_Space(I,RX,RY,RZ,LBox,dq_J,Hubbard_U,Element_Type,Nr_atoms,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType); + end + [Coulomb_Pot_k,Coulomb_Force_k] = Ewald_k_Space(RX,RY,RZ,LBox,dq_J,Nr_atoms,Coulomb_acc,TIMERATIO); + Coulomb_Pot_dq_J = Coulomb_Pot_Real+Coulomb_Pot_k; + CC(:,J) = Coulomb_Pot_dq_J; + dq_J(J) = 0; + end +% CC = 0.5*(CC+CC'); diff --git a/proxies/matlab/DM_Fermi.m b/proxies/matlab/DM_Fermi.m new file mode 100644 index 0000000..4e7aebf --- /dev/null +++ b/proxies/matlab/DM_Fermi.m @@ -0,0 +1,37 @@ + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function [P0,mu0] = DM_Fermi(H0,T,mu_0,Ne,m,eps,MaxIt) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + N = max(size(H0)); + I = eye(N); + mu0 = mu_0; + OccErr = 1; + Cnt = 0; + while OccErr > eps + %kB = 6.33366256e-6; % Ry/K; + %kB = 3.166811429e-6; % Ha/K; + kB = 8.61739e-5; % eV/K; + beta = 1/(kB*T); % Temp in Kelvin + cnst = 2^(-2-m)*beta; + P0 = 0.5*I - cnst*(H0-mu0*I); + for i = 1:m + P02 = P0*P0; + ID0 = inv(2*(P02-P0) + I); + P_0 = ID0*P02; + P0 = P_0; + end + TrdPdmu = trace(beta*P0*(I-P0)); + if abs(TrdPdmu) > 1e-8 + mu0 = mu0 + (Ne - trace(P0))/TrdPdmu; + OccErr = abs(trace(P0)-Ne); + else + OccErr = 0; + end + Cnt = Cnt + 1; + if (Cnt >= MaxIt) + OccErr; + OccErr = 0; + Cnt = MaxIt; + end + end + % Adjust occupation + P0 = P0 + ((Ne - trace(P0))/TrdPdmu)*beta*P0*(I-P0); diff --git a/proxies/matlab/DM_PRT_Fermi.m b/proxies/matlab/DM_PRT_Fermi.m new file mode 100644 index 0000000..dea0e2c --- /dev/null +++ b/proxies/matlab/DM_PRT_Fermi.m @@ -0,0 +1,43 @@ + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + function [P0,P1,mu0,mu1] = DM_PRT_Fermi(H0,H1,T,mu_0,mu1,Ne,m,eps,MaxIt) + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + N = max(size(H0)); + I = eye(N); mu_1_start = mu1; + mu0 = mu_0; mu1 = mu1; % Intial guess + OccErr = 1; + Cnt = 0; + while OccErr > eps + %kB = 6.33366256e-6; % Ry/K; + %kB = 3.166811429e-6; % Ha/K; + kB = 8.61739e-5; % eV/K; + beta = 1/(kB*T); % Temp in Kelvin + cnst = 2^(-2-m)*beta; + P0 = 0.5*I - cnst*(H0-mu0*I); + P1 = -cnst*(H1-mu1*I); + for i = 1:m + % hh = sort(real(eig(P0))); + P02 = P0*P0; + DX1 = P0*P1+P1*P0; + ID0 = inv(2*(P02-P0) + I); + P_0 = ID0*P02; + P_1 = ID0*(DX1+2*(P1-DX1)*P_0); + P0 = P_0; P1 = P_1; + end + TrdPdmu = trace(beta*P0*(I-P0)); + if abs(TrdPdmu) > 1e-9 + mu0 = mu0 + (Ne - trace(P0))/TrdPdmu; + mu1 = mu1 + (0 - trace(P1))/TrdPdmu; + OccErr = abs(trace(P0+P1)-Ne); + else + OccErr = 0; + end + Cnt = Cnt + 1; + if (Cnt >= MaxIt) + OccErr; + OccErr = 0; + Cnt = MaxIt; + end + end + % Adjust occupation + P0 = P0 + ((Ne - trace(P0))/TrdPdmu)*beta*P0*(I-P0); + P1 = P1 - trace(P1)*I/N; diff --git a/proxies/matlab/DensityMatrix.m b/proxies/matlab/DensityMatrix.m new file mode 100644 index 0000000..50c3b0d --- /dev/null +++ b/proxies/matlab/DensityMatrix.m @@ -0,0 +1,13 @@ +function [D,mu] = DensityMatrix(H,nocc) + +N = max(size(H)); +[Q,E] = eig(H); +e = sort(diag(E)); +mu = 0.5*(e(nocc)+e(nocc+1)); +D = zeros(N); +for i = 1:N + if e(i) < mu + D = D + Q(:,i)*Q(:,i)'; + end +end + diff --git a/proxies/matlab/DensityMatrixPRT.m b/proxies/matlab/DensityMatrixPRT.m new file mode 100644 index 0000000..c3cde2c --- /dev/null +++ b/proxies/matlab/DensityMatrixPRT.m @@ -0,0 +1,34 @@ +function [D,D1] = DensityMatrixPRT(H0,H1,nocc) + +N = max(size(H0)); +[Q,E] = eig(H0); +e = diag(E); +mu = 0.5*(e(nocc)+e(nocc+1)); +D = zeros(N); +for i = 1:N + if e(i) < mu + D = D + Q(:,i)*Q(:,i)'; + end +end + +Q1 = 0*Q; +for i = 1:N + if e(i) < mu + for j = 1:N + H1Tmp = (Q(:,j)'*H1*Q(:,i)/(e(i) -e(j))); + if j ~= i + Q1(:,i) = Q1(:,i) + H1Tmp*Q(:,j); + end + end + end +end +D1 = Q1*Q' + Q*Q1'; % Calculated using Rayleigh Schrodinger Pertrubations theory + +% OccErr1 = trace(D1)-0 +% IdErr1 = norm(D1*D+D*D1-D1) +% ComErr1 = norm(D1*H0-H0*D1 + D*H1-H1*D) +% pause + + + + diff --git a/proxies/matlab/Energy.m b/proxies/matlab/Energy.m new file mode 100644 index 0000000..7389f4f --- /dev/null +++ b/proxies/matlab/Energy.m @@ -0,0 +1,34 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Total energy calculation % +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [Etot,Eband0,Ecoul,Edipole,S_ent] = Energy(H0,U,Efield,D0,C,D,q,Rx,Ry,Rz,f,Te); + +%% E = 2*trace(H0*(D-D0)) + 0.5*sum_ij{i!=j} (qi*Cij*qj) + 0.5*sum_i qi^2*Ui - Efield*mu - 2*Te*S_ent +%% dipole = mu(:) = sum_i qi*R(i,:); qi = 2*(D_ii-D0_ii) + + +kB = 8.61739e-5; % eV/K; +N = max(size(q)); +D0 = diag(D0); +Eband0 = 2*trace(H0*(D-D0)); % Single-particle/band energy + +Ecoul = 0.5*q'*C*q; % Coulomb energy +for i = 1:N + Ecoul = Ecoul + 0.5*q(i)*U(i)*q(i); +end + +Edipole = 0; +for i = 1:N + Edipole = Edipole - q(i)*(Rx(i)*Efield(1)+Ry(i)*Efield(2)+Rz(i)*Efield(3)); % External-field-Dipole interaction energy +end + +S_ent = 0; eps = 1e-9 +for i = 1:N + if (f(i) < 1-eps) & (f(i) > eps) + S_ent = - kB*(f(i)*log(f(i)) + (1-f(i))*log(1-f(i))); + end +end + +Etot = Eband0 + Ecoul + Edipole - 2*Te*S_ent; % Total energy + + diff --git a/proxies/matlab/Energy_save_00.m b/proxies/matlab/Energy_save_00.m new file mode 100644 index 0000000..7389f4f --- /dev/null +++ b/proxies/matlab/Energy_save_00.m @@ -0,0 +1,34 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Total energy calculation % +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [Etot,Eband0,Ecoul,Edipole,S_ent] = Energy(H0,U,Efield,D0,C,D,q,Rx,Ry,Rz,f,Te); + +%% E = 2*trace(H0*(D-D0)) + 0.5*sum_ij{i!=j} (qi*Cij*qj) + 0.5*sum_i qi^2*Ui - Efield*mu - 2*Te*S_ent +%% dipole = mu(:) = sum_i qi*R(i,:); qi = 2*(D_ii-D0_ii) + + +kB = 8.61739e-5; % eV/K; +N = max(size(q)); +D0 = diag(D0); +Eband0 = 2*trace(H0*(D-D0)); % Single-particle/band energy + +Ecoul = 0.5*q'*C*q; % Coulomb energy +for i = 1:N + Ecoul = Ecoul + 0.5*q(i)*U(i)*q(i); +end + +Edipole = 0; +for i = 1:N + Edipole = Edipole - q(i)*(Rx(i)*Efield(1)+Ry(i)*Efield(2)+Rz(i)*Efield(3)); % External-field-Dipole interaction energy +end + +S_ent = 0; eps = 1e-9 +for i = 1:N + if (f(i) < 1-eps) & (f(i) > eps) + S_ent = - kB*(f(i)*log(f(i)) + (1-f(i))*log(1-f(i))); + end +end + +Etot = Eband0 + Ecoul + Edipole - 2*Te*S_ent; % Total energy + + diff --git a/proxies/matlab/Ewald_Real_Space.m b/proxies/matlab/Ewald_Real_Space.m new file mode 100644 index 0000000..7eccbfa --- /dev/null +++ b/proxies/matlab/Ewald_Real_Space.m @@ -0,0 +1,97 @@ +function [COULOMBV,FCOUL] = Ewald_Real_Space(I,RX,RY,RZ,LBox,DELTAQ,U,Element_Type,Nr_atoms,COULACC,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType) + +ccnt = 0; +COULVOL = LBox(1)*LBox(2)*LBox(3); +SQRTX = sqrt(-log(COULACC)); +CALPHA = sqrt(pi)*((TIMERATIO*Nr_atoms/(COULVOL^2))^(1/6)); +COULCUT = SQRTX/CALPHA; +CALPHA2 = CALPHA*CALPHA; +if (COULCUT > 50) + COULCUT = 50; + CALPHA = SQRTX/COULCUT; +end +COULCUT2 = COULCUT*COULCUT; +CALPHA2 = CALPHA*CALPHA; + +RELPERM = 1; +KECONST = 14.3996437701414*RELPERM; +TFACT = 16.0/(5.0*KECONST); + +SQRTPI = sqrt(pi); + +FCOUL = zeros(3,1); +COULOMBV = 0; + +TI = TFACT*U(I); +TI2 = TI*TI; +TI3 = TI2*TI; +TI4 = TI2*TI2; +TI6 = TI4*TI2; + +SSA = TI; +SSB = TI3/48; +SSC = 3*TI2/16; +SSD = 11*TI/16; +SSE = 1; + +Ra = [RX(I),RY(I),RZ(I)]; + +for nnI = 1:nrnnlist(I) + Rb(1) = nnRx(I,nnI); + Rb(2) = nnRy(I,nnI); + Rb(3) = nnRz(I,nnI); + J = nnType(I,nnI); + + Rab = Rb-Ra; % OBS b - a !!! + dR = norm(Rab); + MAGR = dR; + MAGR2 = dR*dR; + + if (dR <= COULCUT) & (dR > 1e-12) + + TJ = TFACT*U(J); + DC = Rab/dR; + + %! Using Numerical Recipes ERFC + Z = abs(CALPHA*MAGR); + NUMREP_ERFC = erfc(Z); + + CA = NUMREP_ERFC/MAGR; + COULOMBV = COULOMBV + DELTAQ(J)*CA; + ccnt = ccnt + 1; + TEST(ccnt) = DELTAQ(J)*CA; + CA = CA + 2*CALPHA*exp( -CALPHA2*MAGR2 )/SQRTPI; + FORCE = -KECONST*DELTAQ(I)*DELTAQ(J)*CA/MAGR; + EXPTI = exp(-TI*MAGR ); + + if Element_Type(I) == Element_Type(J) + COULOMBV = COULOMBV - DELTAQ(J)*EXPTI*(SSB*MAGR2 + SSC*MAGR + SSD + SSE/MAGR); + ccnt = ccnt + 1; + TEST(ccnt) = - DELTAQ(J)*EXPTI*(SSB*MAGR2 + SSC*MAGR + SSD + SSE/MAGR); + FORCE = FORCE + (KECONST*DELTAQ(I)*DELTAQ(J)*EXPTI)*((SSE/MAGR2 - 2*SSB*MAGR - SSC) + SSA*(SSB*MAGR2 + SSC*MAGR + SSD + SSE/MAGR)); + else + TJ2 = TJ*TJ; + TJ3 = TJ2*TJ; + TJ4 = TJ2*TJ2; + TJ6 = TJ4*TJ2; + EXPTJ = exp( -TJ*MAGR ); + TI2MTJ2 = TI2 - TJ2; + TJ2MTI2 = -TI2MTJ2; + SA = TI; + SB = TJ4*TI/(2 * TI2MTJ2 * TI2MTJ2); + SC = (TJ6 - 3*TJ4*TI2)/(TI2MTJ2 * TI2MTJ2 * TI2MTJ2); + SD = TJ; + SE = TI4*TJ/(2 * TJ2MTI2 * TJ2MTI2); + SF = (TI6 - 3*TI4*TJ2)/(TJ2MTI2 * TJ2MTI2 * TJ2MTI2); + + COULOMBV = COULOMBV - (DELTAQ(J)*(EXPTI*(SB - (SC/MAGR)) + EXPTJ*(SE - (SF/MAGR)))); + FORCE = FORCE + KECONST*DELTAQ(I)*DELTAQ(J)*((EXPTI*(SA*(SB - (SC/MAGR)) - (SC/MAGR2))) + (EXPTJ*(SD*(SE - (SF/MAGR)) - (SF/MAGR2)))); + end + + FCOUL(1) = FCOUL(1) + DC(1)*FORCE; + FCOUL(2) = FCOUL(2) + DC(2)*FORCE; + FCOUL(3) = FCOUL(3) + DC(3)*FORCE; + end +end +COULOMBV = KECONST * COULOMBV; + diff --git a/proxies/matlab/Ewald_k_Space.m b/proxies/matlab/Ewald_k_Space.m new file mode 100644 index 0000000..e8a8d1b --- /dev/null +++ b/proxies/matlab/Ewald_k_Space.m @@ -0,0 +1,108 @@ +function [COULOMBV,FCOUL] = Ewald_k_Space(RX,RY,RZ,LBox,DELTAQ,Nr_atoms,COULACC,TIMERATIO) + +COULVOL = LBox(1)*LBox(2)*LBox(3); + +SQRTX = sqrt(-log(COULACC)); +CALPHA = sqrt(pi)*((TIMERATIO*Nr_atoms/(COULVOL^2))^(1/6)); +COULCUT = SQRTX/CALPHA; +CALPHA2 = CALPHA*CALPHA; +if (COULCUT > 50) + COULCUT = 50; + CALPHA = SQRTX/COULCUT; +end +COULCUT2 = COULCUT*COULCUT; +KCUTOFF = 2*CALPHA*SQRTX; +KCUTOFF2 = KCUTOFF*KCUTOFF; +CALPHA2 = CALPHA*CALPHA; +FOURCALPHA2 = 4*CALPHA2; +RECIPVECS = zeros(3,3); +RECIPVECS(1,1) = 2*pi/LBox(1); +RECIPVECS(2,2) = 2*pi/LBox(2); +RECIPVECS(3,3) = 2*pi/LBox(3); +LMAX = floor(KCUTOFF / sqrt(RECIPVECS(1,1)*RECIPVECS(1,1))); +MMAX = floor(KCUTOFF / sqrt(RECIPVECS(2,2)*RECIPVECS(2,2))); +NMAX = floor(KCUTOFF / sqrt(RECIPVECS(3,3)*RECIPVECS(3,3))); + +RELPERM = 1; +KECONST = 14.3996437701414*RELPERM; + +SQRTPI = sqrt(pi); + +FCOUL = zeros(3,Nr_atoms); +COULOMBV = zeros(1,Nr_atoms); +SINLIST = zeros(Nr_atoms); +COSLIST = zeros(Nr_atoms); +%CR = R'; + +for L = 0:LMAX + + if L == 0 + MMIN = 0; + else + MMIN = -MMAX; + end + + L11 = L*RECIPVECS(1,1); + L12 = L*RECIPVECS(1,2); + L13 = L*RECIPVECS(1,3); + + for M = MMIN:MMAX + + NMIN = -NMAX; + + if (L == 0) & (M == 0) + NMIN = 1; + end + + M21 = L11 + M*RECIPVECS(2,1); + M22 = L12 + M*RECIPVECS(2,2); + M23 = L13 + M*RECIPVECS(2,3); + + for N = NMIN:NMAX + K(1) = M21 + N*RECIPVECS(3,1); + K(2) = M22 + N*RECIPVECS(3,2); + K(3) = M23 + N*RECIPVECS(3,3); + K2 = K(1)*K(1) + K(2)*K(2) + K(3)*K(3); + if K2 <= KCUTOFF2 + PREFACTOR = 8*pi*exp(-K2/(4*CALPHA2))/(COULVOL*K2); + PREVIR = (2/K2) + (2/(4*CALPHA2)); + + COSSUM = 0; + SINSUM = 0; + + %! Doing the sin and cos sums + + for I = 1:Nr_atoms + %DOT = K(1)*CR(1,I) + K(2)*CR(2,I) + K(3)*CR(3,I); + DOT = K(1)*RX(I) + K(2)*RY(I) + K(3)*RZ(I); + %! We re-use these in the next loop... + SINLIST(I) = sin(DOT); + COSLIST(I) = cos(DOT); + COSSUM = COSSUM + DELTAQ(I)*COSLIST(I); + SINSUM = SINSUM + DELTAQ(I)*SINLIST(I); + end + COSSUM2 = COSSUM*COSSUM; + SINSUM2 = SINSUM*SINSUM; + + %! Add up energy and force contributions + + KEPREF = KECONST*PREFACTOR; + for I = 1:Nr_atoms + COULOMBV(I) = COULOMBV(I) + KEPREF*(COSLIST(I)*COSSUM + SINLIST(I)*SINSUM); + FORCE = KEPREF * DELTAQ(I)*(SINLIST(I)*COSSUM - COSLIST(I)*SINSUM); + FCOUL(1,I) = FCOUL(1,I) + FORCE*K(1); + FCOUL(2,I) = FCOUL(2,I) + FORCE*K(2); + FCOUL(3,I) = FCOUL(3,I) + FORCE*K(3); + end + + KEPREF = KEPREF * (COSSUM2 + SINSUM2); + + end + end + end +end + +%! Point self energy +CORRFACT = 2*KECONST*CALPHA/SQRTPI; +COULOMBV = COULOMBV - CORRFACT*DELTAQ; + diff --git a/proxies/matlab/Forces.m b/proxies/matlab/Forces.m new file mode 100644 index 0000000..d595c87 --- /dev/null +++ b/proxies/matlab/Forces.m @@ -0,0 +1,109 @@ +function [Ftot,Fcoul,Fband0,Fdipole,FPulay,FScoul,FSdipole] = Forces(H,H0,S,C,D,D0,dHx,dHy,dHz,dSx,dSy,dSz,dCx,dCy,dCz,Efield,U,q,Rx,Ry,Rz,Nats,H_INDEX_START,H_INDEX_END) + +HDIM = max(size(H0)); +Fcoul = zeros(3,Nats); +for i = 1:Nats + Fcoul(1,i) = -q(i)*q(:)'*dCx(:,i); + Fcoul(2,i) = -q(i)*q(:)'*dCy(:,i); + Fcoul(3,i) = -q(i)*q(:)'*dCz(:,i); +end + +Fband0 = zeros(3,Nats); +for i = 1:Nats % Slater-Koster Force SKForce from Tr[D*dH0/dR] + I_A = H_INDEX_START(i); + I_B = H_INDEX_END(i); + Xtmp = dHx(I_A:I_B,:)*D(:,I_A:I_B); + Ytmp = dHy(I_A:I_B,:)*D(:,I_A:I_B); + Ztmp = dHz(I_A:I_B,:)*D(:,I_A:I_B); + Fband0(1,i) = -2*2*trace(Xtmp); + Fband0(2,i) = -2*2*trace(Ytmp); + Fband0(3,i) = -2*2*trace(Ztmp); +end + +FSdipole = zeros(3,Nats); +for k = 1:Nats % Slater-Koster Force SKForce from Tr[D*dH0/dR] + k_a = H_INDEX_START(k); + k_b = H_INDEX_END(k); + d_Sx = zeros(HDIM); + d_Sx(:,k_a:k_b) = dSx(:,k_a:k_b); d_Sx(k_a:k_b,:) = dSx(:,k_a:k_b)'; + d_Sy = zeros(HDIM); + d_Sy(:,k_a:k_b) = dSy(:,k_a:k_b); d_Sy(k_a:k_b,:) = dSy(:,k_a:k_b)'; + d_Sz = zeros(HDIM); + d_Sz(:,k_a:k_b) = dSz(:,k_a:k_b); d_Sz(k_a:k_b,:) = dSz(:,k_a:k_b)'; + + dqi_dRkX = zeros(Nats,1); dqi_dRkY = zeros(Nats,1); dqi_dRkZ = zeros(Nats,1); + for i = 1:Nats + if i == k + dqi_dRkX(i) = -2*trace(D(k_a:k_b,:)*dSx(:,k_a:k_b)); + dqi_dRkY(i) = -2*trace(D(k_a:k_b,:)*dSy(:,k_a:k_b)); + dqi_dRkZ(i) = -2*trace(D(k_a:k_b,:)*dSz(:,k_a:k_b)); + else + i_a = H_INDEX_START(i); i_b = H_INDEX_END(i); + dqi_dRkX(i) = -2*trace(dSx(i_a:i_b,k_a:k_b)*D(k_a:k_b,i_a:i_b)); + dqi_dRkY(i) = -2*trace(dSy(i_a:i_b,k_a:k_b)*D(k_a:k_b,i_a:i_b)); + dqi_dRkZ(i) = -2*trace(dSz(i_a:i_b,k_a:k_b)*D(k_a:k_b,i_a:i_b)); + end + FSdipole(1,k) = FSdipole(1,k) - dqi_dRkX(i)*(Rx(i)*Efield(1)+Ry(i)*Efield(2)+Rz(i)*Efield(3)); + FSdipole(2,k) = FSdipole(2,k) - dqi_dRkY(i)*(Rx(i)*Efield(1)+Ry(i)*Efield(2)+Rz(i)*Efield(3)); + FSdipole(3,k) = FSdipole(3,k) - dqi_dRkZ(i)*(Rx(i)*Efield(1)+Ry(i)*Efield(2)+Rz(i)*Efield(3)); + end + if k == 1 + dqK = dqi_dRkX; + dQi_dRkx = dqK(:) + end +end + +Fdipole = zeros(3,Nats); +for i = 1:Nats + Fdipole(1,i) = q(i)*Efield(1); % Forces from External field-dipole interaction + Fdipole(2,i) = q(i)*Efield(2); % Forces from External field-dipole interaction + Fdipole(3,i) = q(i)*Efield(3); % Forces from External field-dipole interaction +end + +Z = S^(-1/2); +SIHD = 2*2*Z*Z'*H*D; % Pulay Force FPUL from 2Tr[ZZ'HD*dS/dR] +FPulay = zeros(3,Nats); +for i = 1:Nats + I_A = H_INDEX_START(i); + I_B = H_INDEX_END(i); + Xtmp = dSx(I_A:I_B,:)*SIHD(:,I_A:I_B); + Ytmp = dSy(I_A:I_B,:)*SIHD(:,I_A:I_B); + Ztmp = dSz(I_A:I_B,:)*SIHD(:,I_A:I_B); + FPulay(1,i) = trace(Xtmp); + FPulay(2,i) = trace(Ytmp); + FPulay(3,i) = trace(Ztmp); +end + +CoulPot = C*q; % Factor of 2 or 1/2 or +/- +FScoul = zeros(3,Nats); % Coulomb force FSCOUL from nonorthogonality +dDSX = zeros(HDIM,1); +dDSY = zeros(HDIM,1); +dDSZ = zeros(HDIM,1); +for Ia = 1:Nats % Derivatives Ra + Ia_A = H_INDEX_START(Ia); + Ia_B = H_INDEX_END(Ia); + for iq = 1:HDIM + dDSX(iq) = D(iq,Ia_A:Ia_B)*dSx(Ia_A:Ia_B,iq); + dDSY(iq) = D(iq,Ia_A:Ia_B)*dSy(Ia_A:Ia_B,iq); + dDSZ(iq) = D(iq,Ia_A:Ia_B)*dSz(Ia_A:Ia_B,iq); + end + for iq = Ia_A:Ia_B + dDSX(iq) = dDSX(iq) + D(iq,:)*dSx(iq,:)'; + dDSY(iq) = dDSY(iq) + D(iq,:)*dSy(iq,:)'; + dDSZ(iq) = dDSZ(iq) + D(iq,:)*dSz(iq,:)'; + end + for j = 1:Nats % Get the Mulliken charges for all atoms + j_a = H_INDEX_START(j); + j_b = H_INDEX_END(j); + dQLxdR = sum(dDSX(j_a:j_b)); % Derivative with respect to Ia of charge on atom j + dQLydR = sum(dDSY(j_a:j_b)); + dQLzdR = sum(dDSZ(j_a:j_b)); + FScoul(1,Ia) = FScoul(1,Ia) - dQLxdR*(U(j)*q(j) + CoulPot(j)); + FScoul(2,Ia) = FScoul(2,Ia) - dQLydR*(U(j)*q(j) + CoulPot(j)); + FScoul(3,Ia) = FScoul(3,Ia) - dQLzdR*(U(j)*q(j) + CoulPot(j)); + end + +end +FScoul = 2*FScoul; + +Ftot = Fband0 + Fcoul + Fdipole + FPulay + FScoul + FSdipole; % Collected total force diff --git a/proxies/matlab/Forces_save_00.m b/proxies/matlab/Forces_save_00.m new file mode 100644 index 0000000..812f56d --- /dev/null +++ b/proxies/matlab/Forces_save_00.m @@ -0,0 +1,108 @@ +function [Ftot,Fcoul,Fband0,Fdipole,FPulay,FScoul,FSdipole] = Forces(H,H0,S,C,D,D0,dHx,dHy,dHz,dSx,dSy,dSz,dCx,dCy,dCz,Efield,U,q,Rx,Ry,Rz,Nats,H_INDEX_START,H_INDEX_END) + +HDIM = max(size(H0)); +Fcoul = zeros(3,Nats); +for i = 1:Nats + Fcoul(1,i) = -q(i)*q(:)'*dCx(:,i); + Fcoul(2,i) = -q(i)*q(:)'*dCy(:,i); + Fcoul(3,i) = -q(i)*q(:)'*dCz(:,i); +end + +Fband0 = zeros(3,Nats); +for i = 1:Nats % Slater-Koster Force SKForce from Tr[D*dH0/dR] + I_A = H_INDEX_START(i); + I_B = H_INDEX_END(i); + Xtmp = dHx(I_A:I_B,:)*D(:,I_A:I_B); + Ytmp = dHy(I_A:I_B,:)*D(:,I_A:I_B); + Ztmp = dHz(I_A:I_B,:)*D(:,I_A:I_B); + Fband0(1,i) = -2*2*trace(Xtmp); + Fband0(2,i) = -2*2*trace(Ytmp); + Fband0(3,i) = -2*2*trace(Ztmp); +end + +FSdipole = zeros(3,Nats); +for k = 1:Nats % Slater-Koster Force SKForce from Tr[D*dH0/dR] + k_a = H_INDEX_START(k); + k_b = H_INDEX_END(k); + d_Sx = zeros(HDIM); + d_Sx(:,k_a:k_b) = dSx(:,k_a:k_b); d_Sx(k_a:k_b,:) = dSx(:,k_a:k_b)'; + d_Sy = zeros(HDIM); + d_Sy(:,k_a:k_b) = dSy(:,k_a:k_b); d_Sy(k_a:k_b,:) = dSy(:,k_a:k_b)'; + d_Sz = zeros(HDIM); + d_Sz(:,k_a:k_b) = dSz(:,k_a:k_b); d_Sz(k_a:k_b,:) = dSz(:,k_a:k_b)'; + + dqi_dRkX = zeros(Nats,1); dqi_dRkY = zeros(Nats,1); dqi_dRkZ = zeros(Nats,1); + for i = 1:Nats + if i == k + dqi_dRkX(i) = 2*trace(D(k_a:k_b,:)*dSx(:,k_a:k_b)); + dqi_dRkY(i) = 2*trace(D(k_a:k_b,:)*dSy(:,k_a:k_b)); + dqi_dRkZ(i) = 2*trace(D(k_a:k_b,:)*dSz(:,k_a:k_b)); + else + i_a = H_INDEX_START(i); i_b = H_INDEX_END(i); + dqi_dRkX(i) = 2*trace(dSx(i_a:i_b,k_a:k_b)*D(k_a:k_b,i_a:i_b)); + dqi_dRkY(i) = 2*trace(dSy(i_a:i_b,k_a:k_b)*D(k_a:k_b,i_a:i_b)); + dqi_dRkZ(i) = 2*trace(dSz(i_a:i_b,k_a:k_b)*D(k_a:k_b,i_a:i_b)); + end + FSdipole(1,k) = FSdipole(1,k) - dqi_dRkX(i)*(Rx(i)*Efield(1)+Ry(i)*Efield(2)+Rz(i)*Efield(3)); + FSdipole(2,k) = FSdipole(2,k) - dqi_dRkY(i)*(Rx(i)*Efield(1)+Ry(i)*Efield(2)+Rz(i)*Efield(3)); + FSdipole(3,k) = FSdipole(3,k) - dqi_dRkZ(i)*(Rx(i)*Efield(1)+Ry(i)*Efield(2)+Rz(i)*Efield(3)); + end + if k == 1 + check = dqi_dRkX(1:10)' + end +end + +Fdipole = zeros(3,Nats); +for i = 1:Nats + Fdipole(1,i) = q(i)*Efield(1); % Forces from External field-dipole interaction + Fdipole(2,i) = q(i)*Efield(2); % Forces from External field-dipole interaction + Fdipole(3,i) = q(i)*Efield(3); % Forces from External field-dipole interaction +end + +Z = S^(-1/2); +SIHD = 2*2*Z*Z'*H*D; % Pulay Force FPUL from 2Tr[ZZ'HD*dS/dR] +FPulay = zeros(3,Nats); +for i = 1:Nats + I_A = H_INDEX_START(i); + I_B = H_INDEX_END(i); + Xtmp = dSx(I_A:I_B,:)*SIHD(:,I_A:I_B); + Ytmp = dSy(I_A:I_B,:)*SIHD(:,I_A:I_B); + Ztmp = dSz(I_A:I_B,:)*SIHD(:,I_A:I_B); + FPulay(1,i) = trace(Xtmp); + FPulay(2,i) = trace(Ytmp); + FPulay(3,i) = trace(Ztmp); +end + +CoulPot = C*q; % Factor of 2 or 1/2 or +/- +FScoul = zeros(3,Nats); % Coulomb force FSCOUL from nonorthogonality +dDSX = zeros(HDIM,1); +dDSY = zeros(HDIM,1); +dDSZ = zeros(HDIM,1); +for Ia = 1:Nats % Derivatives Ra + Ia_A = H_INDEX_START(Ia); + Ia_B = H_INDEX_END(Ia); + for iq = 1:HDIM + dDSX(iq) = D(iq,Ia_A:Ia_B)*dSx(Ia_A:Ia_B,iq); + dDSY(iq) = D(iq,Ia_A:Ia_B)*dSy(Ia_A:Ia_B,iq); + dDSZ(iq) = D(iq,Ia_A:Ia_B)*dSz(Ia_A:Ia_B,iq); + end + for iq = Ia_A:Ia_B + dDSX(iq) = dDSX(iq) + D(iq,:)*dSx(iq,:)'; + dDSY(iq) = dDSY(iq) + D(iq,:)*dSy(iq,:)'; + dDSZ(iq) = dDSZ(iq) + D(iq,:)*dSz(iq,:)'; + end + for j = 1:Nats % Get the Mulliken charges for all atoms + j_a = H_INDEX_START(j); + j_b = H_INDEX_END(j); + dQLxdR = sum(dDSX(j_a:j_b)); % Derivative with respect to Ia of charge on atom j + dQLydR = sum(dDSY(j_a:j_b)); + dQLzdR = sum(dDSZ(j_a:j_b)); + FScoul(1,Ia) = FScoul(1,Ia) - dQLxdR*(U(j)*q(j) + CoulPot(j)); + FScoul(2,Ia) = FScoul(2,Ia) - dQLydR*(U(j)*q(j) + CoulPot(j)); + FScoul(3,Ia) = FScoul(3,Ia) - dQLzdR*(U(j)*q(j) + CoulPot(j)); + end + +end +FScoul = 2*FScoul; + +Ftot = Fband0 + Fcoul + Fdipole + FPulay + FScoul + FSdipole; % Collected total force diff --git a/proxies/matlab/Get_q.m b/proxies/matlab/Get_q.m new file mode 100644 index 0000000..852e3db --- /dev/null +++ b/proxies/matlab/Get_q.m @@ -0,0 +1,9 @@ +function [q] = Get_q(D,S,H_Index_Start,H_Index_End,Znuc,Nats) + +Z = S^(-1/2); +DS = 2*diag(D*S); +q = zeros(Nats,1); +for i = 1:Nats + q(i) = sum(DS(H_Index_Start(i):H_Index_End(i))) - Znuc(i); +end + diff --git a/proxies/matlab/GetdC.m b/proxies/matlab/GetdC.m new file mode 100644 index 0000000..c068cc1 --- /dev/null +++ b/proxies/matlab/GetdC.m @@ -0,0 +1,86 @@ +function [dCx,dCy,dCz] = GetdC(Nr_atoms,dh,Coulomb_acc,Rcut,TIMERATIO,HDIM,Hubbard_U,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox) + + dq_J = zeros(1,Nr_atoms); Nats = Nr_atoms; + dCx = zeros(Nr_atoms); dCy = zeros(Nr_atoms); dCz = zeros(Nr_atoms); + Coulomb_Pot_k = 0; + RX0 = RX; RY0 = RY; RZ0 = RZ; + + for J = 1:Nr_atoms + + dq_J = 0*dq_J; + dq_J(J) = 1; + + RX(J) = RX0(J) + dh; + [nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); + for I = 1:Nr_atoms + [Coulomb_Pot_Real(I),Coulomb_Force_Real(:,I)] = Ewald_Real_Space(I,RX,RY,RZ,LBox,dq_J,Hubbard_U,Element_Type,Nr_atoms,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType); + end + [Coulomb_Pot_k,Coulomb_Force_k] = Ewald_k_Space(RX,RY,RZ,LBox,dq_J,Nr_atoms,Coulomb_acc,TIMERATIO); + Coulomb_Pot_p = Coulomb_Pot_Real + Coulomb_Pot_k; + RX = RX0; + + RX(J) = RX0(J) - dh; + [nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); + for I = 1:Nr_atoms + [Coulomb_Pot_Real(I),Coulomb_Force_Real(:,I)] = Ewald_Real_Space(I,RX,RY,RZ,LBox,dq_J,Hubbard_U,Element_Type,Nr_atoms,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType); + end + [Coulomb_Pot_k,Coulomb_Force_k] = Ewald_k_Space(RX,RY,RZ,LBox,dq_J,Nr_atoms,Coulomb_acc,TIMERATIO); + Coulomb_Pot_m = Coulomb_Pot_Real + Coulomb_Pot_k; + RX = RX0; + + dCx(:,J) = (Coulomb_Pot_p - Coulomb_Pot_m)/(2*dh); + +%%%% +%RX0 = RX; +%RX(J) = RX0(J) + dh; +%Cp = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nr_atoms,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); +%RX = RX0; +% +%RX(J) = RX0(J) - dh; +%Cm = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nr_atoms,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); +%RX = RX0; +%dC_x = (Cp-Cm)/(2*dh); +%%%% + + RY = RY0; RY(J) = RY0(J) + dh; + [nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); + for I = 1:Nr_atoms + [Coulomb_Pot_Real(I),Coulomb_Force_Real(:,I)] = Ewald_Real_Space(I,RX,RY,RZ,LBox,dq_J,Hubbard_U,Element_Type,Nr_atoms,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType); + end + [Coulomb_Pot_k,Coulomb_Force_k] = Ewald_k_Space(RX,RY,RZ,LBox,dq_J,Nr_atoms,Coulomb_acc,TIMERATIO); + Coulomb_Pot_p = Coulomb_Pot_Real + Coulomb_Pot_k; + RY = RY0; + + RY(J) = RY0(J) - dh; + [nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); + for I = 1:Nr_atoms + [Coulomb_Pot_Real(I),Coulomb_Force_Real(:,I)] = Ewald_Real_Space(I,RX,RY,RZ,LBox,dq_J,Hubbard_U,Element_Type,Nr_atoms,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType); + end + [Coulomb_Pot_k,Coulomb_Force_k] = Ewald_k_Space(RX,RY,RZ,LBox,dq_J,Nr_atoms,Coulomb_acc,TIMERATIO); + Coulomb_Pot_m = Coulomb_Pot_Real + Coulomb_Pot_k; + RY = RY0; + + dCy(:,J) = (Coulomb_Pot_p - Coulomb_Pot_m)/(2*dh); + + RZ(J) = RZ0(J) + dh; + [nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); + for I = 1:Nr_atoms + [Coulomb_Pot_Real(I),Coulomb_Force_Real(:,I)] = Ewald_Real_Space(I,RX,RY,RZ,LBox,dq_J,Hubbard_U,Element_Type,Nr_atoms,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType); + end + [Coulomb_Pot_k,Coulomb_Force_k] = Ewald_k_Space(RX,RY,RZ,LBox,dq_J,Nr_atoms,Coulomb_acc,TIMERATIO); + Coulomb_Pot_p = Coulomb_Pot_Real + Coulomb_Pot_k; + RZ = RZ0; + + RZ(J) = RZ0(J) - dh; + [nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); + for I = 1:Nr_atoms + [Coulomb_Pot_Real(I),Coulomb_Force_Real(:,I)] = Ewald_Real_Space(I,RX,RY,RZ,LBox,dq_J,Hubbard_U,Element_Type,Nr_atoms,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType); + end + [Coulomb_Pot_k,Coulomb_Force_k] = Ewald_k_Space(RX,RY,RZ,LBox,dq_J,Nr_atoms,Coulomb_acc,TIMERATIO); + Coulomb_Pot_m = Coulomb_Pot_Real + Coulomb_Pot_k; + RZ = RZ0; + + dCz(:,J) = (Coulomb_Pot_p - Coulomb_Pot_m)/(2*dh); + + dq_J(J) = 0; + end diff --git a/proxies/matlab/GetdH.m b/proxies/matlab/GetdH.m new file mode 100644 index 0000000..c86abcd --- /dev/null +++ b/proxies/matlab/GetdH.m @@ -0,0 +1,38 @@ +function [dH0x,dH0y,dH0z] = GetdH(Nr_atoms,dx,HDIM,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox,nrnnlist,nnRx,nnRy,nnRz,nnType) + +dH0x = zeros(HDIM,HDIM); dH0y = zeros(HDIM,HDIM); dH0z = zeros(HDIM,HDIM); +for I = 1:Nr_atoms + Type_pair(1) = Element_Type(I); + Rax_p = [RX(I)+dx,RY(I),RZ(I)]; Rax_m = [RX(I)-dx,RY(I),RZ(I)]; + Ray_p = [RX(I),RY(I)+dx,RZ(I)]; Ray_m = [RX(I),RY(I)-dx,RZ(I)]; + Raz_p = [RX(I),RY(I),RZ(I)+dx]; Raz_m = [RX(I),RY(I),RZ(I)-dx]; + IDim = H_INDEX_END(I)-H_INDEX_START(I)+1; + for J = 1:nrnnlist(I) + IJ = nnType(I,J); + if IJ ~= I + Type_pair(2) = Element_Type(IJ); + Rb = [nnRx(I,J),nnRy(I,J),nnRz(I,J)]; + JDim = H_INDEX_END(IJ)-H_INDEX_START(IJ)+1; + + [fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,Es,Ep,U] = LoadBondIntegralParameters_H(Type_pair); % Used in BondIntegral(dR,fxx_xx) + diagonal(1:2) = [Es,Ep]; + dh0x_p = Slater_Koster_Pair(Rax_p,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + dh0x_m = Slater_Koster_Pair(Rax_m,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + dh0y_p = Slater_Koster_Pair(Ray_p,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + dh0y_m = Slater_Koster_Pair(Ray_m,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + dh0z_p = Slater_Koster_Pair(Raz_p,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + dh0z_m = Slater_Koster_Pair(Raz_m,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + + for II = 1:IDim + II_H = H_INDEX_START(I) + II - 1; + for JJ = 1:JDim + JJ_H = H_INDEX_START(IJ) + JJ - 1; + dH0x(II_H,JJ_H) = dH0x(II_H,JJ_H) + (dh0x_p(II,JJ)-dh0x_m(II,JJ))/(2*dx); + dH0y(II_H,JJ_H) = dH0y(II_H,JJ_H) + (dh0y_p(II,JJ)-dh0y_m(II,JJ))/(2*dx); + dH0z(II_H,JJ_H) = dH0z(II_H,JJ_H) + (dh0z_p(II,JJ)-dh0z_m(II,JJ))/(2*dx); + end + end + + end + end +end diff --git a/proxies/matlab/GetdS.m b/proxies/matlab/GetdS.m new file mode 100644 index 0000000..7564e55 --- /dev/null +++ b/proxies/matlab/GetdS.m @@ -0,0 +1,37 @@ +function [dSx,dSy,dSz] = GetdS(Nr_atoms,dx,HDIM,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox,nrnnlist,nnRx,nnRy,nnRz,nnType) + +dSx = zeros(HDIM,HDIM); dSy = zeros(HDIM,HDIM); dSz = zeros(HDIM,HDIM); +for I = 1:Nr_atoms + Type_pair(1) = Element_Type(I); + Rax_p = [RX(I)+dx,RY(I),RZ(I)]; Rax_m = [RX(I)-dx,RY(I),RZ(I)]; + Ray_p = [RX(I),RY(I)+dx,RZ(I)]; Ray_m = [RX(I),RY(I)-dx,RZ(I)]; + Raz_p = [RX(I),RY(I),RZ(I)+dx]; Raz_m = [RX(I),RY(I),RZ(I)-dx]; + IDim = H_INDEX_END(I)-H_INDEX_START(I)+1; + for J = 1:nrnnlist(I) + IJ = nnType(I,J) ; + if IJ ~= I + Type_pair(2) = Element_Type(IJ); + Rb = [nnRx(I,J),nnRy(I,J),nnRz(I,J)]; + JDim = H_INDEX_END(IJ)-H_INDEX_START(IJ)+1; + diagonal(1:2) = [1,1]; + [fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi] = LoadBondIntegralParameters_S(Type_pair); + ds0x_p = Slater_Koster_Pair(Rax_p,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + ds0x_m = Slater_Koster_Pair(Rax_m,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + ds0y_p = Slater_Koster_Pair(Ray_p,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + ds0y_m = Slater_Koster_Pair(Ray_m,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + ds0z_p = Slater_Koster_Pair(Raz_p,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + ds0z_m = Slater_Koster_Pair(Raz_m,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + for II = 1:IDim + II_S = H_INDEX_START(I) + II - 1; + for JJ = 1:JDim + JJ_S = H_INDEX_START(IJ) + JJ - 1; + dSx(II_S,JJ_S) = dSx(II_S,JJ_S) + (ds0x_p(II,JJ)-ds0x_m(II,JJ))/(2*dx); + dSy(II_S,JJ_S) = dSy(II_S,JJ_S) + (ds0y_p(II,JJ)-ds0y_m(II,JJ))/(2*dx); + dSz(II_S,JJ_S) = dSz(II_S,JJ_S) + (ds0z_p(II,JJ)-ds0z_m(II,JJ))/(2*dx); + end + end + + end + end +end + diff --git a/proxies/matlab/H0_and_S.m b/proxies/matlab/H0_and_S.m new file mode 100644 index 0000000..0eb19a4 --- /dev/null +++ b/proxies/matlab/H0_and_S.m @@ -0,0 +1,95 @@ +function [H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nr_atoms,nrnnlist,nnRx,nnRy,nnRz,nnType) + +%TYPE = A.textdata(:); +%RX = A.data(:,1); RY = A.data(:,2); RZ = A.data(:,3); +CNT = 1; +for i = 1:Nr_atoms + if char(TYPE(i)) == 'H' + H_INDEX_START(i) = CNT; + NrOrb(i) = 1; % a single s orbital + CNT = CNT+1; + H_INDEX_END(i) = CNT-1; + Znuc(i) = 1; % For hydrogen + Mnuc(i) = 1.0079; + else + H_INDEX_START(i) = CNT; + NrOrb(i) = 4; % one 1 + three p orbitals + CNT = CNT+4; + H_INDEX_END(i) = CNT-1; + if char(TYPE(i)) == 'O' + Znuc(i) = 6; % For oxygen + Mnuc(i) = 15.9994; + end + if char(TYPE(i)) == 'C' + Znuc(i) = 4; % For oxygen + Mnuc(i) = 12.01; + end + if char(TYPE(i)) == 'N' + Znuc(i) = 5; % For oxygen + Mnuc(i) = 14.0067; + end + end + Element_Type(i) = char(TYPE(i)); +end +HDIM = CNT-1; + +H0 = zeros(HDIM,HDIM); % Charge independent H0! +for I = 1:Nr_atoms + + Type_pair(1) = Element_Type(I); + Ra = [RX(I),RY(I),RZ(I)]; + IDim = H_INDEX_END(I)-H_INDEX_START(I)+1; + for J = 1:nrnnlist(I) + Type_pair(2) = Element_Type(nnType(I,J)); + Rb = [nnRx(I,J),nnRy(I,J),nnRz(I,J)]; + JDim = H_INDEX_END(nnType(I,J))-H_INDEX_START(nnType(I,J))+1; +% Hamiltonian block for a-b atom pair + [fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,Es,Ep,U] = LoadBondIntegralParameters_H(Type_pair); % Used in BondIntegral(dR,fxx_xx); + if I == nnType(I,J) + Hubbard_U(I) = U; + end + diagonal(1:2) = [Es,Ep]; + h0 = Slater_Koster_Pair(Ra,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + for II = 1:IDim + II_H = H_INDEX_START(I) + II - 1; + for JJ = 1:JDim + JJ_H = H_INDEX_START(nnType(I,J)) + JJ - 1; + H0(II_H,JJ_H) = h0(II,JJ) ; + H0(JJ_H,II_H) = h0(II,JJ); + end + end + end + +end +H0 = 0.5*(H0+H0'); + +S = zeros(HDIM,HDIM); +for I = 1:Nr_atoms + Type_pair(1) = Element_Type(I); + Ra = [RX(I),RY(I),RZ(I)]; + IDim = H_INDEX_END(I)-H_INDEX_START(I)+1; + + for J = 1:nrnnlist(I) + Type_pair(2) = Element_Type(nnType(I,J)); + Rb = [nnRx(I,J),nnRy(I,J),nnRz(I,J)]; + JDim = H_INDEX_END(nnType(I,J))-H_INDEX_START(nnType(I,J))+1; +% Overlap block for a-b atom pair + [fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi] = LoadBondIntegralParameters_S(Type_pair); + diagonal(1:2) = [1,1]; + s0 = Slater_Koster_Pair(Ra,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal); + for II = 1:IDim + II_S = H_INDEX_START(I) + II - 1; + for JJ = 1:JDim + JJ_S = H_INDEX_START(nnType(I,J)) + JJ - 1; + S(II_S,JJ_S) = s0(II,JJ); + S(JJ_S,II_S) = s0(II,JJ); + end + end + end +end +S = 0.5*(S+S'); + +D0 = AtomicDensityMatrix(Nr_atoms,H_INDEX_START,H_INDEX_END,HDIM,Znuc); +D0 = D0/2; + + diff --git a/proxies/matlab/LoadBondIntegralParameters_H.m b/proxies/matlab/LoadBondIntegralParameters_H.m new file mode 100644 index 0000000..809ac2b --- /dev/null +++ b/proxies/matlab/LoadBondIntegralParameters_H.m @@ -0,0 +1,261 @@ +function [fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,Es,Ep,U] = LoadBondIntegralParameters_H(TYPE_PAIR) + +TYPE_a = TYPE_PAIR(1); +TYPE_b = TYPE_PAIR(2); + +if TYPE_a == 'H' + if TYPE_b == 'H' +% fss_sigma(1:8) = [-9.340000 -1.145903 -0.391777 0.000000 0.000000 0.750000 3.500000 4.000000]; + fss_sigma(1:8) = [-9.400000D0,-1.145903D0,-0.391777D0,0.000D0,0.000D0,0.750D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fps_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; +% Es = -6.35; % E_s +% Ep = 0; +% U = 12.85; % U for H + Es = -6.4835; % E_s + Ep = 0.0; + U = 12.054683; % U for H + elseif TYPE_b == 'C' +% fss_sigma(1:8) = [-9.072577 -1.393093 -0.430611 0.000000 0.000000 1.100000 3.500000 4.000000]; +% fsp_sigma(1:8) = [8.176008 -0.985177 -0.427403 0.000000 0.000000 1.100000 3.500000 4.000000]; +% fps_sigma(1:8) = [8.176008 -0.985177 -0.427403 0.000000 0.000000 1.100000 3.500000 4.000000]; + + fss_sigma(1:8) = [-9.235812D0,-1.372683D0,-0.408433D0,0.0000D0,0.0000D0,1.1000D0,3.5000D0,4.0000D0]; + fsp_sigma(1:8) = [8.104851D0,-0.936099D0,-0.626219D0,0.0000D0,0.0000D0,1.1000D0,3.5000D0,4.0000D0]; + fps_sigma(1:8) = [8.104851D0,-0.936099D0,-0.626219D0,0.0000D0,0.0000D0,1.1000D0,3.5000D0,4.0000D0]; + + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + Es = 0; Ep = 0; U = 0; + elseif TYPE_b == 'O' +% fss_sigma(1:8) = [-12.230931 -1.808632 -0.421164 0.000000 0.000000 1.000000 3.500000 4.000000]; +% fsp_sigma(1:8) = [9.466088 -1.321262 -0.386336 0.000000 0.000000 1.000000 3.500000 4.000000]; +% fps_sigma(1:8) = [9.466088 -1.321262 -0.386336 0.000000 0.000000 1.000000 3.500000 4.000000]; + + fss_sigma(1:8) = [-12.189103D0,-1.800097D0,-0.325933D0,0.0000D0,0.0000D0,1.0000D0,3.5000D0,4.0000D0]; + fsp_sigma(1:8) = [9.518733D0,-1.333235D0,-0.393710D0,0.0000D0,0.0000D0,1.0000D0,3.5000D0,4.0000D0]; + fps_sigma(1:8) = [9.518733D0,-1.333235D0,-0.393710D0,0.0000D0,0.0000D0,1.0000D0,3.5000D0,4.0000D0]; + + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + Es = 0; Ep = 0; U = 0; + elseif TYPE_b == 'N' +% fss_sigma(1:8) = [-12.095890 -1.519057 -0.277247 0.000000 0.000000 1.000000 3.500000 4.000000]; +% fsp_sigma(1:8) = [9.851338 -1.231616 -0.370836 0.000000 0.000000 1.000000 3.500000 4.000000]; +% fps_sigma(1:8) = [9.851338 -1.231616 -0.370836 0.000000 0.000000 1.000000 3.500000 4.000000]; + + fss_sigma(1:8) = [-12.631030D0,-1.585597D0,-0.250969D0,0.000D0,0.0000D0,1.000D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [9.837852D0,-1.234850D0,-0.324283D0,0.000D0,0.0000D0,1.000D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [9.837852D0,-1.234850D0,-0.324283D0,0.000D0,0.0000D0,1.000D0,3.500D0,4.000D0]; + + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + Es = 0; Ep = 0; U = 0; + end +elseif TYPE_a == 'C' + if TYPE_b == 'H' +% fss_sigma(1:8) = [-9.072577 -1.393093 -0.430611 0.000000 0.000000 1.100000 3.500000 4.000000]; +% fsp_sigma(1:8) = [8.176008 -0.985177 -0.427403 0.000000 0.000000 1.100000 3.500000 4.000000]; +% fps_sigma(1:8) = [8.176008 -0.985177 -0.427403 0.000000 0.000000 1.100000 3.500000 4.000000]; + + fss_sigma(1:8) = [-9.235812D0,-1.372683D0,-0.408433D0,0.000D0,0.000D0,1.100D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [8.104851D0,-0.936099D0,-0.626219D0,0.000D0,0.000D0,1.100D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [8.104851D0,-0.936099D0,-0.626219D0,0.000D0,0.000D0,1.100D0,3.500D0,4.000D0]; + + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + Es = 0; Ep = 0; U = 0; + elseif TYPE_b == 'C' +% fss_sigma(1:8) = [-9.404207 -1.363297 -0.507128 0.000000 0.000000 1.400000 3.500000 4.000000]; +% fsp_sigma(1:8) = [8.662429 -1.047410 -0.661999 0.000000 0.000000 1.400000 3.500000 4.000000]; +% fps_sigma(1:8) = [8.662429 -1.047410 -0.661999 0.000000 0.000000 1.400000 3.500000 4.000000]; +% fpp_sigma(1:8) = [6.811512 -0.552299 -0.776890 0.000000 0.000000 1.400000 3.500000 4.000000]; +% fpp_pi(1:8) = [-3.550127 -1.925572 -0.132715 0.000000 0.000000 1.400000 3.500000 4.000000]; + + fss_sigma(1:8) = [-9.197237D0,-1.607050D0,-0.535057D0,0.000D0,0.000D0,1.400D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [8.562436D0,-0.980182D0,-0.646929D0,0.000D0,0.000D0,1.400D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [8.562436D0,-0.980182D0,-0.646929D0,0.000D0,0.000D0,1.400D0,3.500D0,4.000D0]; + fpp_sigma(1:8) = [6.614756D0,-0.528591D0,-0.951460D0,0.000D0,0.000D0,1.400D0,3.500D0,4.000D0]; + fpp_pi(1:8) = [-3.678302D0,-1.881668D0,-0.255951D0,0.000D0,0.000D0,1.400D0,3.500D0,4.000D0]; + +% Es = -13.75; % E_s +% Ep = -5.28; % E_p +% U = 10.000; % U for C + + Es = -13.7199; % E_s + Ep = -5.2541; % E_p + U = 14.240811; % U for C + + elseif TYPE_b == 'O' +% fss_sigma(1:8) = [-14.369472 -2.077439 -0.875471 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fsp_sigma(1:8) = [9.576296 -1.156217 -0.494803 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fps_sigma(1:8) = [14.037374 -1.192632 -0.654572 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_sigma(1:8) = [9.331152 -0.718120 -0.822100 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_pi(1:8) = [-5.334367 -2.263939 -0.204910 0.000000 0.000000 1.200000 3.500000 4.000000]; + + fss_sigma(1:8) = [-13.986685D0,-1.931973D0,-0.432011D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [10.718738D0,-1.389459D0,-0.182128D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [14.194791D0,-1.371650D0,-0.248285D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fpp_sigma(1:8) = [8.622023D0,-0.557144D0,-0.938551D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fpp_pi(1:8) = [-5.327397D0,-2.190160D0,-0.089303D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + + Es = 0; Ep = 0; U = 0; + elseif TYPE_b == 'N' +% fss_sigma(1:8) = [-7.010061 -1.730597 -0.575559 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fsp_sigma(1:8) = [7.543283 -1.293768 -0.624363 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fps_sigma(1:8) = [9.090970 -1.494255 -0.616711 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fpp_sigma(1:8) = [6.892240 -0.931920 -0.769164 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fpp_pi(1:8) = [-2.903346 -2.149349 -0.253006 0.000000 0.000000 1.500000 3.500000 4.000000]; + + fss_sigma(1:8) = [-7.409712D0,-1.940942D0,-0.219762D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [7.501761D0,-1.211169D0,-0.373905D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [8.697591D0,-1.267240D0,-0.178484D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + fpp_sigma(1:8) = [6.954600D0,-1.188456D0,-0.808043D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + fpp_pi(1:8) = [-2.921605D0,-2.203548D0,-0.409424D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + + Es = 0; Ep = 0; U = 0; + end +elseif TYPE_a == 'O' + if TYPE_b == 'H' +% fss_sigma(1:8) = [-12.230931 -1.808632 -0.421164 0.000000 0.000000 1.000000 3.500000 4.000000]; +% fsp_sigma(1:8) = [9.466088 -1.321262 -0.386336 0.000000 0.000000 1.000000 3.500000 4.000000]; +% fps_sigma(1:8) = [9.466088 -1.321262 -0.386336 0.000000 0.000000 1.000000 3.500000 4.000000]; + + fss_sigma(1:8) = [-12.189103D0,-1.800097D0,-0.325933D0,0.000D0,0.000D0,1.000D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [9.518733D0,-1.333235D0,-0.393710D0,0.000D0,0.000D0,1.000D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [9.518733D0,-1.333235D0,-0.393710D0,0.000D0,0.000D0,1.000D0,3.500D0,4.000D0]; + + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + Es = 0; Ep = 0; U = 0; + elseif TYPE_b == 'C' +% fss_sigma(1:8) = [-14.369472 -2.077439 -0.875471 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fsp_sigma(1:8) = [14.037374 -1.192632 -0.654572 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fps_sigma(1:8) = [9.576296 -1.156217 -0.494803 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_sigma(1:8) = [9.331152 -0.718120 -0.822100 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_pi(1:8) = [-5.334367 -2.263939 -0.204910 0.000000 0.000000 1.200000 3.500000 4.000000]; + + fss_sigma(1:8) = [-13.986685D0,-1.931973D0,-0.432011D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [14.194791D0,-1.371650D0,-0.248285D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [10.718738D0,-1.389459D0,-0.182128D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fpp_sigma(1:8) = [8.622023D0,-0.557144D0,-0.938551D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fpp_pi(1:8) = [-5.327397D0,-2.190160D0,-0.089303D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + + Es = 0; Ep = 0; U = 0; + elseif TYPE_b == 'O' +% fss_sigma(1:8) = [-12.737687 -1.851608 -0.666621 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fsp_sigma(1:8) = [13.683050 -1.684554 -0.468349 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fps_sigma(1:8) = [13.683050 -1.684554 -0.468349 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_sigma(1:8) = [9.460772 -1.211748 -0.581016 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_pi(1:8) = [-4.494595 -2.709223 -0.284124 0.000000 0.000000 1.200000 3.500000 4.000000]; + + fss_sigma(1:8) = [-14.387756D0,-2.244278D0,-1.645605D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + fsp_sigma(1:8) = [13.699127D0,-1.602358D0,-0.114474D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + fps_sigma(1:8) = [13.699127D0,-1.602358D0,-0.114474D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + fpp_sigma(1:8) = [9.235469D0,-1.131474D0,-0.924535D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + fpp_pi(1:8) = [ -4.526526D0,-2.487174D0,-0.201464D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + +% Es = -23.96; % E_s +% Ep = -9.02; % E_p +% U = 12.15; % U for O + + Es = -23.9377; % E_s + Ep = -9.0035; % E_p + U = 11.8761410; % U for O + + elseif TYPE_b == 'N' +% fss_sigma(1:8) = [-11.430028 -2.257346 -1.152844 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fsp_sigma(1:8) = [12.143744 -0.822913 -0.676127 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fps_sigma(1:8) = [11.597479 -1.382001 -0.765170 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_sigma(1:8) = [9.465191 -1.082032 -0.769214 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_pi(1:8) = [-4.676789 -2.171480 -0.288002 0.000000 0.000000 1.200000 3.500000 4.000000]; + + fss_sigma(1:8) = [-9.360078D0,-1.293118D0,-0.379415D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [10.723048D0,-0.454312D0,-0.916563D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [10.309052D0,-0.981652D0,-0.828497D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fpp_sigma(1:8) = [9.259131D0,-0.734112D0,-1.023762D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + fpp_pi(1:8) = [-4.532623D0,-1.999631D0,-0.286275D0,0.000D0,0.000D0,1.200D0,3.500D0,4.000D0]; + + Es = 0; Ep = 0; U = 0; + end +elseif TYPE_a == 'N' + if TYPE_b == 'H' +% fss_sigma(1:8) = [-12.095890 -1.519057 -0.277247 0.000000 0.000000 1.000000 3.500000 4.000000]; +% fsp_sigma(1:8) = [9.851338 -1.231616 -0.370836 0.000000 0.000000 1.000000 3.500000 4.000000]; +% fps_sigma(1:8) = [9.851338 -1.231616 -0.370836 0.000000 0.000000 1.000000 3.500000 4.000000]; + + fss_sigma(1:8) = [-12.631030D0,-1.585597D0,-0.250969D0,0.000D0,0.000D0,1.000D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [9.837852D0,-1.234850D0,-0.324283D0,0.000D0,0.000D0,1.000D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [9.837852D0,-1.234850D0,-0.324283D0,0.000D0,0.000D0,1.000D0,3.500D0,4.000D0]; + + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + Es = 0; Ep = 0; U = 0; + elseif TYPE_b == 'C' +% fss_sigma(1:8) = [-7.010061 -1.730597 -0.575559 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fsp_sigma(1:8) = [9.090970 -1.494255 -0.616711 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fps_sigma(1:8) = [7.543283 -1.293768 -0.624363 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fpp_sigma(1:8) = [6.892240 -0.931920 -0.769164 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fpp_pi(1:8) = [-2.903346 -2.149349 -0.253006 0.000000 0.000000 1.500000 3.500000 4.000000]; + + fss_sigma(1:8) = [-7.409712D0,-1.940942D0,-0.219762D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + fsp_sigma(1:8) = [8.697591D0,-1.267240D0,-0.178484D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + fps_sigma(1:8) = [7.501761D0,-1.211169D0,-0.373905D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + fpp_sigma(1:8) = [6.954600D0,-1.188456D0,-0.808043D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + fpp_pi(1:8) = [-2.921605D0,-2.203548D0,-0.409424D0,0.000D0,0.000D0,1.500D0,3.500D0,4.000D0]; + + Es = 0; Ep = 0; U = 0; + elseif TYPE_b == 'O' +% fss_sigma(1:8) = [-11.430028 -2.257346 -1.152844 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fsp_sigma(1:8) = [11.597479 -1.382001 -0.765170 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fps_sigma(1:8) = [12.143744 -0.822913 -0.676127 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_sigma(1:8) = [9.465191 -1.082032 -0.769214 0.000000 0.000000 1.200000 3.500000 4.000000]; +% fpp_pi(1:8) = [-4.676789 -2.171480 -0.288002 0.000000 0.000000 1.200000 3.500000 4.000000]; + + fss_sigma(1:8) = [-9.360078D0,-1.293118D0,-0.379415D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + fsp_sigma(1:8) = [10.309052D0,-0.981652D0,-0.828497D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + fps_sigma(1:8) = [10.723048D0,-0.454312D0,-0.916563D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + fpp_sigma(1:8) = [9.259131D0,-0.734112D0,-1.023762D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + fpp_pi(1:8) = [-4.532623D0,-1.999631D0,-0.286275D0,0.00D0,0.00D0,1.20D0,3.50D0,4.00D0]; + + Es = 0; Ep = 0; U = 0; + elseif TYPE_b == 'N' +% fss_sigma(1:8) = [-7.710330 -2.365312 -0.525527 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fsp_sigma(1:8) = [8.222314 -1.612118 -0.690081 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fps_sigma(1:8) = [8.222314 -1.612118 -0.690081 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fpp_sigma(1:8) = [7.178570 -1.176467 -0.571049 0.000000 0.000000 1.500000 3.500000 4.000000]; +% fpp_pi(1:8) = [-2.829344 -2.408049 -0.387709 0.000000 0.000000 1.500000 3.500000 4.000000]; + + fss_sigma(1:8) = [-7.165811D0,-2.348869D0,-0.541905D0,0.00D0,0.00D0,1.50D0,3.50D0,4.00D0]; + fsp_sigma(1:8) = [8.212268D0,-1.499123D0,-0.526440D0,0.00D0,0.00D0,1.50D0,3.50D0,4.00D0]; + fps_sigma(1:8) = [8.212268D0,-1.499123D0,-0.526440D0,0.00D0,0.00D0,1.50D0,3.50D0,4.00D0]; + fpp_sigma(1:8) = [7.102331D0,-1.252366D0,-0.552533D0,0.00D0,0.00D0,1.50D0,3.50D0,4.00D0]; + fpp_pi(1:8) = [-2.828938D0,-2.376886D0,-0.560898D0,0.00D0,0.00D0,1.50D0,3.50D0,4.00D0]; + +% Es = -18.58; % E_s +% Ep = -7.09; % E_p +% U = 15.93; % U for N + + Es = -18.5565; + Ep = -7.0625; + U = 17.3729; + + end +else + Es = 0; Ep = 0; U = 0; + fss_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fss_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fsp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fps_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; +end + +% Maybe better to pre-calculate? +fss_sigma = ScaleTail(fss_sigma); +fsp_sigma = ScaleTail(fsp_sigma); +fps_sigma = ScaleTail(fps_sigma); +fpp_sigma = ScaleTail(fpp_sigma); +fpp_pi = ScaleTail(fpp_pi); diff --git a/proxies/matlab/LoadBondIntegralParameters_S.m b/proxies/matlab/LoadBondIntegralParameters_S.m new file mode 100644 index 0000000..34e57ef --- /dev/null +++ b/proxies/matlab/LoadBondIntegralParameters_S.m @@ -0,0 +1,123 @@ +function [fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi] = LoadBondIntegralParameters_S(Type_pair) + +Type_a = Type_pair(1); +Type_b = Type_pair(2); + +if Type_a == 'H' + if Type_b == 'H' + fss_sigma(1:8) = [0.575007 -1.391261 -0.778831 0.080209 -0.017759 0.750000 3.500000 4.000000]; + fsp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fps_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + elseif Type_b == 'C' + fss_sigma(1:8) = [0.416003 -1.459596 -0.654874 0.009140 -0.012658 1.100000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.495695 -0.901626 -1.007214 0.189808 -0.057087 1.100000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.495695 -0.901626 -1.007214 0.189808 -0.057087 1.100000 3.500000 4.000000]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + elseif Type_b == 'O' + fss_sigma(1:8) = [0.404725 -1.702546 -0.707938 0.074904 -0.039922 1.000000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.447660 -0.952979 -1.163537 0.400616 -0.156965 1.000000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.447660 -0.952979 -1.163537 0.400616 -0.156965 1.000000 3.500000 4.000000]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + elseif Type_b == 'N' + fss_sigma(1:8) = [0.446693 -1.500463 -0.657448 0.065741 -0.037004 1.000000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.501530 -0.785734 -1.123232 0.394878 -0.148501 1.000000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.501530 -0.785734 -1.123232 0.394878 -0.148501 1.000000 3.500000 4.000000]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + end +elseif Type_a == 'C' + if Type_b == 'H' + fss_sigma(1:8) = [0.416003 -1.459596 -0.654874 0.009140 -0.012658 1.100000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.495695 -0.901626 -1.007214 0.189808 -0.057087 1.100000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.495695 -0.901626 -1.007214 0.189808 -0.057087 1.100000 3.500000 4.000000]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + elseif Type_b == 'C' + fss_sigma(1:8) = [0.346977 -1.519820 -0.570812 -0.013518 -0.015829 1.400000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.400467 -0.984048 -0.853949 0.157178 -0.073381 1.400000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.400467 -0.984048 -0.853949 0.157178 -0.073381 1.400000 3.500000 4.000000]; + fpp_sigma(1:8) = [-0.382417 0.102889 -2.786680 2.646356 -1.134320 1.400000 3.500000 4.000000]; + fpp_pi(1:8) = [0.214357 -1.948923 -0.578323 -0.034356 -0.007257 1.400000 3.500000 4.000000]; + elseif Type_b == 'O' + fss_sigma(1:8) = [0.375339 -1.547372 -0.642492 0.020614 -0.026699 1.200000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.373027 -0.776043 -1.019920 0.257539 -0.102838 1.200000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.458068 -1.035067 -0.937868 0.190562 -0.077841 1.200000 3.500000 4.000000]; + fpp_sigma(1:8) = [-0.322293 0.795473 -3.476601 2.589965 -0.897800 1.200000 3.500000 4.000000]; + fpp_pi(1:8) = [0.244570 -1.922717 -0.573671 -0.057280 -0.004108 1.200000 3.500000 4.000000]; + elseif Type_b == 'N' + fss_sigma(1:8) = [0.263438 -1.754525 -0.584215 -0.007801 -0.021729 1.500000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.326609 -1.197485 -0.807786 0.134891 -0.084373 1.500000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.337943 -1.335442 -0.769693 0.119373 -0.079493 1.500000 3.500000 4.000000]; + fpp_sigma(1:8) = [-0.350240 -0.467439 -1.849316 1.854403 -0.988471 1.500000 3.500000 4.000000]; + fpp_pi(1:8) = [0.158424 -2.114409 -0.582346 -0.051076 -0.006183 1.500000 3.500000 4.000000]; + end +elseif Type_a == 'O' + if Type_b == 'H' + fss_sigma(1:8) = [0.404725 -1.702546 -0.707938 0.074904 -0.039922 1.000000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.447660 -0.952979 -1.163537 0.400616 -0.156965 1.000000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.447660 -0.952979 -1.163537 0.400616 -0.156965 1.000000 3.500000 4.000000]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + elseif Type_b == 'C' + fss_sigma(1:8) = [0.375339 -1.547372 -0.642492 0.020614 -0.026699 1.200000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.458068 -1.035067 -0.937868 0.190562 -0.077841 1.200000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.373027 -0.776043 -1.019920 0.257539 -0.102838 1.200000 3.500000 4.000000]; + fpp_sigma(1:8) = [-0.322293 0.795473 -3.476601 2.589965 -0.897800 1.200000 3.500000 4.000000]; + fpp_pi(1:8) = [0.244570 -1.922717 -0.573671 -0.057280 -0.004108 1.200000 3.500000 4.000000]; + elseif Type_b == 'O' + fss_sigma(1:8) = [0.296445 -1.911896 -0.663451 0.038054 -0.046608 1.200000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.362143 -1.285274 -0.939591 0.204641 -0.106438 1.200000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.362143 -1.285274 -0.939591 0.204641 -0.106438 1.200000 3.500000 4.000000]; + fpp_sigma(1:8) = [-0.312044 0.121814 -2.519352 1.681266 -0.644566 1.200000 3.500000 4.000000]; + fpp_pi(1:8) = [0.193010 -2.168462 -0.580629 -0.105104 0.004891 1.200000 3.500000 4.000000]; + elseif Type_b == 'N' + fss_sigma(1:8) = [0.340064 -1.703613 -0.622348 0.036738 -0.040158 1.200000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.420014 -1.107918 -0.905594 0.188424 -0.088365 1.200000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.370946 -1.040947 -0.931097 0.252441 -0.115450 1.200000 3.500000 4.000000]; + fpp_sigma(1:8) = [-0.314073 0.499050 -2.914288 2.067657 -0.738439 1.200000 3.500000 4.000000]; + fpp_pi(1:8) = [0.223937 -1.991867 -0.537630 -0.081270 -0.004130 1.200000 3.500000 4.000000]; + end +elseif Type_a == 'N' + if Type_b == 'H' + fss_sigma(1:8) = [0.446693 -1.500463 -0.657448 0.065741 -0.037004 1.000000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.501530 -0.785734 -1.123232 0.394878 -0.148501 1.000000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.501530 -0.785734 -1.123232 0.394878 -0.148501 1.000000 3.500000 4.000000]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; + elseif Type_b == 'C' + fss_sigma(1:8) = [0.263438 -1.754525 -0.584215 -0.007801 -0.021729 1.500000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.337943 -1.335442 -0.769693 0.119373 -0.079493 1.500000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.326609 -1.197485 -0.807786 0.134891 -0.084373 1.500000 3.500000 4.000000]; + fpp_sigma(1:8) = [-0.350240 -0.467439 -1.849316 1.854403 -0.988471 1.500000 3.500000 4.000000]; + fpp_pi(1:8) = [0.158424 -2.114409 -0.582346 -0.051076 -0.006183 1.500000 3.500000 4.000000]; + elseif Type_b == 'O' + fss_sigma(1:8) = [0.340064 -1.703613 -0.622348 0.036738 -0.040158 1.200000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.370946 -1.040947 -0.931097 0.252441 -0.115450 1.200000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.420014 -1.107918 -0.905594 0.188424 -0.088365 1.200000 3.500000 4.000000]; + fpp_sigma(1:8) = [-0.314073 0.499050 -2.914288 2.067657 -0.738439 1.200000 3.500000 4.000000]; + fpp_pi(1:8) = [0.223937 -1.991867 -0.537630 -0.081270 -0.004130 1.200000 3.500000 4.000000]; + elseif Type_b == 'N' + fss_sigma(1:8) = [0.231654 -1.879002 -0.572765 -0.004579 -0.031106 1.500000 3.500000 4.000000]; + fsp_sigma(1:8) = [-0.305271 -1.385158 -0.751032 0.114531 -0.090839 1.500000 3.500000 4.000000]; + fps_sigma(1:8) = [-0.305271 -1.385158 -0.751032 0.114531 -0.090839 1.500000 3.500000 4.000000]; + fpp_sigma(1:8) = [-0.324668 -0.547805 -1.638658 1.495168 -0.827868 1.500000 3.500000 4.000000]; + fpp_pi(1:8) = [0.142909 -2.162036 -0.571942 -0.071640 -0.004682 1.500000 3.500000 4.000000]; + end +else + fss_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fsp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fps_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_sigma(1:8) = [0,0,0,0,0,0,0,0]; + fpp_pi(1:8) = [0,0,0,0,0,0,0,0]; +end + +% Maybe better to pre-calculate? +fss_sigma = ScaleTail(fss_sigma); +fsp_sigma = ScaleTail(fsp_sigma); +fps_sigma = ScaleTail(fps_sigma); +fpp_sigma = ScaleTail(fpp_sigma); +fpp_pi = ScaleTail(fpp_pi); diff --git a/proxies/matlab/Main.m b/proxies/matlab/Main.m new file mode 100644 index 0000000..59a05a5 --- /dev/null +++ b/proxies/matlab/Main.m @@ -0,0 +1,145 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% SCF-TB - PROXY APPLICATION % +% A.M.N. Niklasson, T1, LANL % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Total Energy: % +% E = 2Tr[H0(D-D0)] + (1/2)sum_{ij} q_i C_{ij} q_j - Efield*dipole % +% dipole = sum_i R_{i} q_i % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +clear; + +% Initial data, load atoms and coordinates, etc +%Nats = 50; % Number of atoms +%Nocc = 40; % Nr of electrons / 2 +Nats = 5; % Number of atoms +Nocc = 4; % Nr of electrons / 2 +Efield = 0*0.1*[0.90,0.0,-.00]'; %%% DOES NOT GIVE CRRECT FORCES FOR Efield > 0 +Te = 100 % Some electronic temperature +A = importdata('COORD.dat'); +TYPE = A.textdata(:); +RX = A.data(:,1); RY = A.data(:,2); RZ = A.data(:,3); +%LBox(1) = 14; LBox(2) = 14; LBox(3) = 14 % PBC +LBox(1) = 5; LBox(2) = 5; LBox(3) = 5 % PBC + +% Get Hamiltonian, Overlap, atomic DM = D0 (vector only), etc +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,4.0,Nats); +[H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nats,nrnnlist,nnRx,nnRy,nnRz,nnType); +HDIM = max(size(H0)); +Z = S^(-1/2); +Z0 = Z; S0 = S; +Rcut = 10.42; Coulomb_acc = 10e-7; TIMERATIO = 10; + +% Get Coulomb Matrix. In principle we do not need an explicit representation of the Coulomb matrix C! +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); +C = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nats,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); + +% SCF ground state optimization for H and D and q and occupation factors f, D*S*D = D, Tr[DS] = Nocc, f in [0,1] +[H,Hcoul,Hdipole,D,Dorth,q,f] = SCF(H0,S,Efield,C,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Nocc,Hubbard_U,Znuc,Nats,Te); + +[Etot,Eband0,Ecoul,Edipole,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,D,q,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent +Eneries = [Etot,Eband0,Ecoul,Edipole,S_ent] +ZI = S^(1/2); +DO = ZI*D*ZI'; + +dx = 0.0001; +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,4.0,Nats); +[dSx,dSy,dSz] = GetdS(Nats,dx,HDIM,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox,nrnnlist,nnRx,nnRy,nnRz,nnType); +[dHx,dHy,dHz] = GetdH(Nats,dx,HDIM,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox,nrnnlist,nnRx,nnRy,nnRz,nnType); +[dCx,dCy,dCz] = GetdC(Nats,dx,Coulomb_acc,Rcut,TIMERATIO,HDIM,Hubbard_U,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox); + +[Ftot,Fcoul,Fband0,Fdipole,FPulay,FScoul,FSdipole] = Forces(H,H0,S,C,D,D0,dHx,dHy,dHz,dSx,dSy,dSz,dCx,dCy,dCz,Efield,Hubbard_U,q,RX,RY,RZ,Nats,H_INDEX_START,H_INDEX_END); + +Force_1 = Ftot(1,:) +Force_2 = Ftot(2,:) +Force_2 = Ftot(3,:) +pause + +RX0 = RX; +%%%%%%%% FINITE DIFF FORCE + +DD = D; +q0 = Get_q(DD,S,H_INDEX_START,H_INDEX_END,Znuc,Nats); +CC = C; RX0 = RX; RY0 = RY; RZ0 = RZ; HH0 = H0; HH = H; + +RX = RX0; RX(1) = RX0(1) + 0.0001; + +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,4.0,Nats); +[H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nats,nrnnlist,nnRx,nnRy,nnRz,nnType); Z = S^(-1/2); +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); +C = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nats,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); +[H,Hcoul,Hdipole,D,Dorth,q,f] = SCF(H0,S,Efield,C,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Nocc,Hubbard_U,Znuc,Nats,Te); +%[Etot_p,Eband0_p,Ecoul_p,Edipole_p,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,DD,q0,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent +[Etot_p,Eband0_p,Ecoul_p,Edipole_p,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,D,q,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent +q_p = q; H_p = H; D_p = D; +q0_p = Get_q(DD,S,H_INDEX_START,H_INDEX_END,Znuc,Nats); + +RX = RX0; RX(1) = RX0(1) - 0.0001; +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,4.0,Nats); +[H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nats,nrnnlist,nnRx,nnRy,nnRz,nnType); Z = S^(-1/2); +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); +C = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nats,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); +[H,Hcoul,Hdipole,D,Dorth,q,f] = SCF(H0,S,Efield,C,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Nocc,Hubbard_U,Znuc,Nats,Te); +%[Etot_m,Eband0_m,Ecoul_m,Edipole_m,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,DD,q0,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent +[Etot_m,Eband0_m,Ecoul_m,Edipole_m,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,D,q,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent +q_m = q; H_m = H; D_m = D; +q0_m = Get_q(DD,S,H_INDEX_START,H_INDEX_END,Znuc,Nats); +RX = RX0; + +% Fixed charges d_ETOT = -0.241562399168060; +% Flexible charges d_ETOT = 0.164765711758719 +% Diff = -0.406328110926779 +d_ETOT = (Etot_p - Etot_m)/.0002 +F_analytic = Ftot(1,1) % = -0.214411998896872 with flexible D +ForceSum = Fcoul + Fband0 + Fdipole; % Correct for fixed D = DD and q = q0 +Force_without_FS = ForceSum(1,1) % = d_ETOT Correct for fixed D = DD and q = q0 +DipoleForce = Fdipole(1,1) +COmpare_Dipole_f = (Edipole_p - Edipole_m)/.0002 % = Fdipole(1,1) Correct for fixed D and q +f_Pul = FPulay(1,1) +fs_coul = FScoul(1,1) +fs_dip = FSdipole(1,1) +d_q = (q0_p - q0_m)/.0002; +fsForce = 0; +for i = 1:Nats + fsForce = fsForce + d_q(i)*(RX(i)*Efield(1) + RY(i)*Efield(2) + RZ(i)*Efield(3)); +end +fsForce % = FSdipole(1,1) Always correct + +%[Ftot,Fcoul,Fband0,Fdipole,FPulay,FScoul,FSdipole] = Forces(H,H0,S,C,D,D0,dHx,dHy,dHz,dSx,dSy,dSz,dCx,dCy,dCz,Efield,Hubbard_U,q,RX,RY,RZ,Nats,H_INDEX_START,H_INDEX_END); + +d_EBand0 = (Eband0_p-Eband0_m)/.0002 + +d_EBand = (2*trace(H_p*(D_p-diag(D0))) - 2*trace(H_m*(D_m-diag(D0))))/.0002 + +d_EDipole = (Edipole_p - Edipole_m)/.0002 +d_Ecoul = (Ecoul_p-Ecoul_m)/.0002 + +band0 = Fband0(1,1) +F_total = Ftot(1,1) +F_diople = Fdipole(1,1) + FSdipole(1,1) +FS_dipole = FSdipole(1,1) +F_coul = Fcoul(1,1) + FScoul(1,1) +FS_coul = FScoul(1,1) +F_pul = FPulay(1,1) +HEJ = 1 +pause + +RX = RX0; RX(1) = RX0(1) + 0.0001; +Edipole_p = 0; +for i = 1:Nats + Edipole_p = Edipole_p - q0(i)*(RX(i)*Efield(1)+RY(i)*Efield(2)+RZ(i)*Efield(3)); % External-field-Dipole interaction energy +end +RX = RX0; RX(1) = RX0(1) - 0.0001; +Edipole_m = 0; +for i = 1:Nats + Edipole_m = Edipole_m - q0(i)*(RX(i)*Efield(1)+RY(i)*Efield(2)+RZ(i)*Efield(3)); % External-field-Dipole interaction energy +end +d_FDipole = (Edipole_p - Edipole_m)/.0002 + +dq_dr = (q_p - q_m)/.0002; +d_Edipole_m = 0; +for i = 1:Nats + d_Edipole_m = d_Edipole_m - dq_dr(i)*(RX(i)*Efield(1)+RY(i)*Efield(2)+RZ(i)*Efield(3)); % External-field-Dipole interaction energy +end +d_EDipole = d_Edipole_m + +F11 = Fband0(1,1) + Fcoul(1,1) + FPulay(1,1) + FScoul(1,1) diff --git a/proxies/matlab/Main_save_00.m b/proxies/matlab/Main_save_00.m new file mode 100644 index 0000000..49895e9 --- /dev/null +++ b/proxies/matlab/Main_save_00.m @@ -0,0 +1,85 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% SCF-TB - PROXY APPLICATION % +% A.M.N. Niklasson, T1, LANL % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Total Energy: % +% E = 2Tr[H0(D-D0)] + (1/2)sum_{ij} q_i C_{ij} q_j - Efield*dipole % +% dipole = sum_i R_{i} q_i % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +clear; + +% Initial data, load atoms and coordinates, etc +Nats = 50; % Number of atoms +Nocc = 40; % Nr of electrons / 2 +Efield = 1*[-0.40,0.3,-0.31]'; +Te = 100 % Some electronic temperature +A = importdata('COORD.dat'); +TYPE = A.textdata(:); +RX = A.data(:,1); RY = A.data(:,2); RZ = A.data(:,3); +LBox(1) = 14; LBox(2) = 14; LBox(3) = 14 % PBC + +% Get Hamiltonian, Overlap, atomic DM = D0 (vector only), etc +[H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nats); +Z = S^(-1/2); +Z0 = Z; S0 = S; +HDIM = max(size(H0)); +Rcut = 10.42; Coulomb_acc = 10e-7; TIMERATIO = 10; + +% Get Coulomb Matrix. In principle we do not need an explicit representation of the Coulomb matrix C! +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); +C = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nats,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); + +% SCF ground state optimization for H and D and q and occupation factors f, D*S*D = D, Tr[DS] = Nocc, f in [0,1] +[H,Hcoul,Hdipole,D,q,f] = SCF(H0,S,Efield,C,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Nocc,Hubbard_U,Znuc,Nats,Te); +[Etot,Eband0,Ecoul,Edipole,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,D,q,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent + +%%%%%%%% Num Test Forces + +%%%%%%%%%%%%%%%%%%%%%%%% + +dx = 0.0001; +[dSx,dSy,dSz] = GetdS(Nats,dx,HDIM,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox); +[dHx,dHy,dHz] = GetdH(Nats,dx,HDIM,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox); +[dCx,dCy,dCz] = GetdC(Nats,dx,Coulomb_acc,Rcut,TIMERATIO,HDIM,Hubbard_U,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox); + +[Ftot,Fcoul,Fband0,Fdipole,FPulay,FScoul,FSdipole] = Forces(H,H0,S,C,D,D0,dHx,dHy,dHz,dSx,dSy,dSz,dCx,dCy,dCz,Efield,Hubbard_U,q,RX,RY,RZ,Nats,H_INDEX_START,H_INDEX_END); + +% Zero Field +% Ftot(1,3) = -2.640524966084072 +% q(1:3)' = 0.299074107847914 -0.075231905026516 -0.074189178585703 + +Force_11 = Ftot(1,1) + +RX0 = RX; +%%%%%%%% FINITE DIFF FORCE +RX = RX0; RX(1) = RX0(1) + 0.0001; +% Get Hamiltonian, Overlap, atomic DM = D0 (vector only), etc +[H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nats); +Z = S^(-1/2); + +% Get Coulomb Matrix. In principle we do not need an explicit representation of the Coulomb matrix C! +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); +C = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nats,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); + +% SCF ground state optimization for H and D and q and occupation factors f, D*S*D = D, Tr[DS] = Nocc, f in [0,1] +[H,Hcoul,Hdipole,D,q,f] = SCF(H0,S,Efield,C,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Nocc,Hubbard_U,Znuc,Nats,Te); +[Etot_p,Eband0,Ecoul,Edipole_p,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,D,q,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent +Edipole_p + +RX = RX0; RX(1) = RX0(1) - 0.0001; +% Get Hamiltonian, Overlap, atomic DM = D0 (vector only), etc +[H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nats); +Z = S^(-1/2); + +% Get Coulomb Matrix. In principle we do not need an explicit representation of the Coulomb matrix C! +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); +C = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nats,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); + +% SCF ground state optimization for H and D and q and occupation factors f, D*S*D = D, Tr[DS] = Nocc, f in [0,1] +[H,Hcoul,Hdipole,D,q,f] = SCF(H0,S,Efield,C,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Nocc,Hubbard_U,Znuc,Nats,Te); +[Etot_m,Eband0,Ecoul,Edipole_m,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,D,q,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent +Edipole_m + +dETOT = (Etot_p - Etot_m)/.0002 +%dFDipole = (Edipole_p - Edipole_m)/.0002 + diff --git a/proxies/matlab/Main_save_01.m b/proxies/matlab/Main_save_01.m new file mode 100644 index 0000000..2b31add --- /dev/null +++ b/proxies/matlab/Main_save_01.m @@ -0,0 +1,110 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% SCF-TB - PROXY APPLICATION % +% A.M.N. Niklasson, T1, LANL % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Total Energy: % +% E = 2Tr[H0(D-D0)] + (1/2)sum_{ij} q_i C_{ij} q_j - Efield*dipole % +% dipole = sum_i R_{i} q_i % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +clear; + +% Initial data, load atoms and coordinates, etc +Nats = 50; % Number of atoms +Nocc = 40; % Nr of electrons / 2 +Efield = 0.0*[0.90,0.0,-.00]'; +Te = 100 % Some electronic temperature +A = importdata('COORD.dat'); +TYPE = A.textdata(:); +RX = A.data(:,1); RY = A.data(:,2); RZ = A.data(:,3); +LBox(1) = 14; LBox(2) = 14; LBox(3) = 14 % PBC + +% Get Hamiltonian, Overlap, atomic DM = D0 (vector only), etc +[H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nats); +HDIM = max(size(H0)); +Z = S^(-1/2); +Z0 = Z; S0 = S; +Rcut = 10.42; Coulomb_acc = 10e-7; TIMERATIO = 10; + +% Get Coulomb Matrix. In principle we do not need an explicit representation of the Coulomb matrix C! +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); +C = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nats,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); + +% SCF ground state optimization for H and D and q and occupation factors f, D*S*D = D, Tr[DS] = Nocc, f in [0,1] +[H,Hcoul,Hdipole,D,q,f] = SCF(H0,S,Efield,C,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Nocc,Hubbard_U,Znuc,Nats,Te); +[Etot,Eband0,Ecoul,Edipole,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,D,q,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent + +dx = 0.0001; +[dSx,dSy,dSz] = GetdS(Nats,dx,HDIM,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox); +[dHx,dHy,dHz] = GetdH(Nats,dx,HDIM,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox); +[dCx,dCy,dCz] = GetdC(Nats,dx,Coulomb_acc,Rcut,TIMERATIO,HDIM,Hubbard_U,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Element_Type,LBox); + +[Ftot,Fcoul,Fband0,Fdipole,FPulay,FScoul,FSdipole] = Forces(H,H0,S,C,D,D0,dHx,dHy,dHz,dSx,dSy,dSz,dCx,dCy,dCz,Efield,Hubbard_U,q,RX,RY,RZ,Nats,H_INDEX_START,H_INDEX_END); + +Force_11 = Ftot(1,1) + +RX0 = RX; +%%%%%%%% FINITE DIFF FORCE + +DD = D; +q0 = Get_q(DD,S,H_INDEX_START,H_INDEX_END,Znuc,Nats); +CC = C; RX0 = RX; RY0 = RY; RZ0 = RZ; HH0 = H0; HH = H; + +RX = RX0; RX(1) = RX0(1) + 0.0001; +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); + +[H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nats); +C = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nats,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); +[H,Hcoul,Hdipole,D,q,f] = SCF(H0,S,Efield,C,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Nocc,Hubbard_U,Znuc,Nats,Te); +[Etot_p,Eband0_p,Ecoul_p,Edipole_p,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,D,q,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent +q_p = q; H_p = H; D_p = D; + +RX = RX0; RX(1) = RX0(1) - 0.0001; +[nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(RX,RY,RZ,LBox,Rcut,Nats); + +[H0,S,D0,H_INDEX_START,H_INDEX_END,Element_Type,Mnuc,Znuc,Hubbard_U] = H0_and_S(TYPE,RX,RY,RZ,LBox,Nats); +C = CoulombMatrix(RX,RY,RZ,LBox,Hubbard_U,Element_Type,Nats,HDIM,Coulomb_acc,TIMERATIO,nnRx,nnRy,nnRz,nrnnlist,nnType,H_INDEX_START,H_INDEX_END); +[H,Hcoul,Hdipole,D,q,f] = SCF(H0,S,Efield,C,RX,RY,RZ,H_INDEX_START,H_INDEX_END,Nocc,Hubbard_U,Znuc,Nats,Te); +[Etot_m,Eband0_m,Ecoul_m,Edipole_m,S_ent] = Energy(H0,Hubbard_U,Efield,D0,C,D,q,RX,RY,RZ,f,Te); % Energy calculation - 2*Te*S_ent +q_m = q; H_m = H; D_m = D; + +d_ETOT = (Etot_p - Etot_m)/.0002 +Ftot(1,1) + +pause +d_EBand0 = (Eband0_p-Eband0_m)/.0002 + +d_EBand = (2*trace(H_p*(D_p-diag(D0))) - 2*trace(H_m*(D_m-diag(D0))))/.0002 + +d_EDipole = (Edipole_p - Edipole_m)/.0002 +d_Ecoul = (Ecoul_p-Ecoul_m)/.0002 + +band0 = Fband0(1,1) +F_total = Ftot(1,1) +F_diople = Fdipole(1,1) + FSdipole(1,1) +FS_dipole = FSdipole(1,1) +F_coul = Fcoul(1,1) + FScoul(1,1) +FS_coul = FScoul(1,1) +F_pul = FPulay(1,1) +HEJ = 1 +pause + +RX = RX0; RX(1) = RX0(1) + 0.0001; +Edipole_p = 0; +for i = 1:Nats + Edipole_p = Edipole_p - q0(i)*(RX(i)*Efield(1)+RY(i)*Efield(2)+RZ(i)*Efield(3)); % External-field-Dipole interaction energy +end +RX = RX0; RX(1) = RX0(1) - 0.0001; +Edipole_m = 0; +for i = 1:Nats + Edipole_m = Edipole_m - q0(i)*(RX(i)*Efield(1)+RY(i)*Efield(2)+RZ(i)*Efield(3)); % External-field-Dipole interaction energy +end +d_FDipole = (Edipole_p - Edipole_m)/.0002 + +dq_dr = (q_p - q_m)/.0002; +d_Edipole_m = 0; +for i = 1:Nats + d_Edipole_m = d_Edipole_m - dq_dr(i)*(RX(i)*Efield(1)+RY(i)*Efield(2)+RZ(i)*Efield(3)); % External-field-Dipole interaction energy +end +d_EDipole = d_Edipole_m + +F11 = Fband0(1,1) + Fcoul(1,1) + FPulay(1,1) + FScoul(1,1) diff --git a/proxies/matlab/PBC_Coulomb.m b/proxies/matlab/PBC_Coulomb.m new file mode 100644 index 0000000..be9bcbc --- /dev/null +++ b/proxies/matlab/PBC_Coulomb.m @@ -0,0 +1,11 @@ +function [C] = PBC_Coulomb(R,L,N,U) + +C = zeros(N); +for i = 1:N + C(i,i) = U(i); + for j = i+1:N + Dist2 = min([(R(i)-R(j))^2,(R(i)-R(j)+L)^2,(R(i)-R(j)-L)^2]); + %C(i,j) = (U(i)+U(j))*exp(-4*sqrt(Dist2)); C(j,i) = C(i,j); + C(i,j) = (U(i)+U(j))*exp(-1*sqrt(Dist2)); C(j,i) = C(i,j); + end +end diff --git a/proxies/matlab/PBC_CoulombPot.m b/proxies/matlab/PBC_CoulombPot.m new file mode 100644 index 0000000..95f0997 --- /dev/null +++ b/proxies/matlab/PBC_CoulombPot.m @@ -0,0 +1,29 @@ +function [Vcoul,dVcoul] = PBC_CoulombPot(q,C,U) + + N = max(size(q)); + Vcoul = zeros(N,1); + dVcoul = zeros(N,N); + for i = 1:N + for j = 1:N + if i~=j + Vcoul(i) = Vcoul(i) + q(j)/norm(R(i)-R(j)); + else + Vcoul(i) = Vcoul(i) + q(i)*U(i); + end + end + end + + for k = 1:N + for i = 1:N + for j = 1:N + if j~=i + if i==k + dVcoul(i,k) = dVcoul(i,k) - q(j)*(R(i)-R(j))/(norm(R(i)-R(j))^3); + end + if j==k + dVcoul(i,k) = dVcoul(i,k) + q(j)*(R(i)-R(j))/(norm(R(i)-R(j))^3); + end + end + end + end + end diff --git a/proxies/matlab/PBC_Energy.m b/proxies/matlab/PBC_Energy.m new file mode 100644 index 0000000..8557eeb --- /dev/null +++ b/proxies/matlab/PBC_Energy.m @@ -0,0 +1,30 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Total energy calculation % +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [Etot,Eband0,Ecoul,Edipole,S_ent] = PBC_Energy(H0,Efield,D0,C,D,q,R,Te); + +%% E = 2*trace(H0*(D-D0)) + 0.5*sum_ij{i!=j} (qi*Cij*qj) + 0.5*sum_i qi^2*Ui - Efield*mu +%% dipole = mu(:) = sum_i qi*R(i,:); qi = 2*(D_ii-D0_ii) + +kB = 8.61739e-5; % eV/K; +N = max(size(q)); +Eband0 = 2*trace(H0*(D-D0)); % Single-particle/band energy + +Ecoul = 0.5*q'*C*q; % Coulomb energy + +Edipole = 0; +for i = 1:N + Edipole = Edipole - q(i)*R(i)*Efield; % External-field-Dipole interaction energy +end + +f = eig(D); +S_ent = 0; eps = 1e-9 +for i = 1:N + if (f(i) < 1-eps) & (f(i) > eps) + S_ent = - kB*(f(i)*log(f(i)) + (1-f(i))*log(1-f(i))); + end +end + +Etot = Eband0 + Ecoul + Edipole - 2*Te*S_ent; % Total energy + + diff --git a/proxies/matlab/PBC_Forces.m b/proxies/matlab/PBC_Forces.m new file mode 100644 index 0000000..8aeb7c1 --- /dev/null +++ b/proxies/matlab/PBC_Forces.m @@ -0,0 +1,36 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Calcualte total forces and some matrix derivatives % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [Ftot,dHdR,dCdR] = PBC_Forces(H0,Efield,D0,C,D,q,R,L,U,Rnd); + +N = max(size(q)); + +dHdR = 0*H0; +R0 = R; dR = 0.0001; +dEband0_dR = zeros(N,1); +dEcoul_dR = zeros(N,1); + +for i = 1:N + Rp = R0; + Rp(i,1) = Rp(i,1) + dR; % Finite difference forward displacement + Hp = PBC_Hamiltonian(Rp,L,N,Rnd); + Cp = PBC_Coulomb(Rp,L,N,U); + Rm = R0; + Rm(i,1) = Rm(i,1) - dR; % Finite difference backward displacement + Hm = PBC_Hamiltonian(Rm,L,N,Rnd); + Cm = PBC_Coulomb(Rm,L,N,U); + dHdR(:,i) = (Hp(:,i) - Hm(:,i))/(2*dR); %% H0 derivative collected columnwise. In reality dHdR = dHdR + dHdR' + dCdR(:,i) = (Cp(:,i) - Cm(:,i))/(2*dR); %% C derivative collected columnwise. In reality dCdR = dCdR + dCdR' +end %% Otherwise use q(:)'*dCdR(:,i), which is calculated in regular Ewald + +for i = 1:N % force contributions from band energy 2Tr[H(D-D0)] and Coulomb/Hartree energy (1/2) sum_{ij} q_i C_{ij}q_j + dEband0_dR(i) = 2*2*(D(i,:)-D0(i,:))*dHdR(:,i); + dEcoul_dR(i) = q(i)*q(:)'*dCdR(:,i); +end + +Fdipole = zeros(N,1); +for i = 1:N + Fdipole(i) = -q(i)*Efield; % Forces from External field-dipole interaction +end + +Ftot = - dEband0_dR - dEcoul_dR - Fdipole; % Collected total force diff --git a/proxies/matlab/PBC_Hamiltonian.m b/proxies/matlab/PBC_Hamiltonian.m new file mode 100644 index 0000000..4d85b51 --- /dev/null +++ b/proxies/matlab/PBC_Hamiltonian.m @@ -0,0 +1,12 @@ +function [H0] = PBC_Hamiltonian(R,L,N,Rnd) + +av = sum(Rnd)/N; +H0 = zeros(N); +for i = 1:N + H0(i,i) = 1*(Rnd(i)-av); + for j = i+1:N + Dist2 = min([(R(i)-R(j))^2,(R(i)-R(j)+L)^2,(R(i)-R(j)-L)^2]); + %H0(i,j) = (Rnd(i)+Rnd(j))*exp(-3*Dist2); H0(j,i) = H0(i,j); + H0(i,j) = (Rnd(i)+Rnd(j))*exp(-1*Dist2); H0(j,i) = H0(i,j); + end +end diff --git a/proxies/matlab/PBC_SCF.m b/proxies/matlab/PBC_SCF.m new file mode 100644 index 0000000..e33d93d --- /dev/null +++ b/proxies/matlab/PBC_SCF.m @@ -0,0 +1,21 @@ +function [H,Hcoul,Hdipole,D,q] = PBC_SCF(H0,Efield,D0,C,q,R,nocc,Te) + +N = max(size(H0)); +q_new = q; q_old = 0*q; +it = 0; res = 1; +Vdipole = zeros(N,1); +h = sort(eig(H0)); +mu0 = 0.5*(h(nocc)+h(nocc+1)); mu1 = 0; +while res > 1e-10 + it = it + 1; + Hdipole = diag(-R*Efield); + Hcoul = diag(C*q_new); + H = H0 + Hcoul + Hdipole; +% DA = DensityMatrix(H,nocc); % 2*trace(D) = Ne = 2*nocc + [D,mu0] = DM_Fermi(H,Te,mu0,nocc,16,1e-9,50); + q_old = q_new; + q = 2*diag(D-D0); + q_new = 0.2*q + (1-0.2)*q_old; + res = norm(q-q_old); +end + diff --git a/proxies/matlab/PBC_SCF_PRT.m b/proxies/matlab/PBC_SCF_PRT.m new file mode 100644 index 0000000..fe97eba --- /dev/null +++ b/proxies/matlab/PBC_SCF_PRT.m @@ -0,0 +1,43 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% SCF linear response calculation with respect to perturbation H1 % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [H,H_1,Hcoul,Hdipole,D,D1,q] = PBC_SCF_PRT(H0,H1,C,Efield,D0,U,q,R,mu0,nocc,Te) + +mu1 = 0; +N = max(size(H0)); +q_new = q; q_old = 0*q; % Initial guess +q1 = 0*q; q1_new = q1; q1_old = q1; % Initial guess +Vdipole = zeros(N,1); + +it = 0; +while norm(q-q_old)+norm(q1-q1_old) > 1e-9 % Continue until convergence + it = it + 1; + + V1coul = C*q1_new; % Linear response in Coulomb/Hartree potential + + Vcoul = C*q_new; % Coulomb/Hartree potential + Hcoul = diag(Vcoul); % Hamiltonian from the linear response in Coulomb/Hartree potential + Hdipole = diag(-R*Efield); % Hamiltonian from external field dipole interaction + + H_1 = H1 + diag(V1coul); % Total net linear response Hamiltonian + H = H0 + Hcoul + Hdipole; % Total 0th-order Hamiltonian +% [D,D1] = DensityMatrixPRT(H,H_1,nocc); % 2*trace(D) = Ne = 2*nocc, D = density matrix, D1 = response density matrix + [D,D1,mu0,mu1] = DM_PRT_Fermi(H,H_1,Te,mu0,mu1,nocc,16,1e-9,20); +% Occ_Err = trace(D)-nocc +% OccErr1 = trace(D1)-0 +% IdErr = norm(D*D-D) +% IdErr1 = norm(D1*D+D*D1-D1) +% ComErr = norm(D*H-H*D) +% ComErr1 = norm(D1*H-H*D1 + D*H_1-H_1*D) + + q1_old = q1_new; + q1 = 2*diag(D1); + q1_new = 0.1*q1 + (1-0.1)*q1_old; % Simple linear mixing + + q_old = q_new; + q = 2*diag(D-D0); + q_new = 0.1*q + (1-0.1)*q_old; % Simple linear mixing + Res = norm(q-q_old) +norm(q1-q1_old) ; + %pause +end + diff --git a/proxies/matlab/PBC_SCF_PRT_0.m b/proxies/matlab/PBC_SCF_PRT_0.m new file mode 100644 index 0000000..fc92aa7 --- /dev/null +++ b/proxies/matlab/PBC_SCF_PRT_0.m @@ -0,0 +1,42 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% SCF linear response calculation with respect to perturbation H1 % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [H,H_1,Hcoul,Hdipole,D,D1,q] = PBC_SCF_PRT_0(H0,H1,C,Efield,D0,U,q,R,nocc) + +N = max(size(H0)); +q_new = q; q_old = 0*q; % Initial guess +q1 = 0*q; q1_new = q1; q1_old = q1; % Initial guess +Vdipole = zeros(N,1); + +it = 0; +while norm(q-q_old)+norm(q1-q1_old) > 1e-9 % Continue until convergence + it = it + 1; + + V1coul = C*q1_new; % Linear response in Coulomb/Hartree potential + + Vcoul = C*q_new; % Coulomb/Hartree potential + Hcoul = diag(Vcoul); % Hamiltonian from the linear response in Coulomb/Hartree potential + Hdipole = diag(-R*Efield); % Hamiltonian from external field dipole interaction + + H_1 = H1 + diag(V1coul); % Total net linear response Hamiltonian + H = H0 + Hcoul + Hdipole; % Total 0th-order Hamiltonian + [D,D1] = DensityMatrixPRT(H,H_1,nocc); % 2*trace(D) = Ne = 2*nocc, D = density matrix, D1 = response density matrix +% OccErr = trace(D)-nocc +% OccErr1 = trace(D1)-0 +% IdErr = norm(D*D-D) +% IdErr1 = norm(D1*D+D*D1-D1) +% ComErr = norm(D*H-H*D) +% ComErr1 = norm(D1*H-H*D1 + D*H_1-H_1*D) +% pause + + + + q1_old = q1_new; + q1 = 2*diag(D1); + q1_new = 0.1*q1 + (1-0.1)*q1_old; % Simple linear mixing + + q_old = q_new; + q = 2*diag(D-D0); + q_new = 0.1*q + (1-0.1)*q_old; % Simple linear mixing +end + diff --git a/proxies/matlab/PBC_SCF_PRT_X.m b/proxies/matlab/PBC_SCF_PRT_X.m new file mode 100644 index 0000000..f05bd92 --- /dev/null +++ b/proxies/matlab/PBC_SCF_PRT_X.m @@ -0,0 +1,48 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% SCF linear response calculation with respect to atomic displacements % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [H,H_1,Hcoul,Hdipole,dVcoul,D,D1,q] = PBC_SCF_PRT_X(H0,dHdR,C,dCdR,Efield,D0,U,q,R,mu0,nocc,k,Te) + +N = max(size(H0)); +q_new = q; q_old = 0*q; +q1 = 0*q; q1_new = q1; q1_old = q1; +Vdipole = zeros(N,1); +mu1 = 0; + +H1 = zeros(N); +H1(:,k) = dHdR(:,k); +H1 = H1 + H1'; + +it = 0; +while norm(q-q_old)+norm(q1-q1_old) > 1e-9 + it = it + 1; + + V1coul = C*q1_new; % Linear response in Hartree/Coulomb potential from charge response due to dsiplacement + + dVcoul = dCdR(:,k)*q_new(k); % Linear response in Hartree/Coulomb potential from displacement only + dVcoul(k) = dVcoul(k) + q_new'*dCdR(:,k); % Combined total linear response in Hartree/Coulomb energy from displacement + + Vcoul = C*q_new; % Coulomb/Hartree potential + Hcoul = diag(Vcoul); % Coulomb/Hartree Hamiltonian + Hdipole = diag(-R*Efield); % Hamiltonian from external field-dipole interaction + dR = 0*R; dR(k) = 1; + + H_1 = H1 + diag(V1coul) + diag(dVcoul) + diag(-dR*Efield); % Linear response Hamiltonian + H = H0 + Hcoul + Hdipole; % Total ground-state Kohn-Sham Hamiltonian +% [D,D1] = DensityMatrixPRT(H,H_1,nocc); % 2*trace(D) = Ne = 2*nocc, D = density matrix, D1 = response density matrix +% Occ1 = trace(D1) + [D,D1,mu0,mu1] = DM_PRT_Fermi(H,H_1,Te,mu0,mu1,nocc,16,1e-9,20); +% Occ2 = trace(D1) +% IdFel = norm(D*D-D) +% norm(q-q_old)+norm(q1-q1_old) +% pause + + q1_old = q1_new; + q1 = 2*diag(D1); % Linear response in atom-projected charges + q1_new = 0.1*q1 + (1-0.1)*q1_old; % Simple linear mixing + + q_old = q_new; + q = 2*diag(D-D0); % Atomic charges + q_new = 0.1*q + (1-0.1)*q_old; % Simple linear mixing +end + diff --git a/proxies/matlab/PBC_main.m b/proxies/matlab/PBC_main.m new file mode 100644 index 0000000..3c85308 --- /dev/null +++ b/proxies/matlab/PBC_main.m @@ -0,0 +1,101 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Dual Susceptibility approach to calculate Born-Effective charges % +% 1-dimensional DFTB example with periodic boundary conditions % +% A.M.N. Niklasson, T1, LANL % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Todo: Implement in DFTB/LATTE, which includes % +% 0) Extenson from 1D to 3D with x,y, and z % +% 1) Extension to fractional occupation Te > 0, Done! % +% 2) Extension to general non-orthonormal basis sets % +% 3) If possible, do Periodic Boundary Conditions correctly, % +% without results depending on the edges in Hdipole, Correct!% +% 4) Implement response calculation with AI hardware/GPU % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Total Energy: % +% E = 2Tr[H0(D-D0)] + (1/2)sum_{ij} q_i C_{ij} q_j - Efield*dipole % +% dipole = sum_i R_{i} q_i, half filled, 1 basis-function/atom % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +clear; +N = 20; % N > 2 % Number of atoms and basis functions +Te = 50000 % Some electronic temperature +Efield = 0.0000; % External field +/- dEfield give the BEQ from force derivative +atoms = [1:N]; % Atomic positions +R0 = atoms; +atoms = [N-1:N,1:N-2]; % Atomic positions shifted cyclically => same BEQ but shifted +SEED = atoms; Rnd = (sin(2.4+3*SEED(:).^3-sin(pi*SEED(:)/N))); % "Randomized" seed for models +Rnd2 = (10 + 1*(sin(12+3.3*SEED(:).^5-sin(pi*SEED(:))))); % "Randomized" seed for models +R = atoms'; L = N; %R = R + 3.3; +U = Rnd2; +D0 = eye(N)/2; nocc = N/2; % Atomic denity matrix +H0 = PBC_Hamiltonian(R,L,N,Rnd); C = PBC_Coulomb(R,L,N,U); % Hamiltonian H0 and Coulomb matrix C, toy models + +n = N; M = 1; % M is the number of unit cells +Rtmp = R; Rndtmp = Rnd; Rndtmp2 = Rnd2; +for i = 1:M + R((i-1)*n+1:i*n) = (i-1)*L + Rtmp(1:n); + Rnd((i-1)*n+1:i*n) = Rndtmp(1:n); + Rnd2((i-1)*n+1:i*n) = Rndtmp2(1:n); +end +N = n*M; L = N; nocc = N/2; D0 = eye(N)/2; +U = Rnd2; +H0 = PBC_Hamiltonian(R,L,N,Rnd); C = PBC_Coulomb(R,L,N,U); % Hamiltonian H0 and Coulomb matrix C, toy models + +[D,mu0] = DensityMatrix(H0,nocc); q = 2*(diag(D-D0)); % Density matrix and first initial charge guess +[D,mu0] = DM_Fermi(H0,Te,mu0,nocc,16,1e-9,100); +[H,Hcoul,Hdipole,D,q] = PBC_SCF(H0,Efield,D0,C,q,R,nocc,Te); % Self-consistent optimization + +[Etot,Eband0,Ecoul,Edipole,S_ent] = PBC_Energy(H0,Efield,D0,C,D,q,R,Te); % Energy calculation - 2*Te*S_ent +[Ftot,dHdR,dCdR] = PBC_Forces(H0,Efield,D0,C,D,q,R,L,U,Rnd); % Forces and H0 and C derviative matrices (column wise) + +A = diag(R0); % Position operator +a_dipole = 2*trace(A*(D-D0)) % Dipole +alt_a_dipole = R'*q +pause + +%%% Calculate response in dipole with respect to atomic displacement, i.e. where d_dipole/dR_k = d^2_E//(dRk dEfield) +%%%% Use direct perturbation with respect to displacement, calculated sepconsistently as in DF-PRT +for k = 1:N + [H,H_1,Hcoul,Hdipole,dVcoul,D,D1,q] = PBC_SCF_PRT_X(H0,dHdR,C,dCdR,Efield,D0,U,q,R,mu0,nocc,k,Te); % N number of SCF_PRT, one for each k!!! +% ![H,H_1,Hcoul,Hdipole,dVcoul,D,D1,q] = PBC_SCF_PRT_X(H0,dHdR,C,dCdR,Efield,D0,U,q,R0,mu0,nocc,k,Te); % N number of SCF_PRT, one for each k!!! +q1 = diag(D1); +[k,q(1:10)']; +[k,q1(1:10)']; + + dA = 0*A; dA(k,k) = 1; + dadR(k) = 2*trace(A*D1) + 2*trace(dA*(D-D0)); % d_dipole/dR_k = d^2_E//(dRk dEfield) = 2*R'*q1 + 2*q(k); + Same = [dadR(k) ,2*R0*q1 + q(k)]; +end +a_dipole = R'*q +a_dipole_R0 = R0*q + +%% Use dual SCF susceptibility approach to DF-PRT with respect to dipole observable A +%% Susceptibility for dipole observable -> XA +A0 = A; +Q = eye(N)-D; +%[H,H_1,Hcoul,Hdipole,D,XA,q] = PBC_SCF_PRT(H0,A,C,Efield,D0,U,q,R,mu0,nocc,Te); % Only one SCF_PRT using the dual susceptibility approach!!! +[H,H_1,Hcoul,Hdipole,D,XA,q] = PBC_SCF_PRT(H0,A,C,Efield,D0,U,q,R0,mu0,nocc,Te); % Only one SCF_PRT using the dual susceptibility approach!!! +%[H,H_1,Hcoul,Hdipole,D,XA,q] = PBC_SCF_PRT_0(H0,A,C,Efield,D0,U,q,R,nocc); % At Te = 0 + +for k = 1:N %% Calculate dipole response using XA susceptibility + dA = 0*A; dA(k,k) = 1; + dVcoul = zeros(N,1); dR = zeros(N,1); dR(k) = 1; + dH = zeros(N); + dH(:,k) = dHdR(:,k); + dH = dH + dH'; + + dVcoul = dCdR(:,k)*q(k); dVcoul(k) = dVcoul(k) + q'*dCdR(:,k); + dH = dH + diag(dVcoul) + diag(-dR*Efield); + + da_dR(k) = 2*trace(XA*dH) + 2*trace(dA*(D-D0)); % d_dipole/dR_k = d^2_E//(dRk dEfield) from susceptibility calculation +end + +a_dipole = 2*trace(A*(D-D0)) % Still the same! + +% Check equivalence between the direct DF-PRT approach and the dual susceptibility formulation +Reldiff = norm(dadR-da_dR)/norm(dadR) +%q' +mm = 2 +dadR +da_dR +%da_dR(n*(mm-1)+1:mm*n) +%da_dR(n*mm+1:(mm+1)*n) diff --git a/proxies/matlab/SCF.m b/proxies/matlab/SCF.m new file mode 100644 index 0000000..2cb606e --- /dev/null +++ b/proxies/matlab/SCF.m @@ -0,0 +1,50 @@ +function [H,Hcoul,Hdipole,D,Dorth,q,f] = SCF(H0,S,Efield,C,Rx,Ry,Rz,H_Index_Start,H_Index_End,nocc,U,Znuc,Nats,Te) + +N = max(size(H0)); +it = 0; Res = 1; +Z = S^(-1/2); +h = sort(eig(Z'*H0*Z)); +mu0 = 0.5*(h(nocc)+h(nocc+1)); +[D,mu0] = DM_Fermi(Z'*H0*Z,Te,mu0,nocc,16,1e-9,50); +D = Z*D*Z'; +DS = 2*diag(D*S); +q = zeros(Nats,1); +for i = 1:Nats + q(i) = sum(DS(H_Index_Start(i):H_Index_End(i))) - Znuc(i); +end + +while Res > 1e-10 + it = it + 1; + Dipole = diag(-Rx*Efield(1)-Ry*Efield(2)-Rz*Efield(3)); + Hdipole = zeros(N); + CoulPot = C*q; + + Hcoul = zeros(N); + for i = 1:Nats + for j = H_Index_Start(i):H_Index_End(i) + Hdipole(j,j) = Dipole(i); + Hcoul(j,j) = U(i)*q(i) + CoulPot(i); + end + end + + Hcoul = 0.5*Hcoul*S + 0.5*S*Hcoul; + Hdipole = 0.5*Hdipole*S + 0.5*S*Hdipole; + H = H0 + Hcoul + Hdipole; + + [Dorth,mu0] = DM_Fermi(Z'*H*Z,Te,mu0,nocc,16,1e-9,50); + + D = Z*Dorth*Z'; + q_old = q; + + DS = 2*diag(D*S); + for i = 1:Nats + q(i) = sum(DS(H_Index_Start(i):H_Index_End(i))) - Znuc(i); + end + + Res = norm(q-q_old); + + q = q_old + 0.2*(q-q_old); + +end +f = eig(0.5*(Dorth+Dorth')); + diff --git a/proxies/matlab/SCF_save_00.m b/proxies/matlab/SCF_save_00.m new file mode 100644 index 0000000..7dc14a2 --- /dev/null +++ b/proxies/matlab/SCF_save_00.m @@ -0,0 +1,50 @@ +function [H,Hcoul,Hdipole,D,q,f] = SCF(H0,S,Efield,C,Rx,Ry,Rz,H_Index_Start,H_Index_End,nocc,U,Znuc,Nats,Te) + +N = max(size(H0)); +it = 0; Res = 1; +Z = S^(-1/2); +h = sort(eig(Z'*H0*Z)); +mu0 = 0.5*(h(nocc)+h(nocc+1)); +[D,mu0] = DM_Fermi(Z'*H0*Z,Te,mu0,nocc,16,1e-9,50); +D = Z*D*Z'; +DS = 2*diag(D*S); +q = zeros(Nats,1); +for i = 1:Nats + q(i) = sum(DS(H_Index_Start(i):H_Index_End(i))) - Znuc(i); +end + +while Res > 1e-10 + it = it + 1; + Dipole = diag(-Rx*Efield(1)-Ry*Efield(2)-Rz*Efield(3)); + Hdipole = zeros(N); + CoulPot = C*q; + + Hcoul = zeros(N); + for i = 1:Nats + for j = H_Index_Start(i):H_Index_End(i) + Hdipole(j,j) = Dipole(i); + Hcoul(j,j) = U(i)*q(i) + CoulPot(i); + end + end + + Hcoul = 0.5*Hcoul*S + 0.5*S*Hcoul; + Hdipole = 0.5*Hdipole*S + 0.5*S*Hdipole; + H = H0 + Hcoul + Hdipole; + + [Dorth,mu0] = DM_Fermi(Z'*H*Z,Te,mu0,nocc,16,1e-9,50); + + D = Z*Dorth*Z'; + q_old = q; + + DS = 2*diag(D*S); + for i = 1:Nats + q(i) = sum(DS(H_Index_Start(i):H_Index_End(i))) - Znuc(i); + end + + Res = norm(q-q_old); + + q = q_old + 0.2*(q-q_old); + +end +f = eig(0.5*(Dorth+Dorth')); + diff --git a/proxies/matlab/ScaleTail.m b/proxies/matlab/ScaleTail.m new file mode 100644 index 0000000..51d1ff1 --- /dev/null +++ b/proxies/matlab/ScaleTail.m @@ -0,0 +1,26 @@ +function A = ScaleTail(A) +if abs(A(1)) < 1e-12 + A(9:14) = 0; +else + R1 = A(7); + RCUT = A(8); + R1SQ = R1*R1; + RMOD = R1 - A(6); + POLYNOM = RMOD*(A(2) + RMOD*(A(3) + RMOD*(A(4) + A(5)*RMOD))); + SCL_R1 = exp(POLYNOM); + DELTA = RCUT - R1; +%! Now we're using a 6th order polynomial: fitted to value, first, +%! and second derivatives at R1 and R_cut + A(9) = SCL_R1; + RMOD = R1 - A(6); + DPOLY = A(2) + 2*A(3)*RMOD + 3*A(4)*RMOD*RMOD + 4*A(5)*RMOD*RMOD*RMOD; + A(10) = DPOLY*SCL_R1; + DDPOLY = 2*A(3) + 6*A(4)*RMOD + 12*A(5)*RMOD*RMOD; + A(11) = (DPOLY*DPOLY + DDPOLY)*SCL_R1/2; + DELTA2 = DELTA*DELTA; + DELTA3 = DELTA2*DELTA; + DELTA4 = DELTA3*DELTA; + A(12) = (-1/DELTA3)*(3*A(11)*DELTA2 + 6*A(10)*DELTA + 10*A(9)); + A(13) = (1/DELTA4)*(3*A(11)*DELTA2 + 8*A(10)*DELTA + 15*A(9)); + A(14) = (-1/(10*DELTA3))*(6*A(13)*DELTA2 + 3*A(12)*DELTA + A(11)); +end diff --git a/proxies/matlab/Slater_Koster_Block.m b/proxies/matlab/Slater_Koster_Block.m new file mode 100644 index 0000000..2954230 --- /dev/null +++ b/proxies/matlab/Slater_Koster_Block.m @@ -0,0 +1,104 @@ +function x0 = Slater_Koster_Block(IDim,JDim,Ra,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal) + +%%% Standard Slater-Koster sp-parameterization for an atomic block between a pair of atoms +%%% IDim, JDim: dimensions of the output block, e.g. 1 x 4 for H-O or 4 x 4 for O-O, or 4 x 1 for O-H +%%% Ra, Rb: are the vectors of the positions of the two atoms +%%% LBox: Periodic boundary conditions, i.e. length of box in x, y, z (cubic box only) +%%% Type_pair(1 or 2): Character of the type of each atom in the pair, e.g. 'H' for hydrogen of 'O' for oxygen +%%% fss_sigma, ... , fpp_pi: paramters for the bond integrals +%%% diagonal(1 or 2): atomic energies Es and Ep or diagonal elements of the overlap i.e. diagonal = 1 + + +atom_type_a = Type_pair(1); atom_type_b = Type_pair(2); +x0 = zeros(IDim,JDim); +RXb = Rb(1); RYb = Rb(2); RZb = Rb(3); + +for nr_shift_X = -1:1 % Periodic BC shifts in X, Y and Z. Costs a lot extra! +for nr_shift_Y = -1:1 +for nr_shift_Z = -1:1 + + Rb(1) = RXb + nr_shift_X*LBox(1); % Shifts for PBC + Rb(2) = RYb + nr_shift_Y*LBox(2); + Rb(3) = RZb + nr_shift_Z*LBox(3); + Rab = Rb-Ra; % OBS b - a !!! + dR = norm(Rab); + + if dR < 1e-12 % same position and thus the same type atom_type_a = atom_type_b, Ra = Rb + if atom_type_a == 'H' % s atom 1 x 1 + x0(1,1) = x0(1,1) + diagonal(1); % diagonal(1) = Es for atoms, = 1 for overlap + else % sp atom 4 x 4 Diagonal Only + x0(1,1) = x0(1,1) + diagonal(1); % diagonal(1) = Es for atoms, = 1 for overlap + x0(2,2) = x0(2,2) + diagonal(2); % diagonal(2) = Ep for atoms, = 1 for overlap + x0(3,3) = x0(3,3) + diagonal(2); + x0(4,4) = x0(4,4) + diagonal(2); + end + else + L = Rab(1)/dR; % Direction cosines + M = Rab(2)/dR; + N = Rab(3)/dR; + + if atom_type_a == 'H' + if atom_type_b == 'H' % s-s overlap 1 x 1 block + HSSS = BondIntegral(dR,fss_sigma); % Calculate the s-s bond integral + x0(1,1) = x0(1,1) + HSSS; + else % s-sp overlap 1 x 4 block + HSSS = BondIntegral(dR,fss_sigma); + HSPS = BondIntegral(dR,fsp_sigma); + x0(1,1) = x0(1,1) + HSSS; + x0(1,2) = x0(1,2) + L*HSPS; + x0(1,3) = x0(1,3) + M*HSPS; + x0(1,4) = x0(1,4) + N*HSPS; + end + else + if atom_type_b == 'H' % sp-s overlap 4 x 1 block + HSSS = BondIntegral(dR,fss_sigma); + HSPS = BondIntegral(dR,fsp_sigma); + x0(1,1) = x0(1,1) + HSSS; + x0(2,1) = x0(2,1) - L*HSPS; + x0(3,1) = x0(3,1) - M*HSPS; + x0(4,1) = x0(4,1) - N*HSPS; + else % sp-sp overlap + HSSS = BondIntegral(dR,fss_sigma); + HSPS = BondIntegral(dR,fsp_sigma); + HPSS = BondIntegral(dR,fps_sigma); + HPPS = BondIntegral(dR,fpp_sigma); + HPPP = BondIntegral(dR,fpp_pi); + + PPSMPP = HPPS - HPPP; + PXPX = HPPP + L*L*PPSMPP; + PXPY = L*M*PPSMPP; + PXPZ = L*N*PPSMPP; + PYPX = M*L*PPSMPP; + PYPY = HPPP + M*M*PPSMPP; + PYPZ = M*N*PPSMPP; + PZPX = N*L*PPSMPP; + PZPY = N*M*PPSMPP; + PZPZ = HPPP + N*N*PPSMPP; + + x0(1,1) = x0(1,1) + HSSS; + x0(1,2) = x0(1,2) + L*HSPS; % or 0 + x0(1,3) = x0(1,3) + M*HSPS; % or 0 + x0(1,4) = x0(1,4) + N*HSPS; % or 0 + + x0(2,1) = x0(2,1) - L*HPSS; % or 0 + + x0(2,2) = x0(2,2) + PXPX; + x0(2,3) = x0(2,3) + PXPY; + x0(2,4) = x0(2,4) + PXPZ; + + x0(3,1) = x0(3,1) - M*HPSS; % or 0 + + x0(3,2) = x0(3,2) + PYPX; + x0(3,3) = x0(3,3) + PYPY; + x0(3,4) = x0(3,4) + PYPZ; + x0(4,1) = x0(4,1) - N*HPSS; % or 0 + x0(4,2) = x0(4,2) + PZPX; + x0(4,3) = x0(4,3) + PZPY; + x0(4,4) = x0(4,4) + PZPZ; + end + end + end +end +end +end + diff --git a/proxies/matlab/Slater_Koster_Pair.m b/proxies/matlab/Slater_Koster_Pair.m new file mode 100644 index 0000000..c0f69c3 --- /dev/null +++ b/proxies/matlab/Slater_Koster_Pair.m @@ -0,0 +1,94 @@ +function x0 = Slater_Koster_Block(Ra,Rb,LBox,Type_pair,fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,diagonal) + +%%% Standard Slater-Koster sp-parameterization for an atomic block between a pair of atoms +%%% IDim, JDim: dimensions of the output block, e.g. 1 x 4 for H-O or 4 x 4 for O-O, or 4 x 1 for O-H +%%% Ra, Rb: are the vectors of the positions of the two atoms +%%% LBox: Periodic boundary conditions, i.e. length of box in x, y, z (cubic box only) +%%% Type_pair(1 or 2): Character of the type of each atom in the pair, e.g. 'H' for hydrogen of 'O' for oxygen +%%% fss_sigma, ... , fpp_pi: paramters for the bond integrals +%%% diagonal(1 or 2): atomic energies Es and Ep or diagonal elements of the overlap i.e. diagonal = 1 + + +atom_type_a = Type_pair(1); atom_type_b = Type_pair(2); +x0 = zeros(4); +RXb = Rb(1); RYb = Rb(2); RZb = Rb(3); + + Rab = Rb-Ra; % OBS b - a !!! + dR = norm(Rab); + + if dR < 1e-10 % same position and thus the same type atom_type_a = atom_type_b, Ra = Rb + if atom_type_a == 'H' % s atom 1 x 1 + x0(1,1) = x0(1,1) + diagonal(1); % diagonal(1) = Es for atoms, = 1 for overlap + else % sp atom 4 x 4 Diagonal Only + x0(1,1) = x0(1,1) + diagonal(1); % diagonal(1) = Es for atoms, = 1 for overlap + x0(2,2) = x0(2,2) + diagonal(2); % diagonal(2) = Ep for atoms, = 1 for overlap + x0(3,3) = x0(3,3) + diagonal(2); + x0(4,4) = x0(4,4) + diagonal(2); + end + else + L = Rab(1)/dR; % Direction cosines + M = Rab(2)/dR; + N = Rab(3)/dR; + + if atom_type_a == 'H' + if atom_type_b == 'H' % s-s overlap 1 x 1 block + HSSS = BondIntegral(dR,fss_sigma); % Calculate the s-s bond integral + x0(1,1) = x0(1,1) + HSSS; + else % s-sp overlap 1 x 4 block + HSSS = BondIntegral(dR,fss_sigma); + HSPS = BondIntegral(dR,fsp_sigma); + x0(1,1) = x0(1,1) + HSSS; + x0(1,2) = x0(1,2) + L*HSPS; + x0(1,3) = x0(1,3) + M*HSPS; + x0(1,4) = x0(1,4) + N*HSPS; + end + else + if atom_type_b == 'H' % sp-s overlap 4 x 1 block + HSSS = BondIntegral(dR,fss_sigma); + HSPS = BondIntegral(dR,fsp_sigma); + x0(1,1) = x0(1,1) + HSSS; + x0(2,1) = x0(2,1) - L*HSPS; + x0(3,1) = x0(3,1) - M*HSPS; + x0(4,1) = x0(4,1) - N*HSPS; + else % sp-sp overlap + HSSS = BondIntegral(dR,fss_sigma); + HSPS = BondIntegral(dR,fsp_sigma); + HPSS = BondIntegral(dR,fps_sigma); + HPPS = BondIntegral(dR,fpp_sigma); + HPPP = BondIntegral(dR,fpp_pi); + + PPSMPP = HPPS - HPPP; + PXPX = HPPP + L*L*PPSMPP; + PXPY = L*M*PPSMPP; + PXPZ = L*N*PPSMPP; + PYPX = M*L*PPSMPP; + PYPY = HPPP + M*M*PPSMPP; + PYPZ = M*N*PPSMPP; + PZPX = N*L*PPSMPP; + PZPY = N*M*PPSMPP; + PZPZ = HPPP + N*N*PPSMPP; + + x0(1,1) = x0(1,1) + HSSS; + x0(1,2) = x0(1,2) + L*HSPS; % or 0 + x0(1,3) = x0(1,3) + M*HSPS; % or 0 + x0(1,4) = x0(1,4) + N*HSPS; % or 0 + + x0(2,1) = x0(2,1) - L*HPSS; % or 0 + + x0(2,2) = x0(2,2) + PXPX; + x0(2,3) = x0(2,3) + PXPY; + x0(2,4) = x0(2,4) + PXPZ; + + x0(3,1) = x0(3,1) - M*HPSS; % or 0 + + x0(3,2) = x0(3,2) + PYPX; + x0(3,3) = x0(3,3) + PYPY; + x0(3,4) = x0(3,4) + PYPZ; + x0(4,1) = x0(4,1) - N*HPSS; % or 0 + x0(4,2) = x0(4,2) + PZPX; + x0(4,3) = x0(4,3) + PZPY; + x0(4,4) = x0(4,4) + PZPZ; + end + end + end + diff --git a/proxies/matlab/Thresh.m b/proxies/matlab/Thresh.m new file mode 100644 index 0000000..fd05b2d --- /dev/null +++ b/proxies/matlab/Thresh.m @@ -0,0 +1,10 @@ +function [X] = Thresh(X,eps); + +N = max(size(X)); +for i = 1:N +for j = 1:N + if abs(X(i,j)) < eps + X(i,j) = 0; + end +end +end diff --git a/proxies/matlab/nearestneighborlist.m b/proxies/matlab/nearestneighborlist.m new file mode 100644 index 0000000..97d40ce --- /dev/null +++ b/proxies/matlab/nearestneighborlist.m @@ -0,0 +1,67 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Simple N^2 brute force nearest neighborlist % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +function [nrnnlist,nndist,nnRx,nnRy,nnRz,nnType,nnStruct,nrnnStruct] = nearestneighborlist(Rx,Ry,Rz,LBox,Rcut,N) + +% Rx, Ry, Rz are the coordinates of atoms +% LBox dimensions of peridic BC +% N number of atoms +% nrnnlist(I): number of atoms within distance of Rcut from atom I including atoms in the skin +% nndist(I,J): distance between atom I(in box) and J (including atoms in the skin) +% nnRx(I,J): x-coordinte of neighbor J to I within RCut (including atoms in the skin) +% nnRy(I,J): y-coordinte of neighbor J to I within RCut (including atoms in the skin) +% nnRz(I,J): z-coordinte of neighbor J to I within RCut (including atoms in the skin) +% nnType(I,J): The neighbor J of I corresponds to some translated atom number in the box that we need to keep track of +% nnStruct(I,J): The neigbors J to I within Rcut that are all within the box (not in the skin). +% nrnnStruct(I): Number of neigbors to I within Rcut that are all within the box (not in the skin). + +Lx = LBox(1); Ly = LBox(2); Lz = LBox(3); % Dimensions of periodic BC +nx = floor(Lx/Rcut); ny = floor(Ly/Rcut); nz = floor(Lz/Rcut); % Division into # cell boxes: nx, ny, nz + +nndist = zeros(N,floor(10+4*N/((nx+2)*(ny+2)*(nz+2)))); % Allocation of memory, not optimized! +nnRx = zeros(N,floor(10+4*N/((nx+2)*(ny+2)*(nz+2)))); % Make sure the fastes allocation for Forstran is used, e.g. (N,1) instead of (1,N) or the opposite! +nnRy = zeros(N,floor(10+4*N/((nx+2)*(ny+2)*(nz+2)))); +nnRz = zeros(N,floor(10+4*N/((nx+2)*(ny+2)*(nz+2)))); +type = zeros(10*N); +nnType = zeros(N,floor(10+4*N/((nx+2)*(ny+2)*(nz+2)))); +nnStruct = zeros(N,floor(10+4*N/((nx+2)*(ny+2)*(nz+2)))); +nrnnStruct = zeros(N,1); +nrnnlist = zeros(N,1); + +% Simple N^2 brute force nearest neighborlist + for i = 1:N + cnt = 0; + tmp = zeros(N,1); + for m = 1:N + for j = -1:1 + for k = -1:1 + for l = -1:1 + Tx = Rx(m)+j*Lx; % Search all neigbors within a single translation (multiple translations could be necessary for small systems! + Ty = Ry(m)+k*Ly; + Tz = Rz(m)+l*Lz; + dist = norm([Rx(i),Ry(i),Rz(i)]-[Tx,Ty,Tz]); +% if (dist < Rcut) & (dist > 1e-12) % Neighbors within Rcut inlcuidng translated atoms in the "skin" + if (dist < Rcut) % Neighbors within Rcut inlcuidng translated atoms in the "skin" + cnt = cnt + 1; + nndist(i,cnt) = dist; + nnRx(i,cnt) = Tx; + nnRy(i,cnt) = Ty; + nnRz(i,cnt) = Tz; + nnType(i,cnt) = m; % Neigbor is number of original ordering number m in the box that might have been stranslated to the skin + tmp(m) = m; + end + end + end + end + end + nrnnlist(i) = cnt; + cnt2 = 0; + for ss = 1:N + if tmp(ss) > 0 % Includes only neighbors in the box within Rcut (without the skin) + cnt2 = cnt2 + 1; + nnStruct(i,cnt2) = ss; + end + end + nrnnStruct(i) = cnt2; + end + diff --git a/proxies/python/aosa_hamiltonian.py b/proxies/python/aosa_hamiltonian.py new file mode 100644 index 0000000..b8a8289 --- /dev/null +++ b/proxies/python/aosa_hamiltonian.py @@ -0,0 +1,130 @@ +"""AOSA and LATTE - prototype hamiltonian elements +Atomic orbital spherical approximation + - Reads the total number of atoms + - Constructs a set of random coordinates + - Constructs a simple Hamiltonian + - Computes the hamiltonian derivatives +""" + +import os +import sys + +import numpy as np +import scipy.linalg as sp +import sedacs.driver +#import sedacs.interface_modules +from sedacs.dev.io import src_path + +try: + import ctypes + + # import gpulibInterface as gpu + + gpuLib = True + arch = "nvda" + pwd = os.getcwd() + + if arch == "nvda": + print("loading nvidia...") + lib = ctypes.CDLL(str((src_path() / "gpu/nvda/libnvda.so").absolute())) + if arch == "amd": + lib = ctypes.CDLL(str((src_path() / "gpu/amd/libamd.so").absolute())) + +except: + gpuLib = False + + +__all__ = [ + "AOSA_Parameters", + "AOSA_Parameter", + "get_integral", + "get_integral_v1", +] + +class AOSA_Parameter: + def __init__(self,symbol,orb,filePath): + self.symbol = symbol + self.orbType = orb + parFile = open(filePath,"r") + count = 0 + symbFound = False + orbFound = False + for line in parFile: + info = line.split() + if(len(info) >= 1): + print(info) + if(info[0] == "Element="): + if(info[1] == symbol): + norbs = int(info[3]) + symbFound = True + print(info[1],symbol,symbFound) + if(symbFound and info[3] == orb): + print(info[5]) + orbFound = True + self.onsite = float(info[5]) + self.u = float(info[7]) + self.nl = int(info[9]) + self.kappas = np.zeros((self.nl)) + self.ds = np.zeros((self.nl,3)) + self.gammas = np.zeros((self.nl,4)) + if(symbFound and orbFound and info[0] == "LobeIndex="): + self.kappas[count] = float(info[3]) + self.ds[count,0] = float(info[5]) + self.ds[count,1] = float(info[6]) + self.ds[count,2] = float(info[7]) + + self.gammas[count,0] = float(info[9]) + self.gammas[count,1] = float(info[10]) + self.gammas[count,2] = float(info[11]) + self.gammas[count,3] = float(info[12]) + + count = count + 1 + + if(count == self.nl): + break + + + +def get_integral(coordsI,symbolI,orbI,coordsJ,symbolJ,orbJ): + + parI = AOSA_Parameters(symbolI,orbI) + parJ = AOSA_Parameters(symbolJ,orbJ) + + RIJ = coordsJ - coordsI + #Expo + inte = 0.0 + for li in range(parI.nl): + for lj in range(parJ.nl): + sn = np.sign(parI.kappas[li])*np.sign(parJ.kappas[lj]) + kappaIJ = sn*(abs(parI.kappas[li]) + abs(parJ.kappas[lj]))/2 + gammaIJ = (parI.gammas[li,0] + parI.gammas[li,0])/2 + dIJ = RIJ + parJ.ds[lj,:] - parI.ds[li,:] + #dIJ = np.dot(RIJ,parJ.ds[lj,:]) + parJ.ds[lj,:] - parI.ds[li,:] + inte = inte + kappaIJ*np.exp(gammaIJ*np.linalg.norm(dIJ)) + + sval = inte + hval = inte*(parI.onsite + parJ.onsite)/2 + + return hval, sval + + + +def get_integral_v1(coordsI,coordsJ,parI,parJ): + + RIJ = coordsJ - coordsI + #Expo + inte = 0.0 + for li in range(parI.nl): + for lj in range(parJ.nl): + sn = np.sign(parI.kappas[li])*np.sign(parJ.kappas[lj]) + kappaIJ = sn*(abs(parI.kappas[li]) + abs(parJ.kappas[lj]))/2 + gammaIJ = (parI.gammas[li,0] + parJ.gammas[lj,0])/2 + dIJ = RIJ + parJ.ds[lj,:] - parI.ds[li,:] + inte = inte + kappaIJ*np.exp(gammaIJ*np.linalg.norm(dIJ)) + + sval = inte + hval = inte*(parI.onsite + parJ.onsite)/2 + + return hval, sval + + diff --git a/proxies/python/chemical_potential.py b/proxies/python/chemical_potential.py new file mode 100644 index 0000000..4aed181 --- /dev/null +++ b/proxies/python/chemical_potential.py @@ -0,0 +1,211 @@ +"""Chemical potential. This module will handle functions +related to the computation of chemical potential or Fermi +""" + +import os +import sys + +import numpy as np +import scipy.linalg as sp +import sedacs.driver +from sedacs.dev.io import src_path +from hamiltonian_elements import * +from sedacs.file_io import read_coords_file, write_xyz_coordinates +from dnnprt import * +from proxy_global import * +from hamiltonian_random import get_random_hamiltonian +from hamiltonian_random import get_random_coordinates +from hamiltonian_random import RandomNumberGenerator + + +__all__ = [ + "get_mu", + "fermi_dirac", +] + + +## Fermi-Dirac function +# @brief Get the Fermi-Dirac distribution probabilities given a set +# of energy values +# @param mu Chemical potential +# @param energy Energy value/s +# @param etemp Electronic temperature [K] +# @param kB Boltzman constant (default is in eV/K) +# +def fermi_dirac(mu, energy, temp, kB=8.61739e-5): + ''' + Get Fermi probability distributions (values are between 0 and 1) + ''' + fermi = 1/(1 + np.exp((energy - mu)/(kB*temp))) + + return fermi + + +## Comput the chemical potential +# @brief Get the chemical potential from a set of eigenvalues and their weights +# coputed from a partial trace over a "subsytem". It first uses a Newton-Raphson (NR) +# scheme. It then applies a bisection method if NR does not converge +# @param mu0 Initial guess of mu. If set to None, it will use (HOMO+LUMO)/2. +# @param evals Eigenvalues of the system +# @param etemp Electronicn temperature +# @param nocc Number of occupied orbitals (This is typically coputed from the total +# number of electrons) +# @param dvals Weights computed from a partial trace. If set to None, weights are set to 1.0. +# @param kB Boltzman constant (default is in eV/K) +# @param verb Verbosity switch +# +def get_mu(mu0, evals, etemp, nocc, dvals=None, kB=8.61739e-5, verb=False): + + if(verb): + print('\nCalculating mu ...,') + + a = 1.0 + nmax = 30 + tol = 1.0E-10 + + HOMO = evals[int(nocc)] + LUMO = evals[int(nocc) + 1] + mu = 0.5*(LUMO + HOMO) + norbs = len(evals) + notConverged = False + if(dvals is None): + dvals = np.ones((norbs)) + for i in range(nmax+1): + fermi = fermi_dirac(mu, evals, temp) + occ = np.sum([fermi[i]*dvals[i] for i in range(norbs)]) + occErr = abs(occ - nocc) + dFermiDmu = (1/(kB*temp))*fermi*(1.0-fermi)*dvals + occ_prime = np.sum([dFermiDmu[i]*dvals[i] for i in range(norbs)]) + mu = mu + a*(nocc - occ)/occ_prime + if abs(occErr) < tol: + break + elif(abs(mu) > 1.0E10): + print('WARNING: Newton-Raphson did not converge (will try bisection) Occupation error = ', occErr) + notConverged = True + break + if verb: + print('N-R iteration (i,mu,occ,occErr)', i, mu, occ, occErr) + if(i == nmax): + print('WARNING: Newton-Raphson did not converge (will try bisection) Occupation error = ', occErr) + notConverged = True + + if(notConverged): + muMin = np.min(evals) + muMax = np.max(evals) + mu = muMin + step = abs(muMax-muMin) + Ft1 = 0.0 + Ft2 = 0.0 + prod = 0.0 + + #Sum of the occupations + fermi = fermi_dirac(mu, evals, temp) + ft1 = np.sum([fermi[i]*dvals[i] for i in range(norbs)]) + ft1 = ft1 - nocc + + for i in range(1000001): + if(i == 1000000): + print("Bisection method in gpmdcov_musearch_bisec not converging ...") + exit(0) + if(mu > muMax + 1.0 or mu < muMin - 1.0): + print("Bisection method is diverging") + print("muMin=",muMin,"muMax=",muMax) + print(evals) + exit(0) + + if(abs(ft1) < tol): #tolerance control + occErr = ft2 + break + mu = mu + step + + ft2 = 0.0 + + #New sum of the occupations + fermi = fermi_dirac(mu, evals, temp) + ft2 = np.sum([fermi[i]*dvals[i] for i in range(norbs)]) + + ft2 = ft2 - nocc + + #Product to see the change in sign. + prod = ft2*ft1 + if(prod < 0): + mu = mu - step + step = step / 2.0 #If the root is inside we shorten the step. + else: + ft1 = ft2 #If not, Ef moves forward. + if verb: + print('Bisection iteration (i,mu,occ,occErr);', i, mu, occ, ft2) + + print('Final mu, error:', mu, occErr) + + return mu + +## Estimates mu from a matrix using the Girshgorin centers +# @brief It will use the diagonal elements as an approximation +# for eigenvalues. +# @param ham Hamiltonian matrix +# @param etemp Electroninc temperature +# @param nocc Number of occupied states +# @param kB Boltzman constante (default is in units of eV/K) +# @param verb Vorbosity switch +# +def estimate_mu(ham,etemp,nocc,kB=8.61739e-5,verb=False): + diag = np.sort(np.diagonal(ham)) + if(verb): + print("Estimating the chemical potential from diagonal elements ... \n") + mu0 = 0.5*(np.max(diag) + np.min(diag)) + print("diag",diag) + print("Mu0",mu0) + mu = get_mu(mu0,diag,etemp,nocc,kB=kB,dvals=None,verb=True) + + return mu + + +if __name__ == "__main__": + + n = len(sys.argv) + + if n == 1: + print("Give the total number of elements. Example:\n") + print("proxy_a 100\n") + sys.exit(0) + else: + norbs = int(sys.argv[1]) + + verb = True + + #Build random coordinates + coords = get_random_coordinates(norbs) + + #Build random Hamiltonian (Anders' version) + ham = get_random_hamiltonian(coords) + + print("\n Hamiltonan:") + print(ham) + + nocc = 0.5*norbs + etemp = 10000 + + #Scale the diagonal elements + scalingFactor = 1.0 + for i in range(norbs): + ham[i,i] = scalingFactor*ham[i,i] + + #Estimate mu from the diagonal elements of H + muEst = estimate_mu(ham,etemp,nocc,kB=8.61739e-5) + print("\n Estimated mu:",muEst) + + #Get eigenvalues and eigenvectors + evals, evects = sp.eigh(ham) + + #Compute exact mu + mu0 = 0.0 + muReal = get_mu(mu0,evals,etemp,nocc,dvals=None,verb=True) + print("\n Exact mu:",muEst) + + print("\n Realative error of mu estimation",abs((muReal - muEst)/muReal)) + + + + + diff --git a/proxies/python/coordinates.py b/proxies/python/coordinates.py new file mode 100644 index 0000000..05a4f04 --- /dev/null +++ b/proxies/python/coordinates.py @@ -0,0 +1,58 @@ +"""coordinates +This code is only used to guide implemetations and understand which are the +basic elements needed to interface with the sedacs driver. +""" + +import os +import sys +import numpy as np +from random_numbers import RandomNumberGenerator + +__all__ = [ + "get_random_coordinates", +] + + +## Generating random coordinates +# @brief Creates a system of size "nats = Number of atoms" with coordindates having +# a random (-1,1) displacement from a simple cubic lattice with parameter 2.0 Ang. +# This funtion is only used for testing purposes. +# @param nats The total number of atoms +# @return coordinates Position for every atom. z-coordinate of atom 1 = coords[0,2] +# +def get_random_coordinates(nats): + """Get random coordinates""" + length = int(nats ** (1 / 3)) + 1 + coords = np.zeros((nats, 3)) + latticeParam = 2.0 + atomsCounter = -1 + myrand = RandomNumberGenerator(111) + for i in range(length): + for j in range(length): + for k in range(length): + atomsCounter = atomsCounter + 1 + if atomsCounter >= nats: + break + rnd = myrand.generate(-1.0, 1.0) + coords[atomsCounter, 0] = i * latticeParam + rnd + rnd = myrand.generate(-1.0, 1.0) + coords[atomsCounter, 1] = j * latticeParam + rnd + rnd = myrand.generate(-1.0, 1.0) + coords[atomsCounter, 2] = k * latticeParam + rnd + return coords + + +if __name__ == "__main__": + n = len(sys.argv) + if n == 1: + print("Give the total number of atoms. Example:\n") + print("python coordinates.py 100\n") + sys.exit(0) + else: + nats = int(sys.argv[1]) + + verb = True + + coords = get_random_coordinates(nats) + + print("Coordinates:",coords) diff --git a/proxies/python/density_matrix.py b/proxies/python/density_matrix.py new file mode 100644 index 0000000..13b1bcf --- /dev/null +++ b/proxies/python/density_matrix.py @@ -0,0 +1,309 @@ +"""density_matrix +Computes the Density matrix from a given Hamiltonian +This code is only used to guide implemetations and understand which are the +basic elements needed to interface with the sedacs driver. +""" + +import os +import sys + +import numpy as np +import scipy.linalg as sp +from hamiltonian_elements import * +from dnnprt import * +from proxy_global import * +from coordinates import get_random_coordinates +from hamiltonian_random import get_random_hamiltonian +from hamiltonian import get_hamiltonian_proxy +from chemical_potential import fermi_dirac, get_mu +from nonortho import get_xmat +import gpuLibInterface as gpu +from init_proxy import init_proxy_accelerators +from proxy_global import bring_ham_list, bring_dm_list, bring_cublas_handle_list, bring_stream_list + +try: + import ctypes + + + gpuLib = True + arch = "nvda" + pwd = os.getcwd() + + if arch == "nvda": + print("loading nvidia...") + lib = ctypes.CDLL("/home/finkeljo/sedacs-gpmdsp2/src/sedacs/gpu/nvda/libnvda.so") + if arch == "amd": + lib = ctypes.CDLL(str((src_path() / "gpu/amd/libamd.so").absolute())) + +except: + gpuLib = False + +import ctypes + + + +__all__ = [ + "get_density_matrix_proxy", + "get_density_matrix_gpu", +] + + +## Computes the Density matrix from a given Hamiltonian. +# @author Anders Niklasson +# @brief This will create a Density matrix \f$ \rho \f$ +# \f[ \rho = \sum^{nocc} v_k v_k^T \f] +# where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ +# +# @param ham Hamiltonian matrix +# @param nocc Number of occupied orbitals +# @param core_size Number of atoms in the cores. +# @param method Type of algorithm used to compute DM +# @param accel Type of accelerator/special device used to compute DM. Default is No and +# will only use numpy. +# @param mu Chemical potential. If set to none, the calculation will use nocc +# @param etemp Electronic temperature +# @param overlap Overlap matrix +# @param verb Verbosity. If True is passed, information is printed. +# +# @return rho Density matrix +# +def get_density_matrix_proxy(ham, nocc, norbsInCore=None, method="Diag", accel="No", mu=None, etemp=0.0, overlap=None, full_data=False, verb=False, lib=None): + """Calcualtion of the full density matrix from H""" + if verb: + print("Computing the Density matrix") + + norbs = len(ham[:, 0]) + ham_orth = np.zeros((norbs, norbs)) + if overlap is not None: + # Get the inverse overlap factor + zmat = get_xmat(overlap, method="Diag", accel="No", verb=False) + + # Orthogonalize Hamiltonian + ham_orth = np.matmul(np.matmul(np.transpose(zmat), ham), zmat) + else: + ham_orth[:, :] = ham[:, :] + + if method == "Diag" and accel == "No": + evals, evects = sp.eigh(ham_orth) + print("evals",evals) + homoIndex = nocc - 1 + lumoIndex = nocc + + #If mu is not set we set mu HOMO+LUMO/2 + if (mu is None): + mu = 0.5 * (evals[homoIndex] + evals[lumoIndex]) + else: + pass + + if verb: + print("Chemical potential = ", mu) + + rho = np.zeros((norbs, norbs)) + if verb: + print("Eigenvalues of H:", evals) + + #If the electronic temperature is 0 + if(etemp < 1.0E-10): + for i in range(norbs): + if evals[i] < mu: + rho = rho + np.outer(evects[:, i], evects[:, i]) + else: + #mu = get_mu(mu, evals, etemp, nocc, dvals=None, kB=8.61739e-5, verb=False) + fvals = np.zeros((norbs)) + fvals = fermi_dirac(mu, evals, etemp, kB=8.61739e-5) + for i in range(norbs): + if evals[i] < mu: + rho = rho + fvals[i]*np.outer(evects[:, i], evects[:, i]) + + elif method == "SP2" and accel == "No": + #rho = dnnprt(ham_orth, norbs, nocc, H1=None, refi=False) + #rho = movingmu_sp2(ham,mu=mu,thresh=0.0,miniter=5,maxiter=50,sp2conv=1.0E-6,idemtol=1.0E-6,verb=True) + #rho = golden_sp2(ham,mu=mu,thresh=0.0,miniter=5,maxiter=50,sp2conv=1.0E-6,idemtol=1.0E-6,verb=True) + rho = sp2_basic(ham,nocc,thresh=0.0,minsp2iter=5,maxsp2iter=30,sp2conv=1.0E-5,idemtol=1.0E-5,verb=True) + + elif method == "SP2" and accel == "TC": + + accel_lib = bring_accel_lib() + + #print("--------set stream in python--------------") + #stream=gpu.set_stream(accel_lib); + #print(id(stream),stream) + + + + #print("\n") + #print("--------init cublas handle in python--------------") + #cublas_handle = gpu.cublasInit(accel_lib) + #print(id(cublas_handle),cublas_handle) + + cublas_handle_list=bring_cublas_handle_list() + streams_list = bring_stream_list() + dev_list = bring_dev_list() + d_ham = dev_list[0] + d_dm = dev_list[1] + + test_handle = cublas_handle_list[0] + test_stream = streams_list[0] + + # determine size + size_of_double = 8 #bytes + matSize = norbs * norbs * size_of_double + + size_of_float = 4 #bytes + matSize_f = norbs * norbs * size_of_float + + pinned_ham = dev_list[10] + pinned_dm = dev_list[11] + #gpu.memcpyHtoH(pinned_ham, ham, matSize, accel_lib) + #gpu.memcpyHtoD(d_ham, pinned_ham, matSize, accel_lib) + gpu.memcpyHtoD(d_ham, ham, matSize, accel_lib) + #e,v = np.linalg.eigh(ham) + #print(e) + rho=np.empty((norbs,norbs)) + print("device is = ", gpu.get_device(accel_lib)) + #ham = d_ham_list[0] + #dm = d_dm_list[0] + + + gpu.dmDNNSP2(dev_list,norbs,nocc,test_handle,test_stream,accel_lib) + + #gpu.dmGoldenSP2(d_ham_list[0],d_dm_list[0],norbs,mu,cublas_handle,accel_lib) + gpu.memcpyDtoH(rho, d_dm, matSize, accel_lib) + #gpu.memcpyDtoH(pinned_dm, d_dm_list[0], matSize, accel_lib) + #gpu.memcpyDtoH(pinned_dm, d_dm, matSize, accel_lib) + #gpu.memcpyHpinnedtoH(rho, pinned_dm, matSize, accel_lib) + #e1,v1 = np.linalg.eigh(rho) + + #gpu.dmMovingMuSP2(d_ham_list[0],d_dm_list[0],norbs,mu,cublas_handle,accel_lib) + #gpu.memcpyDtoH(rho, d_dm_list[0], matSize, accel_lib) + #e2,v2 = np.linalg.eigh(rho) + #for i in range(0,norbs): + # print(e1[i],e2[i]) + #exit() + #rho = sp2_basic(ham,nocc,thresh=0.0,minsp2iter=5,maxsp2iter=30,sp2conv=1.0E-5,idemtol=1.0E-5,verb=True) + + elif method == "SP2" and accel == "PBML": + print("No method yet") + else: + print("The combination of method and accelerator is unknown") + exit(0) + + if(overlap is not None): + rho = np.matmul(np.matmul(zmat,rho),np.transpose(zmat)) + + print(norbs) + dvals = np.zeros((norbs)) + if(method == "Diag"): + if (overlap is not None): + overTimesEvects = np.dot(overlap,evects) + else: + overTimesEvects = evects + for i in range(norbs): + #dvals = np.append(dvals, np.inner(evects[:norbsInCore,i],overTimesEvects[:norbsInCore,i])) + dvals[i] = np.inner(evects[:norbsInCore,i],overTimesEvects[:norbsInCore,i]) + else: + if(norbsInCore is not None): + dvals[:] = norbsInCore/norbs + else: + dvals[:] = 1.0 + + evals = np.zeros(norbs) + evals = np.diag(ham_orth) #We estimate the eigenvaluse from the Girshgorin centers + + + #print("Ham\n",ham_orth) + #print("Mu",mu) + #print("DM\n") + diagonal = np.diag(rho) + #print("tr",np.trace(rho)) + #print("NOCC",nocc,norbs) + #for i in range(norbs): + # print(diagonal[i]) + + evals, evects = sp.eigh(rho) + if(full_data): + return rho, evals, dvals + else: + return rho + + + +## Computes the Density matrix from a given Hamiltonian. +# @author Josh Finkelstein +# @brief This will create a "zero-temperature" Density matrix \f$ \rho \f$ +# \f[ \rho = \sum^{nocc} v_k v_k^T \f] +# where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ +# using GPU/AI accelerator library +# +# @param H Hamiltonian matrix +# @param Nocc Number of occupied orbitals +# @param verb Verbosity. If True is passed, information is printed. +# +# @return D Density matrix +# +def get_density_matrix_gpu(H, N, Nocc, lib, verb=False): + """Calcualted the full density matrix from H""" + if verb: + print("Computing the Density matrix using GPU/AI accel library") + + # init DM + D = np.zeros((N, N)) + kbt = 0.1 + + # get DM from cusolver diag + #dm = gpu.dmDNNSP2(H,D,N,Nocc,lib) + # dm = gpu.dmCheby(H,D,N,Nocc,kbt,lib) + print("Density matrix=", D) + # dm = gpu.dmDiag(H,D,N,Nocc,kbt,lib) + # print("Density matrix=",dm) + #dm = gpu.dmMLSP2(H, D, N, Nocc, lib) + return D + + +if __name__ == "__main__": + n = len(sys.argv) + if n == 1: + print("Give the name of the algorithm and the total number of atoms. Example:\n") + print("density_matrix get_density_matrix_proxy 100\n") + sys.exit(0) + else: + algo = str(sys.argv[1]) + nats = int(sys.argv[2]) + + verb = True + coords = get_random_coordinates(nats) + atomTypes = np.zeros((nats),dtype=int) + symbols = []*nats + symbols[:] = "H" + + filename = "aosa_parameters.dat" + bas_per_atom = [1] + tbparams = read_tbparams(filename, symbols, bas_per_atom) + + nvtx.push_range("get hamiltonian proxy",color="blue", domain="get proxy h") + ham, over = get_hamiltonian_proxy(coords, atomTypes, symbols, get_overlap=True) + nvtx.pop_range(domain="get proxy h") + if (gpuLib == True): + ## + size_of_double = 8 # bytes + matSize = nats * nats * size_of_double + # cublas_handle = gpu.cublasInit(lib) + + #if (eng.accel == "TC"): + init_proxy_accelerators(1,4096) + + ## async copy of ham from host to device + gpu.memcpyHtoD(dev_list[0], ham, matSize, lib) + + + + + + if(algo == "get_density_matrix_proxy"): + occ = int(float(nats) / 2.0) + rho1 = get_density_matrix_proxy(ham, occ, method="SP2") + print(lib) + rho2 = get_density_matrix_proxy(ham, occ, method="SP2", accel="TC",d_ham=d_ham,d_dm=d_dm,lib=lib) + print("Density matrix=", rho1) + print("Density matrix=", rho2) + diff --git a/proxies/python/dnnprt.py b/proxies/python/dnnprt.py new file mode 100644 index 0000000..ae8d554 --- /dev/null +++ b/proxies/python/dnnprt.py @@ -0,0 +1,279 @@ +#!/usr/bin/env python +import numpy as np +import os, sys, argparse, time + + +def gershgorin(M): + # find eigenvalue estimates of the matrix M from the Gershgorin circle theorem + min_e = 0 + max_e = 0 + + for i in range(0, np.shape(M)[0]): + e = M[i, i] # Gershgorin eigenvalue circle center + r = 0 + + for j in range(0, np.shape(M)[0]): # compute sum of abs. val of components in row i + r += np.abs(M[i, j]) + + r -= np.abs(e) # Gershgorin eigenvalue circle radius + + # update min and max eigenvalues as you loop over rows + if e - r < min_e: + min_e = e - r + elif e + r > max_e: + max_e = e + r + + return (min_e, max_e) + + +def dual_half(S): + # Calculation of X^2 as defined in equation (15). Note that precision in numpy is closed under alegbraic operations when of the same data type and inherits the precision of the highest precision operand when not of the same data type. + S0 = np.half(S) + S1 = np.single(np.half(S - S0)) + S0S0 = np.single(np.matmul(S0, S0)) + S0S1 = np.matmul(S0, S1) + X = S0S0 + (S0S1 + np.transpose(S0S1)) + return X + +##SP2 method. +# @param h_bml Input Hamiltonian matrix +# @param rho_bml Output density matrix +# @param threshold Threshold for sparse matrix algebra +# @param bndfil Bond +# @param minsp2iter Minimum sp2 iterations +# @param maxsp2iter Maximum SP2 iterations +# @param sp2conv Convergence type +# @param idemtol Idempotency tolerance +# @param verbose A verbosity level +def sp2_basic(ham,occ,thresh=0.0,minsp2iter=5,maxsp2iter=30,sp2conv=1.0E-5,idemtol=1.0E-5,verb=False): + + hdim = len(ham[:,0]) + + # Normalize + emin, emax = gershgorin(ham) + rho = np.zeros((hdim,hdim)) + rho[:,:] = ham[:,:] + ident = np.diag(np.ones(hdim)) + rho[:,:] = (emax * ident[:,:] - ham[:,:]) / (emax - emin) + + # X2 <- X + for i in range(maxsp2iter): + + trx = np.trace(rho) + + #X2 <- X * X + X2 = np.dot(rho, rho) + + trx2 = np.trace(X2) + + #Trace reduction + if(verb): print("sp2iter", iter, occ, trx, abs(occ-trx)) + + if(trx - occ <= 0.0): + + #X <- 2 * X - X2 + rho = 2*rho - X2 + + trx = 2.0 * trx - trx2 + + else: + + #X <- X2 + rho[:,:] = X2[:,:] + + trx = trx2 + + + if(abs(occ-trx) < idemtol and i > minsp2iter): + break + + if(iter == maxsp2iter): + print("sp2 purification is not converging: stop!") + raise 1 + + + #rho = 2.0 * rho + + print("Rho inside",rho) + return rho + + + +#### DEEP-NN FORMULATION OF THE RECURSIVE SP2 FERMI-OPERATOR EXPANSION SCHEME +def dnnprt(H0, N, Nocc, H1=None, refi=False): + """ + Compute density matrix and first order response to perturbation, H1, in the + Hamiltonian, H0. Implementation mimics mixed precision solver. + + Inputs: + ------ + + H0: Hamiltonian matrix + H1: Perturbation to H0 + N: Matrix size + Nocc: Occupation number + dm_only: Compute density matrix only (True/False) + refi: Compute fp64 refinement (True/False) + + """ + np.set_printoptions(precision=15) + + dm_only = True + if H1 is not None: + dm_only = False + + #### INITIALIZE + eps = 1e-16 # Small value, but such that +/- eps is finite in single precision + Csp2 = 4.5 # Convergence criterion as derived by Emanuel + sgn = 0 # Initial value of sgn + I = np.eye(N) # Identity matrix + maxlayer = 100 # Maximum number of layers + v_sgn = np.zeros(maxlayer) # Keeps track of binary in-place learning choices + idemp_err = np.zeros(maxlayer) # Local error estimate + if dm_only == False: + idemp_err_1 = np.zeros(maxlayer) # Local error estimate + + #### CHOSE POST-PROCESSING ACTIVATION FUNCTION REFINEMENT OR NOT + Refinement = True # Or False + + #### LOAD HAMILTONIAN AS INPUT LAYER + X0 = H0 # Initial input layer + if not dm_only: + X1 = H1 + + #### 'EXACT' SOLUTION FOR COMPARISION ONLY + # e, v = np.linalg.eig(H0 + H1) # Diagonlize H as a brute force comparision + # e = np.sort(e) # Sort eigenvalues in increasing order + # E0 = np.sum(e[0:Nocc]) # Sum over the lowest Nocc states using absurd indexing + + #### INITIAL IN-PLACE LEARNING FOR FIRST LAYER + (hN, h1) = gershgorin(X0) # Alternatively, obtain eigenvalue estimates using Gersgorin circle theorem + W0 = -1 / (hN - h1) # Weight (scalar) + B0 = (hN / (hN - h1)) * I # Bias (diagonal matrix) + + #### INITIAL LINEAR TRANSFORM + S0 = W0 * X0 + B0 + S0 = np.single(S0) # Store in single precision + TrS0 = np.trace(S0) # Keep track of occupation + + if dm_only == False: + S1 = W0 * X1 + S1 = np.single(S1) # Store in single precision + TrS1 = np.trace(S1) # Keep track of occupation + + start = time.time() + #### COMPUTATIONAL DEEP LAYERS + for layer in range(maxlayer): + """ SP2 """ + #### ACTIVATION FUNCTION FROM TWO DUAL HALF-PRECISION MATRIX-MATRIX MULTIPLICATIONS + X0_h = np.single( + np.half(S0) + ) # First half-precision repsentation of X, single used to allow single accumulation + X0_l = np.single( + np.half(S0 - X0_h) + ) # Second half-precision repsentation of X, single used to allow single accumulation + X0_hh = np.single(np.matmul(X0_h, X0_h)) # Half-precision multiplication with single accumulation + X0_hl = np.single(np.matmul(X0_h, X0_l)) # Half-precision multiplication with single accumulation + X0_lh = np.transpose(X0_hl) # Use the matrix symmetry of X0 and X1 from the symmetry of S + X0 = np.single(X0_hh + X0_hl + X0_lh) # Additions in single precision + TrX0 = np.trace(X0) # Approximate occupation + print("TrX0",TrX0) + """""" """""" + + """ response """ + if dm_only == False: + #### ACTIVATION FUNCTION FROM TWO DUAL HALF-PRECISION MATRIX-MATRIX MULTIPLICATIONS + X1_h = np.single( + np.half(S1) + ) # First half-precision repsentation of X, single used to allow single accumulation + X1_l = np.single( + np.half(S1 - X1_h) + ) # Second half-precision repsentation of X, single used to allow single accumulation + X0X1_hh = np.single(np.matmul(X0_h, X1_h)) # Half-precision multiplication with single accumulation + X0X1_hl = np.single(np.matmul(X1_h, X0_l)) # Half-precision multiplication with single accumulation + X0X1_lh = np.single(np.matmul(X1_h, X0_l)) # Use the matrix symmetry of X0 and X1 from the symmetry of S + X0X1 = np.single(X0X1_hh + X0X1_hl + X0X1_lh) # Additions in single precision + X1X0 = np.transpose(X0X1) + X1 = np.single(X0X1 + X1X0) + TrX1 = np.trace(X1) # Approximate occupation + """""" """""" + + #### ERROR ESTIMATE OF IDEMPOTENCY + idemp_err[layer] = TrS0 - TrX0 # Error estimate for in-place learning and convergence control + + if dm_only == False: + idemp_err_1[layer] = TrS1 - TrX1 # Error estimate for in-place learning and convergence control + print( + layer, "Idemp error estimate:" + str(idemp_err_1[layer]) + ) # Can reach 0 exactely in low precision arithmetics + + #### LEARNING THROUGH A BINARY ON-THE-FLY IN-PLACE ERROR MINIMIZATION, WHERE sgn = (+/-)*1 + sgn = np.sign(np.abs(2 * TrS0 - TrX0 - Nocc) - np.abs(TrX0 - Nocc) - sgn * eps) + v_sgn[layer] = sgn # Vector with the sgn to keep track + W = sgn # Weight function + B = (1 - sgn) * S0 # Bias function + + #### LINEAR TRANSFORM + S0 = W * X0 + B # Affine linear transform, apply weight and bias + if dm_only == False: + S1 = W * X1 + (1 - W) * S1 # Affine linear transform, apply weight and bias + + #### KEEP TRACK OF THE NEW OCCUPATION + TrS0 = W * TrX0 + (1 - sgn) * TrS0 # Update trace + if dm_only == False: + TrS1 = W * TrX1 + (1 - sgn) * TrS1 # Update trace + + #### CONVERGENCE TEST + if idemp_err[layer] <= 0: + break + if ( + layer > 1 + and v_sgn[layer - 1] != v_sgn[layer - 2] + and idemp_err[layer] >= Csp2 * idemp_err[layer - 2] * idemp_err[layer - 2] + ): + break + + #### POST-PROCESSING REFINEMENT STEP + if refi == True: + #### WITH ACTIVATION FUNCTION REFINEMENT, f(X) = 2*X^2 - X^4, IN DOUBLE PRECISION + X = np.double(S) + X = 2 * X - np.matmul(X, X) + TrS = np.trace(X) + X = np.double(np.matmul(X, X)) + TrX = np.trace(X) + idemp_err[layer + 1] = TrS - TrX + print(layer + 1, "Refined error estimate = " + str(idemp_err[layer + 1])) + num_deep_layers = layer + 1 # +1 to account for the last refinement layer + D = X # Output layer estimate of density matrix + else: + #### WITHOUT ACTIVATION FUNCTION REFINEMENT, f(X) = X # Or, alternativley use half-precision multiplications + num_deep_layers = layer + D0 = np.double(S0) # Output layer estimate of density matrix D + if dm_only == False: + D1 = np.double(S1) # Output layer estimate of density matrix D + + end = time.time() + flops = 2 * N * N * N * num_deep_layers / (end - start) + print(str(end - start) + " sec") + print("FLOPS = " + str(flops / 1e12) + " teraflops") + + #### DOUBLE PRECISION ERROR ESTIMATES OF THE CONVERGED DENSITY MATRIX D + occ_err = np.abs(np.trace(D0) - Nocc) # Occupation Error + D02 = np.matmul(D0, D0) # Matrix square (for error analysis only!) + idem_err = np.abs(np.trace(D02) - np.trace(D0)) # Error estimate, Tr(X2-X) + idem_err_2_norm = np.linalg.norm(D02 - D0) # Idempotency Error in 2-norm + comm_err = np.linalg.norm(np.matmul(D0, H0) - np.matmul(H0, D0)) # Commutation error + energy = np.trace(-np.matmul(D0, H0)) # Band-energy + # energy_err = np.abs(energy - E0) # Band-energy error + + if not dm_only: + energy_1 = np.trace(np.matmul(D0, H1)) + energy_2 = 0.5 * np.trace(np.matmul(D1, H1)) + else: + energy_1 = None + energy_2 = None + + if dm_only: + return D0 + else: + return D0, D1 diff --git a/proxies/python/energy_and_forces.py b/proxies/python/energy_and_forces.py new file mode 100644 index 0000000..c9bd205 --- /dev/null +++ b/proxies/python/energy_and_forces.py @@ -0,0 +1,664 @@ +"""proxy code a +A prototype engine code that: + - Computes TB + coulombic forces + - Coputes band and coulombic energies +This code is only used to guide implemetations and understand which are the +basic elements needed to interface with the sedacs driver. +""" + +import os +import sys + +import numpy as np +import scipy.linalg as sp +import sedacs.driver +from sedacs.dev.io import src_path +from proxies.python.hamiltonian_elements import * +from sedacs.file_io import read_coords_file, write_xyz_coordinates +from proxies.python.dnnprt import * +from proxies.python.proxy_global import * + +__all__ = [ + "get_random_coordinates", + "get_hamiltonian_proxy", + "get_density_matrix_proxy", + "get_density_matrix_gpu", + "get_charges_proxy", + "get_tb_forces_proxy", + "get_ppot_energy_expo_proxy", + "init_proxy_proxy", + "get_ppot_forces_expo_proxy", + "build_coul_ham_proxy", +] + + +## Simple random number generator +# This is important in order to compare across codes +# written in different languages. +# +# To initialize: +# \verbatim +# myRand = rand(123) +# \endverbatim +# where the argument of rand is the seed. +# +# To get a random number between "low" and "high": +# \verbatim +# rnd = myRand.get_rand(low,high) +# \endverbatim +# +class RandomNumberGenerator: + """To generate random numbers.""" + + def __init__(self, seed): + self.a = 321 + self.b = 231 + self.c = 13 + self.seed = seed + self.status = seed * 1000 + + def generate(self, low, high): + """Get a random real number in between low and high.""" + w = high - low + place = self.a * self.status + place = int(place / self.b) + rand = (place % self.c) / self.c + place = int(rand * 1000000) + self.status = place + rand = low + w * rand + + return rand + + +## Generating random coordinates +# @brief Creates a system of size "nats = Number of atoms" with coordindates having +# a random (-1,1) displacement from a simple cubic lattice with parameter 2.0 Ang. +# This funtion is only used for testing purposes. +# @param nats The total number of atoms +# @return coordinates Position for every atom. z-coordinate of atom 1 = coords[0,2] +# +def get_random_coordinates(nats): + """Get random coordinates""" + length = int(nats ** (1 / 3)) + 1 + coords = np.zeros((nats, 3)) + latticeParam = 2.0 + atomsCounter = -1 + myrand = RandomNumberGenerator(111) + for i in range(length): + for j in range(length): + for k in range(length): + atomsCounter = atomsCounter + 1 + if atomsCounter >= nats: + break + rnd = myrand.generate(-1.0, 1.0) + coords[atomsCounter, 0] = i * latticeParam + rnd + rnd = myrand.generate(-1.0, 1.0) + coords[atomsCounter, 1] = j * latticeParam + rnd + rnd = myrand.generate(-1.0, 1.0) + coords[atomsCounter, 2] = k * latticeParam + rnd + return coords + +## Initialize proxy code +# @brief We will read all the parameters needed for the +# guest or proxy code to run. Every guest code will need to +# set up an initialization function and save parameters that +# need to be read from file only once. Bond integral parameter, +# pair potential, etc. will be stored in memory by the guest code. +# +def init_proxy_proxy(symbols,bas_per_atom): + #Some codes will have their own input file + #read_proxy_input_file() + #Read pair potentials + read_ppots("ppots.dat",symbols) + print_ppots() + #Read tb parameters + filename = "aosa_parameters.dat" + read_tbparams(filename, symbols, bas_per_atom) + + +## Computes a Hamiltonian based on exponential decay of orbital couplings. +# @author Anders Niklasson +# @brief Computes a hamiltonian based on exponential decays. +# @param coords Position for every atoms. z-coordinate of atom 1 = coords[0,2] +# @param atomTypes Index type for each atom in the system. Type for first atom = type[0] (not used yet) +# @param symbols Symbols for every atom type +# @param verb Verbosity. If True is passed, information is printed +# @para get_overlap If overlap needs to be returned +# @return ham 2D array of Hamiltonian elements +# +def get_hamiltonian_proxy(coords, atomTypes, symbols, verb=False, get_overlap=False): + """Constructs a simple tight-binding Hamiltonian""" + + # Internal periodic table for the code + symbols_internal = np.array(["Bl", "H", "C", "N", "O", "P"], dtype=str) + numel_internal = np.zeros(len(symbols_internal), dtype=int) + numel_internal[:] = 0, 1, 4, 5, 6, 5 + bas_per_atom = np.zeros(len(symbols_internal), dtype=int) + bas_per_atom[:] = 0, 1, 4, 4, 4, 4 + spOrbTypes = ["s", "px", "py", "pz"] + sOrbTypes = ["s"] + + nats = len(coords[:, 0]) + + # Map symbols to indices in symbols_internal + symbol_to_index = {symbol: idx for idx, symbol in enumerate(symbols_internal)} + + # Translate `symbols` to `symbols_internal` indices + mapped_indices = np.array([symbol_to_index[symbol] for symbol in symbols]) + + # Convert atomTypes to `symbols_internal` indices + atom_internal_indices = mapped_indices[atomTypes] + + + # Sum the corresponding values in bas_per_atom and numel_internal + norbs = np.sum(bas_per_atom[atom_internal_indices]) + numel = np.sum(numel_internal[atom_internal_indices]) + + ham = np.zeros((norbs, norbs)) + if get_overlap: + over = np.zeros((norbs, norbs)) + if verb: + print("Constructing a simple Hamiltonian for the full system") + + colsh = 0 + rowsh = 0 + tbparams = bring_tbparams() + for i in range(0, nats): + for ii in range(bas_per_atom[atom_internal_indices[i]]): + colsh = rowsh + parI = tbparams[atomTypes[i]][ii] + for j in range(i, nats): + if i == j: + llimit = ii + else: + llimit = 0 + for jj in range(llimit,bas_per_atom[atom_internal_indices[j]]): + parJ = tbparams[atomTypes[j]][jj] + hval, sval = get_integral_v1(coords[i],coords[j],parI,parJ) + if(get_overlap): + over[rowsh,colsh] = sval + over[colsh,rowsh] = sval + + ham[rowsh, colsh] = hval + ham[colsh, rowsh] = hval + colsh = colsh + 1 + rowsh = rowsh + 1 + + if get_overlap: + return ham, over + else: + return ham + + +sedacs.driver.get_hamiltonian = get_hamiltonian_proxy + + +## Estimates mu from a matrix using the Girshgorin centers +# @brief It will use the diegonal elements as an approximation +# for eigenvalues. +def estimate_mu(ham,elec_temp,kb): + + diag = ham.np.diagonal(ham) + + +## Add coulombic potentials to the Hamiltonian +# @param ham0 No-SCF Hamiltonian +# @param vcouls Coulombic potentials for every atomic site +# @pparam orbital_based If set to True, coulombic potentials for every orbitals will be +# expected. +# @param hindex will give the orbital index for each atom +# The orbital indices for orbital i goes from `hindex[i]` to `hindex[i+1]-1` +# @param overlap Overlap matrix for nonorthogonal formulations. +# @param verb Verbosity switch. +# +def build_coul_ham_proxy(ham0, vcouls, types, charges, orbital_based, hindex, overlap=None, verb=False): + norbs = len(ham0[:, 0]) + vcouls_orbs = np.zeros((norbs), dtype=float) # Expanded coulombic potentials + nats = len(hindex[:]) - 1 + + tbparams = bring_tbparams() + + if orbital_based: + error_at("build_coul_ham", "Orbital-based coulombic potential not implemented") + else: + for i in range(nats): + for ii in range(hindex[i], hindex[i + 1]): + k = ii - hindex[i] + vcouls_orbs[ii] = vcouls[i] + tbparams[types[i]][k].u * charges[i] + if overlap is None: + ham = ham0 + np.diag(vcouls_orbs) + else: + vmat = np.diag(vcouls_orbs) + ham = ham0 + 0.5 * (np.dot(overlap, vmat) + np.dot(vmat, overlap)) + return ham + + +sedacs.driver.build_coul_ham = build_coul_ham_proxy + + +## Computes the Density matrix from a given Hamiltonian. +# @author Anders Niklasson +# @brief This will create a Density matrix \f$ \rho \f$ +# \f[ \rho = \sum^{nocc} v_k v_k^T \f] +# where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ +# +# @param ham Hamiltonian matrix +# @param nocc Number of occupied orbitals +# @param method Type of algorithm used to compute DM +# @param accel Type of accelerator/special device used to compute DM. Default is No and +# will only use numpy. +# @param mu Chemical potential. If set to none, the calculation will use nocc +# @param elect_temp Electronic temperature +# @param overlap Overlap matrix +# @param verb Verbosity. If True is passed, information is printed. +# +# @return rho Density matrix +# +def get_density_matrix_proxy(ham, nocc, method="Diag", accel="No", mu=None, elect_temp=0.0, overlap=None, verb=False): + """Calcualtion of the full density matrix from H""" + if verb: + print("Computing the Density matrix") + + norbs = len(ham[:, 0]) + ham_orth = np.zeros((norbs, norbs)) + if overlap is not None: + # Get the inverse overlap factor + zmat = get_xmat(overlap, method="Diag", accel="No", verbose=False) + + # Orthogonalize Hamiltonian + ham_orth = np.matmul(np.matmul(np.transpose(zmat), ham), zmat) + else: + ham_orth[:, :] = ham[:, :] + + if method == "Diag" and accel == "No": + evals, evects = sp.eigh(ham_orth) + homoIndex = nocc - 1 + lumoIndex = nocc + mu = 0.5 * (evals[homoIndex] + evals[lumoIndex]) + rho = np.zeros((norbs, norbs)) + if verb: + print("Eigenvalues of H:", evals) + for i in range(norbs): + if evals[i] < mu: + rho = rho + np.outer(evects[:, i], evects[:, i]) + if verb: + print("Chemical potential = ", mu) + elif method == "SP2" and accel == "No": + rho = dnnprt(ham_orth, norbs, nocc, H1=None, refi=False) + print("No method yet") + elif method == "SP2" and accel == "PBML": + print("No method yet") + else: + print("The combination of method and accelerator is unknown") + exit(0) + + if(overlap is not None): + rho = np.matmul(np.matmul(zmat,rho),np.transpose(zmat)) + + return rho + + +sedacs.driver.get_density_matrix = get_density_matrix_proxy + + +## Computes the finite temperature density matrix (DRAFT) +# @todo Write this routine. +def get_density_matrix_T(H, Nocc, Tel, mu0, coreSize, core_ham_dim, S=None, verb=False): + kB = 8.61739e-5 # eV/K, kB = 6.33366256e-6 Ry/K, kB = 3.166811429e-6 Ha/K, #kB = 3.166811429e-6 #Ha/K + if verb: + print("Computing the renormalized Density matrix") + + if S is not None: + E_val, Q = scipy.linalg.eigh(H) ### need S? not ones with S $$$ + else: + E_val, Q = np.linalg.eigh(H) + N = len(H[:, 0]) + + # print('Q\n', Q[:,0]) + + homoIndex = Nocc - 1 + lumoIndex = Nocc + print("HOMO, LUMO:", E_val[homoIndex], E_val[lumoIndex]) + mu_test = 0.5 * (E_val[homoIndex] + E_val[lumoIndex]) # don't need it + print( + N, + Nocc, + ) + print("!!!! mu test:\n", mu_test) + + # use mu0 as a guess + + OccErr = 1.0 + beta = 1.0 / (kB * Tel) + f = np.array([]) + for i in range(N): + f_i = 1 / (np.exp(beta * (E_val[i] - mu0)) + 1) # save fi to f + f = np.append(f, f_i) + # Occ = Occ + f_i*E_occ[i,k] + + D = sum(np.outer(Q[:, i], Q[:, i] * f[i]) for i in range(Nocc)) * 2 + # np.savetxt('co2_32_dm.txt',D) + + # rho = Q@f_vector@Q.T + # or + # rho_ij = SUM_k Q_ik * f_kk * Q_jk + + print("core_ham_dim", core_ham_dim) + dVals = np.array([]) + for i in range(N): + dVals = np.append(dVals, np.inner(Q[:core_ham_dim, i], Q[:core_ham_dim, i])) + + return D, E_val, dVals + + +## Computes the Density matrix from a given Hamiltonian. +# @author Josh Finkelstein +# @brief This will create a "zero-temperature" Density matrix \f$ \rho \f$ +# \f[ \rho = \sum^{nocc} v_k v_k^T \f] +# where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ +# using GPU/AI accelerator library +# +# @param H Hamiltonian matrix +# @param Nocc Number of occupied orbitals +# @param verb Verbosity. If True is passed, information is printed. +# +# @return D Density matrix +# +def get_density_matrix_gpu(H, N, Nocc, lib, verb=False): + """Calcualted the full density matrix from H""" + if verb: + print("Computing the Density matrix using GPU/AI accel library") + + # init DM + D = np.zeros((N, N)) + kbt = 0.1 + + # get DM from cusolver diag + # dm = gpu.dmDNNSP2(H,D,N,Nocc,lib) + # dm = gpu.dmCheby(H,D,N,Nocc,kbt,lib) + print("Density matrix=", D) + # dm = gpu.dmDiag(H,D,N,Nocc,kbt,lib) + # print("Density matrix=",dm) + dm = gpu.dmMLSP2(H, D, N, Nocc, lib) + return D + +## Inverse overlap factorization +# @brief Constructs inverse overlap factors given the overlap matrix +# @param over Overlap matrix +# @param method If a particular needs to be used +# @param accel If an accelerater (hardwar/library/programing model) is used. +# @verb Verbosity switch +## +def get_xmat(over,method="Diag",accel="No",verb=False): + + if(verbose): + print("In get_xmat ...") + + hdim = len(over[0,:]) + if(method == "Diag" and accel == "No"): + e,v = sp.eigh(over) + s = 1./np.sqrt(e) + zmat = np.zeros((hdim,hdim)) + for i in range(hdim): + zmat[i, :] = s[i] * v[:, i] + zmat = np.matmul(v, zmat) + elif method == "Cholesky": + pass + else: + print("ERROR: Method not implemented") + exit(0) + + if verbose: + print("\nZmat Matrix") + print(zmat) + + return zmat + +## Get charges (Mulliken) +# @brief gets the Mulliken charges based on rho +# @param density_matrix Density matrix +def get_charges_proxy(density_matrix,ncores,hindex,overlap=None,verb=False): + if(verb): + status_at("get_charges","Getting charges from density matrix") + + charges = np.zeros((ncores)) + + if overlap is None: + fullDiag = np.diag(density_matrix) + for i in range(ncores): + for ii in range(hindex[i], hindex[i + 1]): + charges[i] = charges[i] + (1.0 - 2.0 * fullDiag[ii]) + else: # S x D + aux = np.dot(overlap, density_matrix) + fullDiag = np.diag(aux) + for i in range(ncores): + for ii in range(hindex[i], hindex[i + 1]): + charges[i] = charges[i] + (1.0 - 2.0 * fullDiag[ii]) + + if verb: + msg = "Total Charge for part= " + str(sum(charges)) + status_at("get_charges", msg) + + return charges + + +## Get TB forces +# \brief Get TB and Coulombic forces from the Hamiltonian, Density matrix +# and charges. +# \param ham Hamiltonian Matrix +# \param rho Density Matrix +# \param field External field +# \param coords Coordinates +# \param atomTypes Atomic types +# \param Symbols Atomic symbols for every type. +## +def get_tb_forces_proxy(ham, rho, charges, field, coords, atomTypes, symbols): + nats = len(coords[:, 0]) + forces = np.zeros((nats, 3)) + forces_coul = np.zeros((nats, 3)) + forces_field = np.zeros((nats, 3)) + forces_band = np.zeros((nats, 3)) + dl = 0.0001 + coordsp = np.zeros((nats, 3)) + coordsm = np.zeros((nats, 3)) + ham = get_hamiltonian_proxy(coords, atomTypes, symbols, verb=False) + vaux = np.ones((nats)) + vaux[:] = 0.5 + rho0 = np.diag(vaux) + + for i in range(len(ham[:, 0])): + # Band Forces from tr(rho dH/dr) + for k in range(3): + coordsp[:, :] = coords[:, :] + coordsp[i, k] = coords[i, k] + dl + hamp = get_hamiltonian_proxy(coordsp, atomTypes, symbols, verb=False) + # Hmu = get_pert(field,coordsp,nats) + # Hp[:,:] = Hp[:,:] + Hmu[:,:] + + coordsm[:, :] = coords[:, :] + coordsm[i, k] = coords[i, k] - dl + hamm = get_hamiltonian_proxy(coordsm, atomTypes, symbols, verb=False) + # Hmu = get_pert(field,coordsm,nats) + # Hm[:,:] = Hm[:,:] + Hmu[:,:] + + dHdx = (hamp - hamm) / (2 * dl) + aux = 2 * np.matmul(rho - rho0, dHdx) + forces_band[i, k] = np.trace(aux) + print("dHdx", dHdx) + + return forces_band + + +def get_ppot_forces_expo_proxy(coords, types): + nats = len(coords[:, 0]) + forces = np.zeros((nats, 3)) + direction = np.zeros(3) + ppots_in = bring_ppots() + ppots = np.zeros((4)) + for i in range(nats): + for j in range(nats): + if i != j: + ii = types[i] + jj = types[j] + ppots[:] = ppots_in[ii, jj, :] + direction = coords[i, :] - coords[j, :] + d = np.linalg.norm(direction) + direction = direction / d + arg = ppots[0] + ppots[1] * d + ppots[2] * d**2 + ppots[3] * d**3 + argPrime = ppots[1] + 2 * ppots[2] * d + 3 * ppots[3] * d**2 + forces[i, :] = -direction * argPrime * (np.exp(arg)) + print(forces[i, :]) + + return forces + + +def get_ppot_energy_expo_proxy(coords, types): + nats = len(coords[:, 0]) + forces = np.zeros((nats, 3)) + direction = np.zeros(3) + energy = 0.0 + ppots_in = bring_ppots() + ppot = np.zeros((4)) + for i in range(nats): + for j in range(nats): + if i != j: + ii = types[i] + jj = types[j] + ppot[:] = ppots_in[ii, jj, :] + direction = coords[i, :] - coords[j, :] + d = np.linalg.norm(direction) + arg = ppot[0] + ppot[1] * d + ppot[2] * d**2 + ppot[3] * d**3 + energy = energy + np.exp(arg) + + return energy + + +## Get band energy +# @brief Get the band energy from the density matrix and the non-SCF Hamiltonian +# @param ham0 Non-scf Hamiltonian matrix +# @param rho0 Atomized density matrix +# @param rho Density matrix +# @return energy Band energy +def get_band_energy(ham0,rho0,rho): + + energy = 2*np.trace(np.dot(ham0,(rho-rho0))) # Single-particle/band energy + return energy + +## Get the electronic free energy +# @brief This computed from the entropy of the Fermi distribution +# @param fvals A vector containing the Fermi function for every eigenenergy +# @param kB Boltzan constant (default is in eV/K) +# @param elect_temp Electronic temperature +# +def get_electron_entropy_energy(fvals,kB=8.61739e-5,elec_temp=0): + if(elec_temp > 1.0E-10): + entropy = 0.0 + tol = 1.0E-9 + entropy = -kB*np.sum( fvals[:]*np.log10(fvals[:]) + (1.0 - fvals[:])*np.log10(1.0 - fvals[:]) ) + else: + entropy = 0.0 + energy = -2.0*elec_temp*entropy + return energy + + +## Get pair potential forces +# \brief We will use a simple LJ +# \param coords +# +def get_ppot_forces_LJ(coords): + # Following Levine + # VLJ = epsilon*( (a/d)^12 - 2*(b/d)^6 ) + # FLJ = espilon*( -12*( (a**12)/(d**13) ) - 12*( (b**6)/(d**7) ) ) + epsilon = 0.1 + a = 1.0 + b = 1.0 + nats = len(coords[:, 0]) + forces = np.zeros((nats, 3)) + direction = np.zeros(3) + for i in range(nats): + for j in range(nats): + if i != j: + direction = coords[i, :] - coords[j, :] + d = np.linalg.norm(direction) + direction = direction / d + forces[i, :] = -direction * epsilon * (-12 * ((a**12) / (d**13)) + 12 * ((b**6) / (d**7))) + + return forces + + +def get_ppot_energy(coords): + epsilon = 0.1 + a = 1.0 + b = 1.0 + nats = len(coords[:, 0]) + direction = np.zeros(3) + energy = 0 + for i in range(nats): + for j in range(nats): + if i != j: + direction = coords[i, :] - coords[j, :] + d = np.linalg.norm(direction) + energy = energy + epsilon * ((a / d) ** 12 - 2 * (b / d) ** 6) + + energy = energy / 2.0 + + return energy + + +if __name__ == "__main__": + n = len(sys.argv) + if n == 1: + print("Give the total number of atoms. Example:\n") + print("proxy_a 100\n") + sys.exit(0) + else: + nats = int(sys.argv[1]) + + verb = True + # coords = get_random_coordinates(nats) + # atomTypes = np.zeros((nats),dtype=int) + # symbols = []*nats + # symbols[:] = "H" + latticeVectors, symbols, atomTypes, coords = read_coords_file("methane.xyz", lib="None", verb=True) + read_ppots("ppots.dat", symbols) + print_ppots() + + bas_per_atom = [4, 1] + filename = "aosa_parameters.dat" + tbparams = read_tbparams(filename, symbols, bas_per_atom) + print("tbparam", tbparams[0].symbol) + exit(0) + + ham, over = get_hamiltonian_proxy(coords, atomTypes, symbols, get_overlap=True) + + with np.printoptions(precision=3, suppress=True): + print(ham) + print(over) + exit(0) + gpuLibIn = False ## need to pass from input file or command line + occ = int(float(nats) / 2.0) # Get the total occupied orbitals + + if gpuLibIn == False: + print("Using CPU for DM construction. Consider installing accelerator library...") + rho = get_density_matrix_proxy(ham, occ) + npart = len(coords[:, 0]) + hindex = np.arange(npart + 1, dtype=int) + field = np.zeros(3) + charges = get_charges_proxy(rho, npart, hindex, overlap=None, verb=False) + eforces = get_tb_forces(ham, rho, charges, field, coords, atomTypes, symbols) + nforces = get_ppot_forces(coords) + + # eenergy = get_tb_energy() + nenergy = get_ppot_energy(coords) + + coords[0, 0] = coords[0, 0] + 0.001 + nenergyp = get_ppot_energy(coords) + + print((nenergyp - nenergy) / 0.001, nforces[0, 0]) + exit(0) + + print(nforces) + exit(0) + print("Hamiltonian matrix=", ham) + print("Density matrix=", rho) + print("Forces=", forces) diff --git a/proxies/python/first_level.py b/proxies/python/first_level.py new file mode 100644 index 0000000..7d6759b --- /dev/null +++ b/proxies/python/first_level.py @@ -0,0 +1,441 @@ +"""proxy code a +A prototype engine that: + - Reads the total number of atoms + - Constructs a set of random coordinates + - Constructs a simple Hamiltonian + - Computes the Density matrix from the Hamiltonian + - Computes atomic Mulliken charges + - Computes TB + coulombic forces +""" + +import os +import sys + +import numpy as np +import scipy.linalg as sp +import sedacs.driver +import sedacs.interface_modules +from sedacs.dev.io import src_path + +try: + import ctypes + + # import gpulibInterface as gpu + + gpuLib = True + arch = "nvda" + pwd = os.getcwd() + + if arch == "nvda": + print("loading nvidia...") + lib = ctypes.CDLL(str((src_path() / "gpu/nvda/libnvda.so").absolute())) + if arch == "amd": + lib = ctypes.CDLL(str((src_path() / "gpu/amd/libamd.so").absolute())) + +except: + gpuLib = False + + +__all__ = [ + "RandomNumberGenerator", + "get_random_coordinates", + "get_hamiltonian_proxy", + "get_density_matrix_proxy", + "get_density_matrix_gpu", + "get_charges_proxy", + "get_forces_proxy", +] + + +## Simple random number generator +# This is important in order to compare across codes +# written in different languages. +# +# To initialize: +# \verbatim +# myRand = rand(123) +# \endverbatim +# where the argument of rand is the seed. +# +# To get a random number between "low" and "high": +# \verbatim +# rnd = myRand.get_rand(low,high) +# \endverbatim +# +class RandomNumberGenerator: + """To generate random numbers.""" + + def __init__(self, seed): + self.a = 321 + self.b = 231 + self.c = 13 + self.seed = seed + self.status = seed * 1000 + + def generate(self, low, high): + """Get a random real number in between low and high.""" + w = high - low + place = self.a * self.status + place = int(place / self.b) + rand = (place % self.c) / self.c + place = int(rand * 1000000) + self.status = place + rand = low + w * rand + + return rand + + +## Generating random coordinates +# @brief Creates a system of size "nats = Number of atoms" with coordindates having +# a random (-1,1) displacement from a simple cubic lattice with parameter 2.0 Ang. +# +# @param nats The total number of atoms +# @return coordinates Position for every atom. z-coordinate of atom 1 = coords[0,2] +# +def get_random_coordinates(nats): + """Get random coordinates""" + length = int(nats ** (1 / 3)) + 1 + coords = np.zeros((nats, 3)) + latticeParam = 2.0 + atomsCounter = -1 + myrand = RandomNumberGenerator(111) + for i in range(length): + for j in range(length): + for k in range(length): + atomsCounter = atomsCounter + 1 + if atomsCounter >= nats: + break + rnd = myrand.generate(-1.0, 1.0) + coords[atomsCounter, 0] = i * latticeParam + rnd + rnd = myrand.generate(-1.0, 1.0) + coords[atomsCounter, 1] = j * latticeParam + rnd + rnd = myrand.generate(-1.0, 1.0) + coords[atomsCounter, 2] = k * latticeParam + rnd + return coords + + +## Computes a Hamiltonian based on exponential decay of orbital couplings. +# @author Anders Niklasson +# @brief Computes a hamiltonian \f$ H_{ij} = (x/m)\exp(-(y/n + decay_{min}) |R_{ij}|^2))\f$, based on distances +# \f$ R_{ij} \f$. \f$ x,m,y,n,decay_{min} \f$ are fixed parameters. +# +# @param coords Position for every atoms. z-coordinate of atom 1 = coords[0,2] +# @param atomTypes Index type for each atom in the system. Type for first atom = type[0] (not used yet) +# @param symbols Symbols for every atom type. +# @param verb Verbosity. If True is passed, information is printed +# @return ham 2D numpy array of Hamiltonian elements +# +def get_hamiltonian_proxy(coords, atomTypes, symbols, verb=False, get_overlap=False): + """Construct simple toy s-Hamiltonian""" + + + #Internal periodic table for the code + symbols_internal = np.array([ "Bl" , + "H" , "He" , + "Li" , "Be" , "B" , "C" , "N" , "O" , "F" , \ + ], dtype=str) + numel_internal = np.zeros(len(symbols_internal),dtype=int) + numel_internal[:] = 0, \ + 1 , 2 , \ + 1 , 2 , 3 , 4 , 5 , 6 , 7 , + + bas_per_atom = np.zeros(len(symbols_internal),dtype=int) + bas_per_atom[:] = 0, \ + 1 , 1 ,\ + 4 , 4, 4, 4 , 4, 4, 4, + + + nats = len(coords[:,0]) + numel = 0 + + # Map symbols to indices in symbols_internal + symbol_to_index = {symbol: idx for idx, symbol in enumerate(symbols_internal)} + + # Translate `symbols` to `symbols_internal` indices + mapped_indices = np.array([symbol_to_index[symbol] for symbol in symbols]) + + # Convert atomTypes to `symbols_internal` indices + atom_internal_indices = mapped_indices[atomTypes] + + # Sum the corresponding values in bas_per_atom and numel_internal + norbs = np.sum(bas_per_atom[atom_internal_indices]) + numel = np.sum(numel_internal[atom_internal_indices]) + + + nocc = int(numel/2.0) + eps = 1e-9 + decay_min = 0.1 + m = 78 + a = 3.817632 + c = 0.816371 + x = 1.029769 + n = 13 + b = 1.927947 + d = 3.386142 + y = 2.135545 + ham = np.zeros((norbs, norbs)) + if(get_overlap): + over = np.zeros((norbs, norbs)) + if verb: + print("Constructing a simple Hamiltonian for the full system") + colsh = 0 + rowsh = 0 + for i in range(0, nats): + for ii in range(bas_per_atom[atom_internal_indices[i]]): + x = (a * x + c) % m # Hamiltonian parameters + y = (b * y + d) % n + colsh = 0 + for j in range(i, nats): + for jj in range(bas_per_atom[atom_internal_indices[j]]): + dist = np.linalg.norm(coords[i, :] - coords[j, :]) + tmp = np.exp(-(y / n + decay_min) * (dist**2)) + if(get_overlap): + over[rowsh,colsh] = tmp + over[colsh,rowsh] = tmp + + tmp = (x/m)*tmp + ham[rowsh, colsh] = tmp + ham[colsh, rowsh] = tmp + colsh = colsh + 1 + rowsh = rowsh + 1 + if(get_overlap): + return ham, over + else: + return ham + +sedacs.driver.get_hamiltonian = get_hamiltonian_proxy + +## Computes the Density matrix from a given Hamiltonian. +# @author Anders Niklasson +# @brief This will create a "zero-temperature" Density matrix \f$ \rho \f$ +# \f[ \rho = \sum^{nocc} v_k v_k^T \f] +# where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ +# +# @param ham Hamiltonian matrix +# @param nocc Number of occupied orbitals +# @param verb Verbosity. If True is passed, information is printed. +# +# @return rho Density matrix +# +def get_density_matrix_proxy(ham, nocc, verb=False): + """Calcualted the full density matrix from H""" + if verb: + print("Computing the Density matrix") + E, Q = sp.eigh(ham) + norbs = len(ham[:, 0]) + homoIndex = nocc - 1 + lumoIndex = nocc + mu = 0.5 * (E[homoIndex] + E[lumoIndex]) + rho = np.zeros((norbs, norbs)) + if verb: + print("Eigenvalues of H:", E) + for i in range(norbs): + if E[i] < mu: + rho = rho + np.outer(Q[:, i], Q[:, i]) + if verb: + print("Chemical potential = ", mu) + return rho + + +sedacs.driver.get_density_matrix = get_density_matrix_proxy + + +## Computes the finite temperature density matrix +# \param +def get_density_matrix_T(H, Nocc, Tel, mu0, coreSize, core_ham_dim, S=None, verb=False): + + kB = 8.61739e-5 # eV/K, kB = 6.33366256e-6 Ry/K, kB = 3.166811429e-6 Ha/K, #kB = 3.166811429e-6 #Ha/K + if(verb): print("Computing the renormalized Density matrix") + + if S is not None: + E_val,Q = scipy.linalg.eigh(H) ### need S? not ones with S $$$ + else: + E_val,Q = np.linalg.eigh(H) + N = len(H[:,0]) + + #print('Q\n', Q[:,0]) + + homoIndex = Nocc - 1 + lumoIndex = Nocc + print('HOMO, LUMO:', E_val[homoIndex], E_val[lumoIndex]) + mu_test = 0.5*(E_val[homoIndex] + E_val[lumoIndex]) #don't need it + print(N, Nocc,) + print('!!!! mu test:\n', mu_test) + + # use mu0 as a guess + + OccErr = 1.0 + beta = 1./(kB*Tel) + f = np.array([]) + for i in range(N): + f_i = 1/(np.exp(beta*(E_val[i] - mu0)) + 1) # save fi to f + f = np.append(f,f_i) + #Occ = Occ + f_i*E_occ[i,k] + + + D = sum(np.outer(Q[:, i],Q[:, i]*f[i]) for i in range(Nocc))*2 + #np.savetxt('co2_32_dm.txt',D) + + + # rho = Q@f_vector@Q.T + # or + # rho_ij = SUM_k Q_ik * f_kk * Q_jk + + + print('core_ham_dim', core_ham_dim) + dVals = np.array([]) + for i in range(N): + dVals = np.append(dVals, np.inner(Q[:core_ham_dim,i],Q[:core_ham_dim, i])) + + return D, E_val, dVals + + +## Computes the Density matrix from a given Hamiltonian. +# @author Josh Finkelstein +# @brief This will create a "zero-temperature" Density matrix \f$ \rho \f$ +# \f[ \rho = \sum^{nocc} v_k v_k^T \f] +# where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ +# using GPU/AI accelerator library +# +# @param H Hamiltonian matrix +# @param Nocc Number of occupied orbitals +# @param verb Verbosity. If True is passed, information is printed. +# +# @return D Density matrix +# +def get_density_matrix_gpu(H, N, Nocc, lib, verb=False): + """Calcualted the full density matrix from H""" + if verb: + print("Computing the Density matrix using GPU/AI accel library") + + # init DM + D = np.zeros((N, N)) + kbt = 0.1 + + # get DM from cusolver diag + # dm = gpu.dmDNNSP2(H,D,N,Nocc,lib) + # dm = gpu.dmCheby(H,D,N,Nocc,kbt,lib) + print("Density matrix=", D) + # dm = gpu.dmDiag(H,D,N,Nocc,kbt,lib) + # print("Density matrix=",dm) + dm = gpu.dmMLSP2(H, D, N, Nocc, lib) + return D + +def get_charges_proxy(density_matrix,ncores,hindex,overlap=None,verb=False): + if(verb): + status_at("get_charges","Getting charges from density matrix") + + fullDiag = np.diag(density_matrix) + charges = np.zeros((ncores)) + + if(overlap is None): + for i in range(ncores): + for ii in range(hindex[i],hindex[i+1]): + charges[i] = charges[i] + (1.0 - fullDiag[ii]) + else: + pass + + if(verb): + msg = "Total Charge for part= " + str(sum(charges)) + status_at("get_charges",msg) + + return charges + + +## Get TB forces +# \brief Get TB and Coulombic forces from the Hamiltonian, Density matrix +# and charges. +# \param ham Hamiltonian Matrix +# \param rho Density Matrix +# \param field External field +# \param coords Coordinates +# \param atomTypes Atomic types +# \param Symbols Atomic symbols for every type. +## +def get_tb_forces(ham, rho, charges, field, coords, atomTypes,symbols): + + nats = len(coords[:,0]) + forces = np.zeros((nats,3)) + forces_coul = np.zeros((nats,3)) + forces_field = np.zeros((nats,3)) + forces_band = np.zeros((nats,3)) + dl = 0.0001 + coordsp = np.zeros((nats,3)) + coordsm = np.zeros((nats,3)) + ham = get_hamiltonian_proxy(coords,atomTypes,symbols,verb=False) + vaux = np.ones((nats)) + vaux[:] = 0.5 + rho0 = np.diag(vaux) + + for i in range(len(ham[:,0])): + + #Band Forces from tr(rho dH/dr) + for k in range(3): + coordsp[:,:] = coords[:,:] + coordsp[i,k] = coords[i,k] + dl + hamp = get_hamiltonian_proxy(coordsp,atomTypes,symbols,verb=False) + #Hmu = get_pert(field,coordsp,nats) + #Hp[:,:] = Hp[:,:] + Hmu[:,:] + + coordsm[:,:] = coords[:,:] + coordsm[i,k] = coords[i,k] - dl + hamm = get_hamiltonian_proxy(coordsm,atomTypes,symbols,verb=False) + #Hmu = get_pert(field,coordsm,nats) + #Hm[:,:] = Hm[:,:] + Hmu[:,:] + + dHdx = (hamp - hamm)/(2*dl) + aux = 2*np.matmul(rho-rho0,dHdx) + forces_band[i,k] = np.trace(aux) + print("dHdx",dHdx) + + #Coulombic Forces + for j in range(len(ham[:,0])): + if(i != j): + distance = np.linalg.norm(coords[i,:] - coords[j,:]) + direction = (coords[i,:] - coords[j,:])/distance + #F_coul[i,:] = F_coul[i,:] - (14.3996437701414*1.0*direction*q[i]*q[j])/(distance**2) + forces_coul[i,:] = forces_coul[i,:] - (1.0*direction*charges[i]*charges[j])/(distance**2) + + #Field forces + #forces_field[i,:] = forces_field[i,:] + field*charges[i] + + forces[:,:] = - ( forces_band[:,:] + forces_coul[:,:] + forces_field[:,:]) + return forces + + +## Main program for proxy a +# \brief It will read the number of atoms, contruct +# a set of random coordinates and give back a Density matrix. +# +if __name__ == "__main__": + n = len(sys.argv) + if n == 1: + print("Give the total number of atoms. Example:\n") + print("proxy_a 100\n") + sys.exit(0) + else: + nats = int(sys.argv[1]) + + verb = True + coords = get_random_coordinates(nats) + atomTypes = np.zeros((nats),dtype=int) + symbols = []*nats + symbols[:] = "H" + + ham = get_hamiltonian_proxy(coords,atomTypes,symbols) + + gpuLibIn = False ## need to pass from input file or command line + occ = int(float(nats) / 2.0) # Get the total occupied orbitals + + if gpuLibIn == False: + print("Using CPU for DM construction. Consider installing accelerator library...") + rho = get_density_matrix_proxy(ham, occ) + npart = len(coords[:,0]) + hindex = np.arange(npart+1,dtype=int) + field = np.zeros(3) + charges = get_charges_proxy(rho,npart,hindex,overlap=None,verb=False) + forces = get_tb_forces(ham, rho, charges, field, coords, atomTypes,symbols) + print("Hamiltonian matrix=",ham) + print("Density matrix=",rho) + print("Forces=",forces) + diff --git a/proxies/python/first_level_gpu.py b/proxies/python/first_level_gpu.py new file mode 100644 index 0000000..297d6b4 --- /dev/null +++ b/proxies/python/first_level_gpu.py @@ -0,0 +1,303 @@ +"""proxy code a +A prototype engine that: + - Reads the total number of atoms + - Constructs a set of random coordinates + - Constructs a simple Hamiltonian + - Computes the Density matrix from the Hamiltonian +""" + +import ctypes +import sys + +import numpy as np +import scipy.linalg as sp +from juliacall import Main as jl + +import sedacs.driver +import sedacs.gpu as gpu +import sedacs.interface_modules +from sedacs.dev.io import src_path +from sedacs.gpu.library import Library + +gpuLib = True +arch = "nvda" + +if arch == "nvda": + print("loading nvidia...") + lib = Library(src_path() / "gpu/nvda/libnvda.so").as_dll() +if arch == "amd": + lib = Library(src_path() / "gpu/amd/libamd.so").as_dll() + + +## Simple random number generator +# This is important in order to compare across codes +# written in different languages. +# +# To initialize: +# \verbatim +# myRand = rand(123) +# \endverbatim +# where the argument of rand is the seed. +# +# To get a random number between "low" and "high": +# \verbatim +# rnd = myRand.get_rand(low,high) +# \endverbatim +# +class rand: + """To generate random numbers.""" + + def __init__(self, seed): + self.a = 321 + self.b = 231 + self.c = 13 + self.seed = seed + self.status = seed * 1000 + + def get_rand(self, low, high): + """Get a random real number in between low and high.""" + w = high - low + place = self.a * self.status + place = int(place / self.b) + rand = (place % self.c) / self.c + place = int(rand * 1000000) + self.status = place + rand = low + w * rand + + return rand + + +## Generating random coordinates +# @brief Creates a system of size "nats = Number of atoms" with coordindates having +# a random (-1,1) displacement from a simple cubic lattice with parameter 2.0 Ang. +# +# @param nats The total number of atoms +# @return coordinates Position for every atom. z-coordinate of atom 1 = coords[0,2] +# +def get_random_coordinates(nats): + """Get random coordinates""" + length = int(nats ** (1 / 3)) + 1 + coords = np.zeros((nats, 3)) + latticeParam = 2.0 + atomsCounter = -1 + myrand = rand(111) + for i in range(length): + for j in range(length): + for k in range(length): + atomsCounter = atomsCounter + 1 + if atomsCounter >= nats: + break + rnd = myrand.get_rand(-1.0, 1.0) + coords[atomsCounter, 0] = i * latticeParam + rnd + rnd = myrand.get_rand(-1.0, 1.0) + coords[atomsCounter, 1] = j * latticeParam + rnd + rnd = myrand.get_rand(-1.0, 1.0) + coords[atomsCounter, 2] = k * latticeParam + rnd + return coords + + +## Computes a Hamiltonian based on a single "s-like" orbitals per atom. +# @author Anders Niklasson +# @brief Computes a hamiltonian \f$ H_{ij} = (x/m)\exp(-(y/n + decay_{min}) |R_{ij}|^2))\f$, based on distances +# \f$ R_{ij} \f$. \f$ x,m,y,n,decay_{min} \f$ are fixed parameters. +# +# @param coords Position for every atoms. z-coordinate of atom 1 = coords[0,2] +# @param types Index type for each atom in the system. Type for first atom = type[0] (not used yet) +# @return H 2D numpy array of Hamiltonian elements +# @param verb Verbosity. If True is passed, information is printed +# +def proxyA_get_hamiltonian(coords, atomTypes=np.zeros((1), dtype=int), verb=False): + """Construct simple toy s-Hamiltonian""" + N = len(coords[:, 1]) + Nocc = int(N / 4) + eps = 1e-9 + decay_min = 0.1 + m = 78 + a = 3.817632 + c = 0.816371 + x = 1.029769 + n = 13 + b = 1.927947 + d = 3.386142 + y = 2.135545 + H = np.zeros((N, N)) + if verb: + print("Constructing a simple Hamiltonian for the full system") + cnt = 0 + for i in range(0, N): + x = (a * x + c) % m # Hamiltonian parameters + y = (b * y + d) % n + for j in range(i, N): + dist = np.linalg.norm(coords[i, :] - coords[j, :]) + tmp = (x / m) * np.exp(-(y / n + decay_min) * (dist**2)) + H[i, j] = tmp + H[j, i] = tmp + return H + + +## Computes the Density matrix from a given Hamiltonian. +# @author Anders Niklasson +# @brief This will create a "zero-temperature" Density matrix \f$ \rho \f$ +# \f[ \rho = \sum^{nocc} v_k v_k^T \f] +# where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ +# +# @param H Hamiltonian matrix +# @param Nocc Number of occupied orbitals +# @param verb Verbosity. If True is passed, information is printed. +# +# @return D Density matrix +# +def get_densityMatrix(H, Nocc, verb=False): + """Calcualted the full density matrix from H""" + if verb: + print("Computing the Density matrix") + E, Q = sp.eigh(H) + N = len(H[:, 0]) + homoIndex = Nocc - 1 + lumoIndex = Nocc + mu = 0.5 * (E[homoIndex] + E[lumoIndex]) + D = np.zeros((N, N)) + if verb: + print("Eigenvalues of H:", E) + for i in range(N): + if E[i] < mu: + D = D + np.outer(Q[:, i], Q[:, i]) + if verb: + print("Chemical potential = ", mu) + return D + + +## Computes the Density matrix from a given Hamiltonian. +# @author Josh Finkelstein +# @brief This will create a "zero-temperature" Density matrix \f$ \rho \f$ +# \f[ \rho = \sum^{nocc} v_k v_k^T \f] +# where \f$ v_k \f$ are the eigenvectors of the matrix \f$ H \f$ +# using GPU/AI accelerator library +# +# @param H Hamiltonian matrix +# @param Nocc Number of occupied orbitals +# @param verb Verbosity. If True is passed, information is printed. +# +# @return D Density matrix +# +def get_densityMatrix_response_accel(H, P, D, R, N, Nocc, handle, lib, verb=False): + """Calcualte the full density matrix and its response to pertubation P in H""" + if verb: + print("Computing the Density matrix using GPU/AI accel library") + + # get DM from PRT + time = gpu.dmDNNPRT(H, P, D, R, N, Nocc, handle, lib) + return time + + +def get_densityMatrix_accel(H, D, N, Nocc, handle, lib, verb=False): + """Calcualted the full density matrix from H""" + if verb: + print("Computing the Density matrix using GPU/AI accel library") + + # init DM + # D = np.zeros((N,N)) + kbt = 0.001 + + # get DM from cusolver diag + # time = gpu.dmDNNSP2(H, D, N, Nocc, handle, lib) + # dm = gpu.dmCheby(H,D,N,Nocc,kbt,lib) + # print("Density matrix=",D) + # time = gpu.dmDiag(H,D,N,Nocc,kbt,lib) + # print("Density matrix=",dm) + time = gpu.dmMLSP2(H, D, N, Nocc, lib) + return time + + +## Main program for proxy a +# \brief It will read the number of atoms, contruct +# a set of random coordinates and give back a Density matrix. +# +if __name__ == "__main__": + nats = 512 + + coords = get_random_coordinates(nats) + + # H = proxyA_get_hamiltonian(coords) + jl.seval("using Pkg") + jl.seval('Pkg.activate("./GeneralizedSP2/examples")') + jl.seval(""" + using Distributions + using GershgorinDiscs + using GeneralizedSP2 + using LinearAlgebra + using ToyHamiltonians + using DelimitedFiles + set_isapprox_rtol(1e-13) + β = 1.25 # Physical + μ = 150 # Physical + sys_size = 512 + dist = LogUniform(100, 200) + Λ = rand(EigvalsSampler(dist), sys_size) + V = rand(EigvecsSampler(dist), sys_size, sys_size) + H = Hamiltonian(Eigen(Λ, V)) + savemodel("H.npy", H) + 𝚲 = eigvals(H) # Must be all reals + emin, emax = floor(minimum(𝚲)), ceil(maximum(𝚲)) + open("minmax.txt", "w") do f + write(f, string(emin) * "\n") + write(f, string(emax) * "\n") + end + H_scaled = rescale_one_zero(emin, emax)(H) + savemodel("H_scaled.npy", H_scaled) + """) + H = np.ascontiguousarray(np.load("H.npy"), dtype=np.float64) + + # Allocate dm + D = np.zeros((nats, nats)) + + P = np.zeros((nats, nats)) + R = np.zeros((nats, nats)) + + gpuLibIn = True ## need to pass from input file or command line + occ = int(float(nats) / 2.0) # Get the total occupied orbitals + + for i in range(10): + if gpuLibIn == False: + print("Using CPU for DM construction. Consider installing accelerator library...") + Dcpu = get_densityMatrix(H, occ) + break + + elif gpuLibIn == True: + if gpuLib == False: + print("No accelerator library found. Consider installing or change input.") + + ## allocate some gpu mem + size_of_double = 8 # bytes + matSize = nats * nats * size_of_double + cublas_handle = gpu.cublasInit(lib) + + d_ham = gpu.dev_alloc(matSize, lib) + d_prt = gpu.dev_alloc(matSize, lib) + d_dm = gpu.dev_alloc(matSize, lib) + d_rsp = gpu.dev_alloc(matSize, lib) + + ## copy ham from host to device + gpu.memcpyHtoD(d_ham, H, matSize, lib) + + ## copy ham from host to device + gpu.memcpyHtoD(d_prt, P, matSize, lib) + + print("iteration ", i) + timer = get_densityMatrix_accel(d_ham, d_dm, nats, occ, cublas_handle, lib) + # timer = get_densityMatrix_response_accel(d_ham, d_prt, d_dm, d_rsp, nats, occ, cublas_handle, lib) + print(f"python time = {timer:0.10f} seconds") + print("=========================") + + ## copy dm from device to host + size_of_double = 8 # bytes + matSize = nats * nats * size_of_double + gpu.memcpyDtoH(D, d_dm, matSize, lib) + + # print(D) + with open("cuda.npy", "wb") as f: + np.save(f, D) + gpu.dev_free(d_dm, lib) + gpu.dev_free(d_ham, lib) + gpu.dev_free(d_prt, lib) + gpu.dev_free(d_rsp, lib) diff --git a/proxies/python/hamiltonian.py b/proxies/python/hamiltonian.py new file mode 100644 index 0000000..2fac56b --- /dev/null +++ b/proxies/python/hamiltonian.py @@ -0,0 +1,182 @@ +"""hamiltonian +A prototype engine code that: + - Constructs different Hamiltonians +This code is only used to guide implemetations and understand which are the +basic elements needed to interface with the sedacs driver. +""" + +import os +import sys + +import numpy as np +import sedacs.driver +from sedacs.dev.io import src_path +import scipy.linalg as sp +from hamiltonian_elements import * +from dnnprt import * +from proxies.python.proxy_global import * +#from proxy_global import * + +try: + import ctypes + + # import gpulibInterface as gpu + + gpuLib = True + arch = "nvda" + pwd = os.getcwd() + + if arch == "nvda": + print("loading nvidia...") + lib = ctypes.CDLL(str((src_path() / "gpu/nvda/libnvda.so").absolute())) + if arch == "amd": + lib = ctypes.CDLL(str((src_path() / "gpu/amd/libamd.so").absolute())) + +except: + gpuLib = False + + +__all__ = [ + "get_hamiltonian_proxy", + "get_random_hamiltonian", + "build_coul_ham_proxy" +] + + +## Computes a Hamiltonian based on exponential decay of orbital couplings. +# @author Anders Niklasson +# @brief Computes a hamiltonian based on exponential decays. +# @param coords Position for every atoms. z-coordinate of atom 1 = coords[0,2] +# @param atomTypes Index type for each atom in the system. Type for first atom = type[0] (not used yet) +# @param symbols Symbols for every atom type +# @param verb Verbosity. If True is passed, information is printed +# @para get_overlap If overlap needs to be returned +# @return ham 2D array of Hamiltonian elements +# +def get_hamiltonian_proxy(coords, atomTypes, symbols, verb=False, get_overlap=False): + """Constructs a simple tight-binding Hamiltonian""" + + # Internal periodic table for the code + symbols_internal = np.array(["Bl", "H", "C", "N", "O", "P"], dtype=str) + numel_internal = np.zeros(len(symbols_internal), dtype=int) + numel_internal[:] = 0, 1, 4, 5, 6, 5 + bas_per_atom = np.zeros(len(symbols_internal), dtype=int) + bas_per_atom[:] = 0, 1, 4, 4, 4, 4 + spOrbTypes = ["s", "px", "py", "pz"] + sOrbTypes = ["s"] + + nats = len(coords[:, 0]) + + # Map symbols to indices in symbols_internal + symbol_to_index = {symbol: idx for idx, symbol in enumerate(symbols_internal)} + + # Translate `symbols` to `symbols_internal` indices + mapped_indices = np.array([symbol_to_index[symbol] for symbol in symbols]) + + # Convert atomTypes to `symbols_internal` indices + atom_internal_indices = mapped_indices[atomTypes] + + + # Sum the corresponding values in bas_per_atom and numel_internal + norbs = np.sum(bas_per_atom[atom_internal_indices]) + numel = np.sum(numel_internal[atom_internal_indices]) + + ham = np.zeros((norbs, norbs)) + if get_overlap: + over = np.zeros((norbs, norbs)) + if verb: + print("Constructing a simple Hamiltonian for the full system") + + colsh = 0 + rowsh = 0 + tbparams = bring_tbparams() + for i in range(0, nats): + for ii in range(bas_per_atom[atom_internal_indices[i]]): + colsh = rowsh + parI = tbparams[atomTypes[i]][ii] + for j in range(i, nats): + if i == j: + llimit = ii + else: + llimit = 0 + for jj in range(llimit,bas_per_atom[atom_internal_indices[j]]): + parJ = tbparams[atomTypes[j]][jj] + hval, sval = get_integral_v1(coords[i],coords[j],parI,parJ) + if(get_overlap): + over[rowsh,colsh] = sval + over[colsh,rowsh] = sval + + ham[rowsh, colsh] = hval + ham[colsh, rowsh] = hval + colsh = colsh + 1 + rowsh = rowsh + 1 + + if get_overlap: + return ham, over + else: + return ham + + +sedacs.driver.get_hamiltonian = get_hamiltonian_proxy + +## Add coulombic potentials to the Hamiltonian +# @param ham0 No-SCF Hamiltonian +# @param vcouls Coulombic potentials for every atomic site +# @pparam orbital_based If set to True, coulombic potentials for every orbitals will be +# expected. +# @param hindex will give the orbital index for each atom +# The orbital indices for orbital i goes from `hindex[i]` to `hindex[i+1]-1` +# @param overlap Overlap matrix for nonorthogonal formulations. +# @param verb Verbosity switch. +# +def build_coul_ham_proxy(ham0, vcouls, types, charges, orbital_based, hindex, overlap=None, verb=False): + norbs = len(ham0[:, 0]) + vcouls_orbs = np.zeros((norbs), dtype=float) # Expanded coulombic potentials + nats = len(hindex[:]) - 1 + + tbparams = bring_tbparams() + + if orbital_based: + error_at("build_coul_ham", "Orbital-based coulombic potential not implemented") + else: + for i in range(nats): + for ii in range(hindex[i], hindex[i + 1]): + k = ii - hindex[i] + vcouls_orbs[ii] = vcouls[i] + tbparams[types[i]][k].u * charges[i] + if overlap is None: + ham = ham0 + np.diag(vcouls_orbs) + else: + vmat = np.diag(vcouls_orbs) + ham = ham0 + 0.5 * (np.dot(overlap, vmat) + np.dot(vmat, overlap)) + return ham + + +## Computes a Hamiltonian based on a single "s-like" orbitals per atom. +# @author Anders Niklasson +# @brief Computes a hamiltonian \f$ H_{ij} = (x/m)\exp(-(y/n + decay_{min}) |R_{ij}|^2))\f$, based on distances +# \f$ R_{ij} \f$. \f$ x,m,y,n,decay_{min} \f$ are fixed parameters. +# +# @param ndim Size of the Hamiltonian matrix +# @param verb Verbosity. If True is passed, information is printed +# @return H 2D numpy array of Hamiltonian elements +# +def get_random_hamiltonian(coords,verb=False): + """Construct simple toy s-Hamiltonian """ + norbs = len(coords[:,0]) + eps = 1e-9; decay_min = 0.1; m = 78; + a = 3.817632; c = 0.816371; x = 1.029769; n = 13; + b = 1.927947; d = 3.386142; y = 2.135545; + ham = np.zeros((norbs,norbs)) + if(verb): print("Constructing a simple Hamiltonian for the full system") + cnt = 0 + for i in range(0,norbs): + x = (a*x+c)%m #Hamiltonian parameters + y = (b*y+d)%n + for j in range(i,norbs): + dist = np.linalg.norm(coords[i,:]-coords[j,:]) + tmp = (x/m)*np.exp(-(y/n + decay_min)*(dist**2)) + ham[i,j] = tmp + ham[j,i] = tmp + ham[i,i] = x*y + return ham + diff --git a/proxies/python/hamiltonian_elements.py b/proxies/python/hamiltonian_elements.py new file mode 100644 index 0000000..c1cf3e0 --- /dev/null +++ b/proxies/python/hamiltonian_elements.py @@ -0,0 +1,309 @@ +"""AOSA and LATTE - prototype hamiltonian elements +Atomic orbital spherical approximation + - Reads the total number of atoms + - Constructs a set of random coordinates + - Constructs a simple Hamiltonian + - Computes the hamiltonian derivatives +""" + +import os +import sys + +import numpy as np +import scipy.linalg as sp +#import sedacs.driver +#import sedacs.interface_modules +#from sedacs.dev.io import src_path + +try: + import ctypes + + # import gpulibInterface as gpu + + gpuLib = True + arch = "nvda" + pwd = os.getcwd() + + if arch == "nvda": + print("loading nvidia...") + lib = ctypes.CDLL(str((src_path() / "gpu/nvda/libnvda.so").absolute())) + if arch == "amd": + lib = ctypes.CDLL(str((src_path() / "gpu/amd/libamd.so").absolute())) + +except: + gpuLib = False + + +__all__ = [ + "AOSA_Parameter", + "get_integral", + "get_integral_v1", +] + +class AOSA_Parameter: + def __init__(self,symbol,orb,filePath): + self.symbol = symbol + self.orbType = orb + parFile = open(filePath,"r") + count = 0 + symbFound = False + orbFound = False + for line in parFile: + info = line.split() + if(len(info) >= 1): + print(info) + if(info[0] == "Element="): + if(info[1] == symbol): + norbs = int(info[3]) + symbFound = True + print(info[1],symbol,symbFound) + if(symbFound and info[3] == orb): + print(info[5]) + orbFound = True + self.onsite = float(info[5]) + self.u = float(info[7]) + self.nl = int(info[9]) + self.kappas = np.zeros((self.nl)) + self.ds = np.zeros((self.nl,3)) + self.gammas = np.zeros((self.nl,4)) + if(symbFound and orbFound and info[0] == "LobeIndex="): + self.kappas[count] = float(info[3]) + self.ds[count,0] = float(info[5]) + self.ds[count,1] = float(info[6]) + self.ds[count,2] = float(info[7]) + + self.gammas[count,0] = float(info[9]) + self.gammas[count,1] = float(info[10]) + self.gammas[count,2] = float(info[11]) + self.gammas[count,3] = float(info[12]) + + count = count + 1 + + if(count == self.nl): + break + + + +def get_integral(coordsI,symbolI,orbI,coordsJ,symbolJ,orbJ): + + parI = AOSA_Parameters(symbolI,orbI) + parJ = AOSA_Parameters(symbolJ,orbJ) + + RIJ = coordsJ - coordsI + #Expo + inte = 0.0 + for li in range(parI.nl): + for lj in range(parJ.nl): + sn = np.sign(parI.kappas[li])*np.sign(parJ.kappas[lj]) + kappaIJ = sn*(abs(parI.kappas[li]) + abs(parJ.kappas[lj]))/2 + gammaIJ = (parI.gammas[li,0] + parI.gammas[li,0])/2 + dIJ = RIJ + parJ.ds[lj,:] - parI.ds[li,:] + #dIJ = np.dot(RIJ,parJ.ds[lj,:]) + parJ.ds[lj,:] - parI.ds[li,:] + inte = inte + kappaIJ*np.exp(gammaIJ*np.linalg.norm(dIJ)) + + sval = inte + hval = inte*(parI.onsite + parJ.onsite)/2 + + return hval, sval + + + +def get_integral_v1(coordsI,coordsJ,parI,parJ): + + RIJ = coordsJ - coordsI + #Expo + inte = 0.0 + for li in range(parI.nl): + for lj in range(parJ.nl): + sn = np.sign(parI.kappas[li])*np.sign(parJ.kappas[lj]) + kappaIJ = sn*(abs(parI.kappas[li]) + abs(parJ.kappas[lj]))/2 + gammaIJ = (parI.gammas[li,0] + parJ.gammas[lj,0])/2 + dIJ = RIJ + parJ.ds[lj,:] - parI.ds[li,:] + inte = inte + kappaIJ*np.exp(gammaIJ*np.linalg.norm(dIJ)) + + sval = inte + hval = inte*(parI.onsite + parJ.onsite)/2 + + return hval, sval + + +def LoadBondIntegralParameters_H(TYPE_PAIR): + + TYPE_a = TYPE_PAIR[0] + TYPE_b = TYPE_PAIR[1] + + fss_sigma = np.zeros((8)) + fsp_sigma = np.zeros((8)) + fps_sigma = np.zeros((8)) + fpp_sigma = np.zeros((8)) + fpp_pi = np.zeros((8)) + + if TYPE_a == 'H': + if TYPE_b == 'H': + fss_sigma[0:8] = [-9.400000,-1.145903,-0.391777,0.000,0.000,0.750,3.500,4.000] + fsp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fps_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_pi[0:8] = [0,0,0,0,0,0,0,0] + Es = -6.4835 + Ep = 0.0 + U = 12.054683 + elif TYPE_b == 'C': + fss_sigma[0:8] = [-9.235812,-1.372683,-0.408433,0.0000,0.0000,1.1000,3.5000,4.000 ] + fsp_sigma[0:8] = [8.104851 ,-0.936099 ,-0.626219 ,0.000 ,0.000 ,1.100 ,3.500 ,4.000 ] + fps_sigma[0:8] = [8.104851 ,-0.936099 ,-0.626219 ,0.000 ,0.000 ,1.100 ,3.500 ,4.000 ] + fpp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_pi[0:8] = [0,0,0,0,0,0,0,0] + Es = 0; Ep = 0; U = 0 + elif TYPE_b == 'O': + fss_sigma[0:8] = [-12.189103 ,-1.800097 ,-0.325933 ,0.000 ,0.000 ,1.000 ,3.500 ,4.000 ] + fsp_sigma[0:8] = [9.518733 ,-1.333235 ,-0.39371 ,0.000 ,0.000 ,1.000 ,3.500 ,4.000 ] + fps_sigma[0:8] = [9.518733 ,-1.333235 ,-0.39371 ,0.000 ,0.000 ,1.000 ,3.500 ,4.000 ] + fpp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_pi[0:8] = [0,0,0,0,0,0,0,0] + Es = 0; Ep = 0; U = 0 + elif TYPE_b == 'N': + fss_sigma[0:8] = [-12.63103 ,-1.585597 ,-0.250969 ,0.00 ,0.000 ,1.00 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [9.837852 ,-1.23485 ,-0.324283 ,0.00 ,0.000 ,1.00 ,3.50 ,4.00 ] + fps_sigma[0:8] = [9.837852 ,-1.23485 ,-0.324283 ,0.00 ,0.000 ,1.00 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_pi[0:8] = [0,0,0,0,0,0,0,0] + Es = 0; Ep = 0; U = 0 + elif TYPE_a == 'C': + if TYPE_b == 'H': + fss_sigma[0:8] = [-9.235812 ,-1.372683 ,-0.408433 ,0.00 ,0.00 ,1.10 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [8.104851 ,-0.936099 ,-0.626219 ,0.00 ,0.00 ,1.10 ,3.50 ,4.00 ] + fps_sigma[0:8] = [8.104851 ,-0.936099 ,-0.626219 ,0.00 ,0.00 ,1.10 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_pi[0:8] = [0,0,0,0,0,0,0,0] + Es = 0; Ep = 0; U = 0 + elif TYPE_b == 'C': + fss_sigma[0:8] = [-9.197237 ,-1.60705 ,-0.535057 ,0.00 ,0.00 ,1.40 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [8.562436 ,-0.980182 ,-0.646929 ,0.00 ,0.00 ,1.40 ,3.50 ,4.00 ] + fps_sigma[0:8] = [8.562436 ,-0.980182 ,-0.646929 ,0.00 ,0.00 ,1.40 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [6.614756 ,-0.528591 ,-0.95146 ,0.00 ,0.00 ,1.40 ,3.50 ,4.00 ] + fpp_pi[0:8] = [-3.678302 ,-1.881668 ,-0.255951 ,0.00 ,0.00 ,1.40 ,3.50 ,4.00 ] + Es = -13.7199 + Ep = -5.2541 + U = 14.240811 + elif TYPE_b == 'O': + fss_sigma[0:8] = [-13.986685 ,-1.931973 ,-0.432011 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [10.718738 ,-1.389459 ,-0.182128 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fps_sigma[0:8] = [14.194791 ,-1.37165 ,-0.248285 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [8.622023 ,-0.557144 ,-0.938551 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fpp_pi[0:8] = [-5.327397 ,-2.19016 ,-0.089303 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + Es = 0; Ep = 0; U = 0; + elif TYPE_b == 'N': + fss_sigma[0:8] = [-7.409712 ,-1.940942 ,-0.219762 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [7.501761 ,-1.211169 ,-0.373905 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + fps_sigma[0:8] = [8.697591 ,-1.26724 ,-0.178484 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [6.95460 ,-1.188456 ,-0.808043 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + fpp_pi[0:8] = [-2.921605 ,-2.203548 ,-0.409424 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + Es = 0; Ep = 0; U = 0 + elif TYPE_a == 'O': + if TYPE_b == 'H': + fss_sigma[0:8] = [-12.189103 ,-1.800097 ,-0.325933 ,0.00 ,0.00 ,1.00 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [9.518733 ,-1.333235 ,-0.39371 ,0.00 ,0.00 ,1.00 ,3.50 ,4.00 ] + fps_sigma[0:8] = [9.518733 ,-1.333235 ,-0.39371 ,0.00 ,0.00 ,1.00 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_pi[0:8] = [0,0,0,0,0,0,0,0] + Es = 0; Ep = 0; U = 0 + elif TYPE_b == 'C': + fss_sigma[0:8] = [-13.986685 ,-1.931973 ,-0.432011 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [14.194791 ,-1.37165 ,-0.248285 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fps_sigma[0:8] = [10.718738 ,-1.389459 ,-0.182128 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [8.622023 ,-0.557144 ,-0.938551 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fpp_pi[0:8] = [-5.327397 ,-2.19016 ,-0.089303 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + Es = 0; Ep = 0; U = 0 + elif TYPE_b == 'O': + fss_sigma[0:8] = [-14.387756 ,-2.244278 ,-1.645605 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + fsp_sigma[0:8] = [13.699127 ,-1.602358 ,-0.114474 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + fps_sigma[0:8] = [13.699127 ,-1.602358 ,-0.114474 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + fpp_sigma[0:8] = [9.235469 ,-1.131474 ,-0.924535 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + fpp_pi[0:8] = [ -4.526526 ,-2.487174 ,-0.201464 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + Es = -23.9377 + Ep = -9.0035 + U = 11.8761410 + elif TYPE_b == 'N': + fss_sigma[0:8] = [-9.360078 ,-1.293118 ,-0.379415 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [10.723048 ,-0.454312 ,-0.916563 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fps_sigma[0:8] = [10.309052 ,-0.981652 ,-0.828497 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [9.259131 ,-0.734112 ,-1.023762 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + fpp_pi[0:8] = [-4.532623 ,-1.999631 ,-0.286275 ,0.00 ,0.00 ,1.20 ,3.50 ,4.00 ] + Es = 0; Ep = 0; U = 0 + elif TYPE_a == 'N': + if TYPE_b == 'H': + fss_sigma[0:8] = [-12.63103 ,-1.585597 ,-0.250969 ,0.00 ,0.00 ,1.00 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [9.837852 ,-1.23485 ,-0.324283 ,0.00 ,0.00 ,1.00 ,3.50 ,4.00 ] + fps_sigma[0:8] = [9.837852 ,-1.23485 ,-0.324283 ,0.00 ,0.00 ,1.00 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_pi[0:8] = [0,0,0,0,0,0,0,0] + Es = 0; Ep = 0; U = 0 + elif TYPE_b == 'C': + fss_sigma[0:8] = [-7.409712 ,-1.940942 ,-0.219762 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + fsp_sigma[0:8] = [8.697591 ,-1.26724 ,-0.178484 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + fps_sigma[0:8] = [7.501761 ,-1.211169 ,-0.373905 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + fpp_sigma[0:8] = [6.95460 ,-1.188456 ,-0.808043 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + fpp_pi[0:8] = [-2.921605 ,-2.203548 ,-0.409424 ,0.00 ,0.00 ,1.50 ,3.50 ,4.00 ] + Es = 0; Ep = 0; U = 0 + elif TYPE_b == 'O': + fss_sigma[0:8] = [-9.360078 ,-1.293118 ,-0.379415 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + fsp_sigma[0:8] = [10.309052 ,-0.981652 ,-0.828497 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + fps_sigma[0:8] = [10.723048 ,-0.454312 ,-0.916563 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + fpp_sigma[0:8] = [9.259131 ,-0.734112 ,-1.023762 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + fpp_pi[0:8] = [-4.532623 ,-1.999631 ,-0.286275 ,0.0 ,0.0 ,1.2 ,3.5 ,4.0 ] + Es = 0; Ep = 0; U = 0 + elif TYPE_b == 'N': + fss_sigma[0:8] = [-7.165811 ,-2.348869 ,-0.541905 ,0.0 ,0.0 ,1.5 ,3.5 ,4.0 ] + fsp_sigma[0:8] = [8.212268 ,-1.499123 ,-0.52644 ,0.0 ,0.0 ,1.5 ,3.5 ,4.0 ] + fps_sigma[0:8] = [8.212268 ,-1.499123 ,-0.52644 ,0.0 ,0.0 ,1.5 ,3.5 ,4.0 ] + fpp_sigma[0:8] = [7.102331 ,-1.252366 ,-0.552533 ,0.0 ,0.0 ,1.5 ,3.5 ,4.0 ] + fpp_pi[0:8] = [-2.828938 ,-2.376886 ,-0.560898 ,0.0 ,0.0 ,1.5 ,3.5 ,4.0 ] + Es = -18.5565 + Ep = -7.0625 + U = 17.3729 + else: + Es = 0; Ep = 0; U = 0 + fss_sigma[0:8] = [0,0,0,0,0,0,0,0] + fss_sigma[0:8] = [0,0,0,0,0,0,0,0] + fsp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fps_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_sigma[0:8] = [0,0,0,0,0,0,0,0] + fpp_pi[0:8] = [0,0,0,0,0,0,0,0] + + #Maybe better to pre-calculate? + fss_sigma = ScaleTail(fss_sigma) + fsp_sigma = ScaleTail(fsp_sigma) + fps_sigma = ScaleTail(fps_sigma) + fpp_sigma = ScaleTail(fpp_sigma) + fpp_pi = ScaleTail(fpp_pi) + + return fss_sigma,fsp_sigma,fps_sigma,fpp_sigma,fpp_pi,Es,Ep,U + + +def ScaleTail(A): + if abs(A[0]) < 1e-12: + A[8:13] = 0; + else: + R1 = A[6] + RCUT = A[7] + R1SQ = R1*R1 + RMOD = R1 - A[5] + POLYNOM = RMOD*(A[1] + RMOD*(A[2] + RMOD*(A[3] + A[4]*RMOD))) + SCL_R1 = exp(POLYNOM) + DELTA = RCUT - R1 + # Now we're using a 6th order polynomial: fitted to value, first, + # and second derivatives at R1 and R_cut + A[8] = SCL_R1 + RMOD = R1 - A[5] + DPOLY = A[1] + 2*A[2]*RMOD + 3*A[3]*RMOD*RMOD + 4*A[4]*RMOD*RMOD*RMOD + A[9] = DPOLY*SCL_R1 + DDPOLY = 2*A[2] + 6*A[3]*RMOD + 12*A[4]*RMOD*RMOD + A[10] = (DPOLY*DPOLY + DDPOLY)*SCL_R1/2 + DELTA2 = DELTA*DELTA + DELTA3 = DELTA2*DELTA + DELTA4 = DELTA3*DELTA + A[11] = (-1/DELTA3)*(3*A[10]*DELTA2 + 6*A[9]*DELTA + 10*A[8]) + A[12] = (1/DELTA4)*(3*A[10]*DELTA2 + 8*A[9]*DELTA + 15*A[8]) + A[13] = (-1/(10*DELTA3))*(6*A[12]*DELTA2 + 3*A[11]*DELTA + A[10]) + diff --git a/proxies/python/hamiltonian_random.py b/proxies/python/hamiltonian_random.py new file mode 100644 index 0000000..5acc2ac --- /dev/null +++ b/proxies/python/hamiltonian_random.py @@ -0,0 +1,57 @@ +"""random number generator +This code is only used to guide implemetations and understand which are the +basic elements needed to interface with the sedacs driver. +""" + +import numpy as np +import sys +from random_numbers import RandomNumberGenerator +from coordinates import get_random_coordinates + + +## Computes a Hamiltonian based on a single "s-like" orbitals per atom. +# @author Anders Niklasson +# @brief Computes a hamiltonian \f$ H_{ij} = (x/m)\exp(-(y/n + decay_{min}) |R_{ij}|^2))\f$, based on distances +# \f$ R_{ij} \f$. \f$ x,m,y,n,decay_{min} \f$ are fixed parameters. +# +# @param ndim Size of the Hamiltonian matrix +# @param verb Verbosity. If True is passed, information is printed +# @return H 2D numpy array of Hamiltonian elements +# +def get_random_hamiltonian(coords,verb=False): + """Construct simple toy s-Hamiltonian """ + norbs = len(coords[:,0]) + eps = 1e-9; decay_min = 0.1; m = 78; + a = 3.817632; c = 0.816371; x = 1.029769; n = 13; + b = 1.927947; d = 3.386142; y = 2.135545; + ham = np.zeros((norbs,norbs)) + if(verb): print("Constructing a simple Hamiltonian for the full system") + cnt = 0 + for i in range(0,norbs): + x = (a*x+c)%m #Hamiltonian parameters + y = (b*y+d)%n + for j in range(i,norbs): + dist = np.linalg.norm(coords[i,:]-coords[j,:]) + tmp = (x/m)*np.exp(-(y/n + decay_min)*(dist**2)) + ham[i,j] = tmp + ham[j,i] = tmp + ham[i,i] = x*y + return ham + + +if __name__ == "__main__": + n = len(sys.argv) + if n == 1: + print("Give the total number of atoms/orbitals. Example:\n") + print("python hamiltonian_random.py 100\n") + sys.exit(0) + else: + nats = int(sys.argv[1]) + + verb = True + + coords = get_random_coordinates(nats) + ham = get_random_hamiltonian(coords,verb=verb) + + print("Hamiltonian:",ham) + diff --git a/proxies/python/init_proxy.py b/proxies/python/init_proxy.py new file mode 100644 index 0000000..eba6bd3 --- /dev/null +++ b/proxies/python/init_proxy.py @@ -0,0 +1,107 @@ +"""Init proxy +This code is only used to guide implemetations and understand which are the +basic elements needed to interface with the sedacs driver. +""" + +import os +import sys +from sedacs.dev.io import src_path +import scipy.linalg as sp +import numpy as np +from proxies.python.proxy_global import read_ppots, bring_ppots, print_ppots, read_tbparams, bring_tbparams +from proxies.python.proxy_global import bring_ham_list, bring_dm_list, touch_ham_list, touch_dm_list, bring_accel_lib, touch_accel_lib +from proxies.python.proxy_global import bring_cublas_handle_list, bring_stream_list, touch_cublas_handle_list, touch_stream_list +from proxies.python.proxy_global import bring_dev_list, touch_dev_list +import ctypes + +__all__ = [ + "init_proxy_proxy","init_proxy_accelerators" +] + + +## Initialize proxy code +# @brief We will read all the parameters needed for the +# guest or proxy code to run. Every guest code will need to +# set up an initialization function and save parameters that +# need to be read from file only once. Bond integral parameter, +# pair potential, etc. will be stored in memory by the guest code. +# +def init_proxy_proxy(symbols,bas_per_atom): + ... + + # We should really have this be defined in the engine or something, it's hard to follow where + # these things are intended to be happening. + + + #Some codes will have their own input file + #read_proxy_input_file() + #Read pair potentials + read_ppots("ppots.dat",symbols) # Not sure what this is but it probably isn't intended to be hardcoded. + #print_ppots() + #Read tb parameters + filename = "aosa_parameters.dat" + read_tbparams(filename, symbols, bas_per_atom) + +def init_proxy_accelerators(nparts,norbs,rank,full_accel_path): + + try: + import ctypes + gpuLib = True + arch = "nvda" + pwd = os.getcwd() + + if arch == "nvda": + print("loading nvidia...") + lib = ctypes.CDLL("/home/finkeljo/vescratch/sedacs-gpmdsp2/src/sedacs/gpu/nvda/libnvda.so") + if arch == "amd": + lib = ctypes.CDLL("/home/finkeljo/vescratch/sedacs-gpmdsp2/src/sedacs/gpu/amd/libamd.so") + + import gpuLibInterface as gpu + + except: + gpuLib = False + + #set devices based on rank + num_devices=2 #num devices per node + gpu.set_device(rank%num_devices,lib) + + touch_accel_lib(full_accel_path) + accel_lib=bring_accel_lib() + + size_of_double = 8 #bytes + size_of_float = 4 #bytes + size_of_half = 2 #bytes + matSize = norbs * norbs * size_of_double + matSize_f = norbs * norbs * size_of_float + matSize_h = norbs * norbs * size_of_half + + # initialize global list storing ham and dm device vars + touch_cublas_handle_list() + touch_stream_list() + touch_dev_list() + + cublas_handle_list=bring_cublas_handle_list() + stream_list=bring_stream_list() + dev_list=bring_dev_list() + + print("CALLING GPU DEVALLOC!!---------------------") + for i in range(0,1): + print("Allocating device mem, handles and streams ...") + cublas_handle_list.append(gpu.cublasInit(accel_lib)) + stream_list.append(gpu.set_stream(accel_lib)) + + + # if sp2 + for i in range(0,3): + print("Allocating device mem, handles and streams ...") + dev_list.append(gpu.dev_alloc(matSize, lib)) + for i in range(3,8): + print("Allocating device mem, handles and streams ...") + dev_list.append(gpu.dev_alloc(matSize_f, lib)) + for i in range(8,10): + print("Allocating device mem, handles and streams ...") + dev_list.append(gpu.dev_alloc(matSize_h, lib)) + for i in range(10,12): + print("Allocating pinned mem ...") + dev_list.append(gpu.host_alloc_pinned(matSize, lib)) + diff --git a/proxies/python/nonortho.py b/proxies/python/nonortho.py new file mode 100644 index 0000000..98aee9b --- /dev/null +++ b/proxies/python/nonortho.py @@ -0,0 +1,35 @@ +import numpy as np +import scipy.linalg as sp + +## Inverse overlap factorization +# @brief Constructs inverse overlap factors given the overlap matrix +# @param over Overlap matrix +# @param method If a particular needs to be used +# @param accel If an accelerater (hardwar/library/programing model) is used. +# @verb Verbosity switch +## +def get_xmat(over,method="Diag",accel="No",verb=False): + + if(verb): + print("In get_xmat ...") + + hdim = len(over[0,:]) + if(method == "Diag" and accel == "No"): + e,v = sp.eigh(over) + s = 1./np.sqrt(e) + zmat = np.zeros((hdim,hdim)) + for i in range(hdim): + zmat[i, :] = s[i] * v[:, i] + zmat = np.matmul(v, zmat) + elif method == "Cholesky": + pass + else: + print("ERROR: Method not implemented") + exit(0) + + if verb: + print("\nZmat Matrix") + print(zmat) + + return zmat + diff --git a/proxies/python/proxy_global.py b/proxies/python/proxy_global.py new file mode 100644 index 0000000..0201e56 --- /dev/null +++ b/proxies/python/proxy_global.py @@ -0,0 +1,106 @@ +#Set some global variables such +#as the parameters that are needed +#throughout the code + +import numpy as np +from proxies.python.hamiltonian_elements import AOSA_Parameter +import ctypes + +ppots = None +tbparams = None +d_ham_list = None +d_dm_list = None + +def read_ppots(filename,symbols): + myfile = open(filename,"r") + global ppots + ppots = np.zeros((len(symbols),len(symbols),4)) + + for lines in myfile: + info = lines.split() + if(len(info) > 1): + pairI = info[0] + pairJ = info[1] + for i in range(len(symbols)): + for j in range(len(symbols)): + if(symbols[i] == pairI and symbols[j] == pairJ): + for k in range(2,len(info)): + ppots[i,j,k-2] = float(info[k]) + ppots[j,i,:] = ppots[i,j,:] + + + +def print_ppots(): + print(ppots) + +def bring_ppots(): + return ppots + +def bring_cublas_handle_list(): + return cublas_handle_list + +def bring_stream_list(): + return stream_list + +def bring_ham_list(): + return d_ham_list + +def bring_dm_list(): + return d_dm_list + +def bring_dev_list(): + return dev_list + +def touch_cublas_handle_list(): + global cublas_handle_list + cublas_handle_list=[] + +def touch_stream_list(): + global stream_list + stream_list=[] + +def touch_ham_list(): + global d_ham_list + d_ham_list=[] + +def touch_dm_list(): + global d_dm_list + d_dm_list=[] + +def touch_dev_list(): + global dev_list + dev_list=[] + +def touch_accel_lib(full_path): + global accel_lib + #lib = ctypes.CDLL("/home/finkeljo/sedacs-gpmdsp2/src/sedacs/gpu/nvda/libnvda.so") + accel_lib = ctypes.CDLL(str(full_path)+"/libnvda.so") + +def bring_accel_lib(): + return accel_lib + +def read_tbparams(filename,symbols,bas_per_atom): + + ntypes = len(symbols) + + global tbparams + + tbparams = [None]*ntypes + sOrbTypes = ["s"] + spOrbTypes = ["s","px","py","pz"] + + for i in range(ntypes): + sublist = [None]*bas_per_atom[i] + for j in range(bas_per_atom[i]): + if(bas_per_atom[i] == 1): + orbTypes = sOrbTypes + elif(bas_per_atom[i] == 4): + orbTypes = spOrbTypes + param = AOSA_Parameter(symbols[i],orbTypes[j],filename) + sublist[j] = param + tbparams[i] = sublist + + +def bring_tbparams(): + return tbparams + diff --git a/proxies/python/random_numbers.py b/proxies/python/random_numbers.py new file mode 100644 index 0000000..487b3b3 --- /dev/null +++ b/proxies/python/random_numbers.py @@ -0,0 +1,69 @@ +"""random number generator +This code is only used to guide implemetations and understand which are the +basic elements needed to interface with the sedacs driver. +""" + +import os +import sys + +__all__ = [ + "RandomNumberGenerator", +] + + +## Simple random number generator +# This is important in order to compare across codes +# written in different languages. +# +# To initialize: +# \verbatim +# myRand = rand(123) +# \endverbatim +# where the argument of rand is the seed. +# +# To get a random number between "low" and "high": +# \verbatim +# rnd = myRand.get_rand(low,high) +# \endverbatim +# +class RandomNumberGenerator: + """To generate random numbers.""" + + def __init__(self, seed): + self.a = 321 + self.b = 231 + self.c = 13 + self.seed = seed + self.status = seed * 1000 + + def generate(self, low, high): + """Get a random real number in between low and high.""" + w = high - low + place = self.a * self.status + place = int(place / self.b) + rand = (place % self.c) / self.c + place = int(rand * 1000000) + self.status = place + rand = low + w * rand + + return rand + + +if __name__ == "__main__": + n = len(sys.argv) + if n == 1: + print("Give the total number of vector elements. Example:\n") + print("python random.py 100\n") + sys.exit(0) + else: + nel = int(sys.argv[1]) + + verb = True + + rnd = RandomNumberGenerator(1234) + + for i in range(nel): + print(i,rnd.generate(0,1)) + + + diff --git a/proxies/vars b/proxies/vars new file mode 100644 index 0000000..51759b6 --- /dev/null +++ b/proxies/vars @@ -0,0 +1,11 @@ +#!/bin/bash +THIS_PATH=`pwd` +MOD_PATH=$THIS_PATH/../mods +LATTE_PATH=$THIS_PATH/../latte +PROXYA_PATH=$THIS_PATH/python_proxy +export PYTHONPATH=$PYTHONPATH:$MOD_PATH:$LATTE_PATH:$PROXYA_PATH +export PYTHONWARNINGS="ignore:Unverified HTTPS request" + +GPU_PATH=$THIS_PATH/../src/sedacs/gpu +export PYTHONPATH=$PYTHONPATH:$GPU_PATH + From e5f764a6e0cf7862cd72c67943c192e1cddf0b12 Mon Sep 17 00:00:00 2001 From: peterli3819 Date: Thu, 1 May 2025 14:35:15 -0600 Subject: [PATCH 3/6] fix proxy code compatibility --- src/sedacs/driver/init.py | 6 +++-- src/sedacs/interface_modules.py | 45 ++++++++++++++++++++++++++++++--- src/sedacs/sdc_hamiltonian.py | 4 +-- src/sedacs/system.py | 16 ++++++++++++ 4 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/sedacs/driver/init.py b/src/sedacs/driver/init.py index fe9b852..0bd4aba 100644 --- a/src/sedacs/driver/init.py +++ b/src/sedacs/driver/init.py @@ -117,6 +117,7 @@ def init(args): sy.latticeVectors, sy.symbols, sy.types, sy.coords = read_coords_file(sdc.coordsFileName, lib="None", verb=True) sy.nats = len(sy.coords[:, 0]) sy.vels = np.zeros((sy.nats, 3)) + sy.hubbard_u = np.zeros(sy.nats) sy.charges = np.zeros(sy.nats) # Get hindex (the orbital index for each atom in the system) @@ -208,8 +209,9 @@ def init(args): fullGraph = np.zeros((sy.nats, sdc.maxDeg + 1), dtype=int) fullGraph[:, :] = graphNL[:, :] - #Initialize proxy/guest code -# init_proxy(sy.symbols,sy.orbs) + if "Proxy" in eng.name: + #Initialize proxy/guest code + init_proxy(sy.symbols,sy.orbs) eng.up = True return sdc, eng, comm, rank, numranks, sy, hindex, fullGraph, nl, nlTrX, nlTrY, nlTrZ diff --git a/src/sedacs/interface_modules.py b/src/sedacs/interface_modules.py index f8c4d13..2dd051d 100644 --- a/src/sedacs/interface_modules.py +++ b/src/sedacs/interface_modules.py @@ -37,13 +37,13 @@ try: from proxies.python.hamiltonian import get_hamiltonian_proxy from proxies.python.density_matrix import get_density_matrix_proxy - from proxies.python.evals_dvals import get_evals_dvals_proxy + #from proxies.python.evals_dvals import get_evals_dvals_proxy from proxies.python.init_proxy import init_proxy_proxy from proxies.python.hamiltonian import build_coul_ham_proxy except Exception as e: pythlib = None - #raise e + raise e __all__ = [ @@ -174,6 +174,8 @@ def get_hamiltonian_module( The non-SCF Hamiltonian matrix. overlap: 2D numpy array, dtype: float, optional The overlap matrix, if requested. + zmat: 2D numpy array, dtype: float, optional + The congruence transform comes with overlap matrix, if requested. """ if eng.name == "ProxyAPython": if get_overlap: @@ -184,6 +186,7 @@ def get_hamiltonian_module( hamiltonian = get_hamiltonian_proxy( coords, types, symbols, get_overlap=get_overlap, verb=verb ) + zmat = None elif eng.name == "ProxyAFortran": nats = len(coords[:, 0]) @@ -257,6 +260,8 @@ def get_hamiltonian_module( forcesFlat_out = np.zeros(3 * nats) # Vectorized forces hamFlat_out = np.zeros(norbs * norbs) # Vectorized hamiltonian overFlat_out = np.zeros(norbs * norbs) # Vectorized overlap + zmatFlat_out = np.zeros(norbs * norbs) # Vectorized congruence transform + evectsFlat_out = np.zeros(norbs * norbs) # Vectorized eigenvectors dmFlat_out = np.zeros(norbs * norbs) # Vectorized density matrix evalsFlat_out = np.zeros(norbs) # We call this one Flat just for consistency dvalsFlat_out = np.zeros(norbs) # Same here @@ -296,6 +301,8 @@ def get_hamiltonian_module( # Getting pointers to the output arrays ham_ptr = hamFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) over_ptr = overFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) + zmat_ptr = zmatFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) + evects_ptr = evectsFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) dm_ptr = dmFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) charges_ptr = chargesFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) evals_ptr = evalsFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) @@ -321,6 +328,8 @@ def get_hamiltonian_module( atomicNumbers_ptr, ham_ptr, over_ptr, + zmat_ptr, + evects_ptr, dm_ptr, charges_ptr, evals_ptr, @@ -335,16 +344,18 @@ def get_hamiltonian_module( # Initializing 2D numpy arrays for the hamiltonian and overlap matrices hamiltonian = np.zeros((norbs, norbs)) overlap = np.zeros((norbs, norbs)) + zmat = np.zeros((norbs, norbs)) # Filling the hamiltonian and overlap matrices with the flattened output arrays from the Fortran function for i in range(norbs): hamiltonian[:, i] = hamFlat_out[norbs * i : norbs + norbs * i] overlap[:, i] = overFlat_out[norbs * i : norbs + norbs * i] + zmat[:, i] = zmatFlat_out[norbs * i : norbs + norbs * i] else: error_at("get_hamiltonian_module", "No specific engine type defined") if get_overlap: - return hamiltonian, overlap + return hamiltonian, overlap, zmat else: return hamiltonian @@ -407,6 +418,8 @@ def get_evals_dvals_modules( Returns ------- + evects: 2D numpy array, dtype: float + The eigenvectors of the input hamiltonian matrix. evals: 1D numpy array, dtype: float The eigenvalues of the input hamiltonian matrix, if requested. dvals: 1D numpy array, dtype: float @@ -459,6 +472,8 @@ def get_evals_dvals_modules( forcesFlat_out = np.zeros(3 * nats) # Vectorized forces hamFlat_out = np.zeros(norbs * norbs) # Vectorized hamiltonian overFlat_out = np.zeros(norbs * norbs) # Vectorized overlap + zmatFlat_out = np.zeros(norbs * norbs) # Vectorized congruence transform + evectsFlat_out = np.zeros(norbs * norbs) # Vectorized eigenvectors dmFlat_out = np.zeros(norbs * norbs) # Vectorized density matrix evalsFlat_out = np.zeros(norbs) # We call this one Flat just for consistency dvalsFlat_out = np.zeros(norbs) # Same here @@ -496,6 +511,8 @@ def get_evals_dvals_modules( # Getting pointers to the output arrays ham_ptr = hamFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) over_ptr = overFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) + zmat_ptr = zmatFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) + evects_ptr = evectsFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) dm_ptr = dmFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) charges_ptr = chargesFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) evals_ptr = evalsFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) @@ -522,6 +539,8 @@ def get_evals_dvals_modules( atomicNumbers_ptr, ham_ptr, over_ptr, + zmat_ptr, + evects_ptr, dm_ptr, charges_ptr, evals_ptr, @@ -539,8 +558,14 @@ def get_evals_dvals_modules( # Filling the eigenvalues and dvals arrays with the output arrays from the Fortran function evals[:] = evalsFlat_out[:] dvals[:] = dvalsFlat_out[:] + # Initializing 2D numpy arrays for the eigenvectors + evects = np.zeros((norbs, norbs)) + # Filling the hamiltonian and overlap matrices with the flattened output arrays from the Fortran function + for i in range(norbs): + evects[:, i] = evectsFlat_out[norbs * i : norbs + norbs * i] + - return evals, dvals + return evects, evals, dvals def get_density_matrix_modules( @@ -705,6 +730,8 @@ def get_density_matrix_modules( forcesFlat_out = np.zeros(3 * nats) # Vectorized forces hamFlat_out = np.zeros(norbs * norbs) # Vectorized hamiltonian overFlat_out = np.zeros(norbs * norbs) # Vectorized overlap + zmatFlat_out = np.zeros(norbs * norbs) # Vectorized congruence transform + evectsFlat_out = np.zeros(norbs * norbs) # Vectorized eigenvectors dmFlat_out = np.zeros(norbs * norbs) # Vectorized density matrix evalsFlat_out = np.zeros(norbs) # We call this one Flat just for consistency dvalsFlat_out = np.zeros(norbs) # Same here @@ -742,6 +769,8 @@ def get_density_matrix_modules( # Getting pointers to the output arrays ham_ptr = hamFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) over_ptr = overFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) + zmat_ptr = zmatFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) + evects_ptr = evectsFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) dm_ptr = dmFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) charges_ptr = chargesFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) evals_ptr = evalsFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) @@ -768,6 +797,8 @@ def get_density_matrix_modules( atomicNumbers_ptr, ham_ptr, over_ptr, + zmat_ptr, + evects_ptr, dm_ptr, charges_ptr, evals_ptr, @@ -931,6 +962,8 @@ def get_energy_forces_modules( forcesFlat_out = np.zeros(3 * nats) # Vectorized forces hamFlat_out = np.zeros(norbs * norbs) # Vectorized hamiltonian overFlat_out = np.zeros(norbs * norbs) # Vectorized overlap + zmatFlat_out = np.zeros(norbs * norbs) # Vectorized congruence transform + evectsFlat_out = np.zeros(norbs * norbs) # Vectorized eigenvectors dmFlat_out = np.zeros(norbs * norbs) # Vectorized density matrix evalsFlat_out = np.zeros(norbs) # We call this one Flat just for consistency dvalsFlat_out = np.zeros(norbs) # Same here @@ -968,6 +1001,8 @@ def get_energy_forces_modules( # Getting pointers to the output arrays ham_ptr = hamFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) over_ptr = overFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) + zmat_ptr = zmatFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) + evects_ptr = evectsFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) dm_ptr = dmFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) charges_ptr = chargesFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) evals_ptr = evalsFlat_out.ctypes.data_as(ctypes.POINTER(ctypes.c_double)) @@ -994,6 +1029,8 @@ def get_energy_forces_modules( atomicNumbers_ptr, ham_ptr, over_ptr, + zmat_ptr, + evects_ptr, dm_ptr, charges_ptr, evals_ptr, diff --git a/src/sedacs/sdc_hamiltonian.py b/src/sedacs/sdc_hamiltonian.py index a707a7d..2521773 100644 --- a/src/sedacs/sdc_hamiltonian.py +++ b/src/sedacs/sdc_hamiltonian.py @@ -70,7 +70,7 @@ def get_hamiltonian( elif eng.interface == "Module": # We will call proxyA directly as it will be loaded as a module. if get_overlap: - ham, overlap = get_hamiltonian_module( + ham, overlap, zmat = get_hamiltonian_module( eng, partIndex, nparts, @@ -84,7 +84,7 @@ def get_hamiltonian( newsystem=newsystem, keepmem=keepmem, ) - return ham, overlap + return ham, overlap, zmat else: return get_hamiltonian_module( eng, diff --git a/src/sedacs/system.py b/src/sedacs/system.py index 822f4c7..cfa1604 100644 --- a/src/sedacs/system.py +++ b/src/sedacs/system.py @@ -121,6 +121,8 @@ def __init__(self, nats=1): self.types = np.zeros(self.nats, dtype=int) ## Coordinates for each atom, e.g., z-coordinate of the frist atom is coords[0,2] self.coords = np.zeros((self.nats, 3), dtype=float) + ## Hubbard U for each atom + self.hubbard_u = np.zeros((self.nats), dtype=float) ## Charged (orbital base population) for each atom self.charges = np.zeros((self.nats), dtype=float) ## Coordinates for each atom, e.g., z-coordinate of the frist atom is coords[0,2] @@ -144,6 +146,20 @@ def __init__(self, nats=1): self.resNames = None ## Residue/molecule id self.resIds = None + ## List of subsystems + self.subSy_list = None + ## Kernel preconditioner + self.ker = None + ## Hamiltonian matrix + self.ham = None + ## Overlap matrix + self.over = None + ## Congruence transformation + self.zmat = None + ## Eigenvectors matrix + self.evects = None + ## Eigenvalues + self.evals = None def extract_types_and_symbols(self,symbols_list_for_all_atoms): """ From 1feb7cf0d239e237b9ce860e43e10e33331a3349 Mon Sep 17 00:00:00 2001 From: peterli3819 Date: Thu, 1 May 2025 15:01:05 -0600 Subject: [PATCH 4/6] adding multiply_graphs function in src/sedacs/graph.py --- src/sedacs/graph.py | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/sedacs/graph.py b/src/sedacs/graph.py index 1416c1e..b0973e5 100644 --- a/src/sedacs/graph.py +++ b/src/sedacs/graph.py @@ -81,7 +81,7 @@ def print_graph(graph): nodesList = [] for k in range(1, graph[i, 0] + 1): if graph[i, k] != -1: - nodesList.append(graph[i, k]) + nodesList.append(int(graph[i, k])) print(i, "(", graph[i, 0], ")", "-", nodesList) @@ -302,7 +302,8 @@ def collect_graph_from_rho(graph, rho, thresh, nnodes, maxDeg, indicesCoreHalos, for j in range(nch): jj = indicesCoreHalos[j] for oj in range(hindex[jj], hindex[jj + 1]): - weights[jj] = weights[jj] + abs(rho[ki, kj]) + if abs(rho[ki, kj]) >= thresh: # Elementwise truncation test Anders + weights[jj] = weights[jj] + abs(rho[ki, kj]) kj = kj + 1 ki = ki + 1 @@ -409,29 +410,38 @@ def add_mult_graphs(graphs): # @param graphA Initial adjacency # @param graphB Initial adjacency # @return graphC Multiplication result -def multiply_graphs(): +def multiply_graphs(graphA, graphB): if len(graphA[:, 0]) != len(graphB[:, 0]): print("!!!ERROR: Graphs have different number of nodes") else: nnodes = len(graphA[:, 0]) maxDeg = len(graphA[0, :]) + vectC = np.zeros((nnodes), dtype=bool) + graphC = np.zeros((nnodes, maxDeg), dtype=int) for i in range(nnodes): - myVect[:] = False - for j in range(1, graphA[i, 0]): + vectC[:] = False + for j in range(1, graphB[i, 0] + 1): + myK = graphB[i, j] + vectC[myK] = True + for j in range(1, graphA[i, 0] + 1): myK = graphA[i, j] # All neighbors of i by A - for k in range(1, graphB[myK, 0]): + vectC[myK] = True + for k in range(1, graphB[myK, 0] + 1): myJ = graphB[myK, k] # All neighbors of myK by B if i != myJ: + # print(i, myJ) vectC[myJ] = True k = 0 - for j in range(1, nnodes): + for j in range(nnodes): if vectC[j]: k = k + 1 graphC[i, k] = j graphC[i, 0] = k + return graphC + # Get a small graph (>-<) # @brief This will construct a small graph for testing purposes. @@ -616,4 +626,13 @@ def convert_to_adjacency_matrix(graph, graphType='sedacs'): return adj +def convert_to_graph(adj, maxDeg): + nNodes = adj.shape[0] + graph = np.zeros((nNodes, maxDeg), dtype = int) + for i in range(nNodes): + connections = adj[i,:].nonzero()[0] + graph[i,1:1+len(connections)] = connections[0:len(connections)] + graph[i,0] = len(connections) + + return graph From 7ca52b78a6abbfb747a896ffe60ae35e5bea658d Mon Sep 17 00:00:00 2001 From: peterli3819 Date: Thu, 1 May 2025 16:11:39 -0600 Subject: [PATCH 5/6] modify src/sedacs/coulombic.py --- src/sedacs/coulombic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sedacs/coulombic.py b/src/sedacs/coulombic.py index 3cef301..49179bb 100644 --- a/src/sedacs/coulombic.py +++ b/src/sedacs/coulombic.py @@ -103,6 +103,7 @@ def get_PME_coulvs( atomtypes, lattice_vecs, calculate_forces=0, + device="cuda", ): """ Get periodic Coulombic potentials using the Particle Mesh Ewald method @@ -133,7 +134,7 @@ def get_PME_coulvs( """ np_dtype = np.float64 dtype = torch.float64 - device = "cuda" + # NOTE: cutoff <= 0.5 * min(box lengths) # so if box lengths are [10.0, 10.0, 10.0], cutoff shuold be at most 5.0. # because of the minumum image convention. From 71c71db93c910c1887ba1277259ef5228de05ac4 Mon Sep 17 00:00:00 2001 From: peterli3819 Date: Thu, 1 May 2025 16:16:49 -0600 Subject: [PATCH 6/6] minor fixes --- src/sedacs/charges.py | 2 +- src/sedacs/chemical_potential.py | 12 ++++++----- src/sedacs/mixer.py | 4 ++-- src/sedacs/mpi.py | 37 ++++++++++++++++++++++++++++++++ src/sedacs/sdc_evals_dvals.py | 4 ++-- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/sedacs/charges.py b/src/sedacs/charges.py index edca84f..47f4d89 100644 --- a/src/sedacs/charges.py +++ b/src/sedacs/charges.py @@ -100,7 +100,7 @@ def collect_charges(chargesOnRank, charges, part, nats, verb=False): Returns ------- - 1D numpy array + chargesOnRank : 1D numpy array Returns the same vector chargesOnRank with the added charges of the part """ diff --git a/src/sedacs/chemical_potential.py b/src/sedacs/chemical_potential.py index c64a4c4..05ed723 100644 --- a/src/sedacs/chemical_potential.py +++ b/src/sedacs/chemical_potential.py @@ -55,8 +55,10 @@ def get_mu(mu0, evals, etemp, nocc, dvals=None, kB=8.61739e-5, verb=False): nmax = 30 tol = 1.0E-10 - #HOMO = evals[int(nocc)] - #LUMO = evals[int(nocc) + 1] + #HOMO = evals[int(nocc) - 1] + #LUMO = evals[int(nocc)] + #with open("energygap.dat", "a") as f: + # f.write(f"{HOMO} {LUMO}\n") #mu = 0.5*(LUMO + HOMO) #mu = 0.5 * (np.min(evals) + np.max(evals)) #mu = np.min(evals) @@ -67,13 +69,13 @@ def get_mu(mu0, evals, etemp, nocc, dvals=None, kB=8.61739e-5, verb=False): dvals = np.ones((norbs)) for i in range(nmax+1): fermi = fermi_dirac(mu, evals, etemp) - occ = np.sum([fermi[i]*dvals[i] for i in range(norbs)]) + occ = np.sum([fermi[j]*dvals[j] for j in range(norbs)]) occErr = abs(occ - nocc) if abs(occErr) < tol: break dFermiDmu = (1/(kB*etemp))*fermi*(1.0-fermi)*dvals occ_prime = np.sum(dFermiDmu[:norbs]*dvals[:norbs]) - mu = mu + a*(nocc - occ)/occ_prime + mu = mu + a*(nocc - occ)/(occ_prime + 1.0E-3) if(abs(mu) > 1.0E10): print('WARNING: Newton-Raphson did not converge (will try bisection) Occupation error = ', occErr) notConverged = True @@ -85,7 +87,7 @@ def get_mu(mu0, evals, etemp, nocc, dvals=None, kB=8.61739e-5, verb=False): notConverged = True if(notConverged): - etemp = 10000 + #etemp = 10000 muMin = np.min(evals) muMax = np.max(evals) mu = muMin diff --git a/src/sedacs/mixer.py b/src/sedacs/mixer.py index d019f07..d6e1a52 100644 --- a/src/sedacs/mixer.py +++ b/src/sedacs/mixer.py @@ -172,7 +172,7 @@ def diis_mix(charges: ArrayLike, chargesAux = (1.0 - mixCoeff)*chargesNewIn + mixCoeff*chargesNewOut - scfError = np.linalg.norm(charges -chargesOld) + scfError = np.linalg.norm(charges - chargesOld) / np.sqrt(len(charges)) if(verb): print("SCF error =", scfError) @@ -219,7 +219,7 @@ def linear_mix(mixCoeff: float, charges = mixCoeff*charges + (1-mixCoeff)*chargesOld # Compute the SCF error. - scfError = np.linalg.norm(charges -chargesOld) + scfError = np.linalg.norm(charges -chargesOld) / np.sqrt(len(charges)) # Update the old charges. chargesOld = charges diff --git a/src/sedacs/mpi.py b/src/sedacs/mpi.py index 40138c1..78df0e4 100644 --- a/src/sedacs/mpi.py +++ b/src/sedacs/mpi.py @@ -240,6 +240,43 @@ def collect_and_sum_vectors_float(vectOnRank: ArrayLike, return fullVect +def collect_and_sum_vectors_int(vectOnRank: ArrayLike, + rank: int, + numranks: int, + comm: MPI.Comm) -> ArrayLike: + """ + Collect and sum vectors from all ranks. + + Parameters + ---------- + vectOnRank : ArrayLike + The vector to be collected and summed. + rank : int + The current rank number. + numranks : int + The number of execution ranks. + comm : MPI.Comm + The MPI communicator. + + Returns + ------- + fullVect : ArrayLike + The full vector. + """ + + if not mpiLib: + + raise ImportError("ERROR: Consider installing mpi4py") + + nDim = len(vectOnRank) + + fullVect = np.zeros(nDim, dtype=int) + + comm.Allreduce(vectOnRank,fullVect,op=MPI.SUM) + + return fullVect + + def collect_and_concatenate_vectors(vectOnRank, comm) -> ArrayLike: """ Collect and concatenate vectors from all ranks. diff --git a/src/sedacs/sdc_evals_dvals.py b/src/sedacs/sdc_evals_dvals.py index 4e7f561..879cccc 100644 --- a/src/sedacs/sdc_evals_dvals.py +++ b/src/sedacs/sdc_evals_dvals.py @@ -78,7 +78,7 @@ def get_evals_dvals( # Tight interface using modules or an external code compiled as a library elif eng.interface == "Module": # We will call proxyA directly as it will be loaded as a module. - evals, dvals = get_evals_dvals_modules( + evects, evals, dvals = get_evals_dvals_modules( eng, partIndex, nparts, @@ -99,4 +99,4 @@ def get_evals_dvals( "ERROR!!!: Interface type not recognized. Use any of the following: Module,File,Socket,MDI" ) - return evals, dvals + return evects, evals, dvals