├── .gitignore ├── LICENSE ├── README.md └── VASP ├── .gitignore ├── Check_convergence ├── dEnergy.sh └── dForce.sh ├── README.md ├── cell_tool.py ├── chgcent.py ├── chgcent_cube.py ├── chgdiff.py ├── impose_sym.py ├── kp_gen.py ├── murn.f ├── p4vmod.py ├── pp_gen.py ├── spincar.py ├── vasp_clean.py ├── vaspwfc ├── plotwfc ├── vasp_constant.py └── vaspwfc.py ├── view_atoms.py └── vtotav.py /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore generated html files, 2 | #UNK* 3 | #WAVECAR 4 | #CHGCAR 5 | **/.DS_Store 6 | not_ready 7 | # except foo.html which is maintained by hand 8 | #!foo.html 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tools 2 | 3 | Post processing tools for DFT codes that I use for convience. 4 | -------------------------------------------------------------------------------- /VASP/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /VASP/Check_convergence/dEnergy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #edit by lipai@USTC 3 | #plot energies of structure in optimization 4 | awk '/E0/{if ( i<=5 ) i++;else print $0 }' OSZICAR >temp.e 5 | gnuplot <=fix) print $1,$2,$3,sqrt($4*$4+$5*$5+$6*$6i); 10 | else if($1=="total") print $0 11 | }' OUTCAR >temp.f 12 | awk '{ 13 | if($1=="total") {print ++i,a;a=0} 14 | else {if(a<$4) a=$4} 15 | }' temp.f >force.conv 16 | #sed -i '1,9d' force.conv 17 | #rm temp.f 18 | tail -100 force.conv >temp.f 19 | #get dist from XDATCAR 20 | touch p1.conv p2.conv; 21 | touch dist.conv 22 | Num=`awk 'NR==7{for(i=1;i<=NF;i++) a=$i+a;}END{print a}' XDATCAR` 23 | Lnum=`wc XDATCAR|awk '{print $1}'` 24 | ((n=(Lnum-7)/(Num+1))) 25 | head -7 XDATCAR >p1.conv 26 | awk -v num="$Num" 'NR==9,NR==(num+1)+7{print $0}' XDATCAR >>p1.conv 27 | for((i=1;ip2.conv 30 | ((n1=9+(Num+1)*i)) 31 | ((n2=(i+1)*(Num+1)+7)) 32 | sed -n ''$n1','$n2'p' XDATCAR >>p2.conv 33 | echo -e $i"\t"`dist.pl p1.conv p2.conv ` >>dist.conv 34 | done 35 | #plot 36 | gnuplot <= 1: 31 | print("\n** ERROR: Must specify name of at least two files on command line.") 32 | print("eg. chgdiff.py CHGCAR1 CHGCAR2 [CHGCAR3 ...]") 33 | print("The reference density is taken from the first filename.") 34 | print("The densities in the files after this will be subtracted from the reference.") 35 | sys.exit(0) 36 | 37 | # Check that files exist 38 | for name in prm.CHGCAR: 39 | if not os.path.isfile(name): 40 | print("\n** ERROR: Input file %s was not found." % name) 41 | sys.exit(0) 42 | 43 | starttime = time.time() 44 | print("Starting calculation at",end='') 45 | print(time.strftime("%H:%M:%S on %a %d %b %Y \n")) 46 | 47 | 48 | 49 | # Read information from command line 50 | # First specify location of CHGCAR file with reference density 51 | CHGCARfile1 = sys.argv[1].lstrip() 52 | 53 | # Open geometry and density class objects 54 | #----------------------------------------- 55 | print("Reading data from file %s ..." % CHGCARfile1, end='') 56 | sys.stdout.flush() 57 | vasp_charge1 = VaspChargeDensity(filename = CHGCARfile1) 58 | chg1 = vasp_charge1.chg[-1] 59 | atoms1 = vasp_charge1.atoms[-1] 60 | del vasp_charge1 61 | print("done.") 62 | 63 | chgdiff=chg1 64 | for CHGCARfile2 in sys.argv[2:]: 65 | CHGCARfile2 = CHGCARfile2.strip() 66 | print("Reading data from file %s ..." % CHGCARfile2, end='') 67 | sys.stdout.flush() 68 | vasp_charge2 = VaspChargeDensity(filename = CHGCARfile2) 69 | chg2 = vasp_charge2.chg[-1] 70 | del vasp_charge2 71 | print("done.") 72 | 73 | # Make sure that the second data set is on the same grid 74 | #-------------------------------------------------------- 75 | if chg2.shape != chg1.shape: 76 | print("\n**ERROR: Two sets of data are not on the same grid.") 77 | print("Data from file %s on %dx%dx%d grid." % (CHGCARfile1,chg1.shape[0],chg1.shape[1],chg1.shape[2])) 78 | print("Data from file %s on %dx%dx%d grid.\n" % (CHGCARfile2,chg2.shape[0],chg2.shape[1],chg2.shape[2])) 79 | sys.exit(0) 80 | else: 81 | print("Subtracting %s from file %s ..." % (CHGCARfile2, CHGCARfile1), end='') 82 | sys.stdout.flush() 83 | 84 | # Take difference 85 | #----------------- 86 | chgdiff=chgdiff-chg2 87 | print("done.") 88 | 89 | 90 | vasp_charge_diff = VaspChargeDensity(filename=None) 91 | vasp_charge_diff.atoms=[atoms1,] 92 | vasp_charge_diff.chg=[chgdiff,] 93 | 94 | # Print out charge density 95 | #-------------------------- 96 | # Check whether CHGDIFF exists 97 | if os.path.isfile("./CHGDIFF.vasp"): 98 | print("\n**WARNING: A file called CHGDIFF already exists in this directory.") 99 | if float(sys.version.split()[0][:3]) < 3.0: 100 | yesno=raw_input("Type y to continue and overwrite it, any other key to stop\n") 101 | else: 102 | yesno=input("Type y to continue and overwrite it, any other key to stop\n") 103 | if yesno!="y": 104 | sys.exit(0) 105 | 106 | 107 | print("Writing density difference data to file CHGDIFF ...", end='') 108 | sys.stdout.flush() 109 | vasp_charge_diff.write(filename="CHGDIFF.vasp",format="chgcar") 110 | 111 | if float(sys.version.split()[0][:3]) < 3.0: 112 | # adding atomic species 113 | fin = [atoms1.get_chemical_symbols()[0]] 114 | for i in range(len(atoms1.get_chemical_symbols())): 115 | if i == len(atoms1.get_chemical_symbols())-1: break 116 | if atoms1.get_chemical_symbols()[i] != atoms1.get_chemical_symbols()[i+1]: 117 | fin.append(atoms1.get_chemical_symbols()[i+1]) 118 | 119 | for chgfiles in ['CHGDIFF.vasp']: 120 | f = open(chgfiles, "r") 121 | contents = f.readlines() 122 | f.close() 123 | 124 | contents.insert(5, ' '.join(fin)+'\n') 125 | 126 | f = open(chgfiles, "w") 127 | contents = "".join(contents) 128 | f.write(contents) 129 | f.close() 130 | 131 | print("done.") 132 | 133 | endtime = time.time() 134 | runtime = endtime-starttime 135 | print("\nEnd of calculation.") 136 | print("Program was running for %.2f seconds." % runtime) 137 | -------------------------------------------------------------------------------- /VASP/impose_sym.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A script to find the the symmetry of unitcell and return refined structures. 4 | 5 | Depends on ase and spglib 6 | """ 7 | 8 | from __future__ import print_function 9 | import argparse 10 | import spglib 11 | from ase.io import read, write 12 | from ase import Atoms 13 | from ase.visualize import view 14 | import numpy as np 15 | import os 16 | import sys 17 | import datetime 18 | import time 19 | 20 | # is digit? function 21 | def is_number(s): 22 | try: 23 | float(s) 24 | return True 25 | except ValueError: 26 | pass 27 | try: 28 | import unicodedata 29 | unicodedata.numeric(s) 30 | return True 31 | except (TypeError, ValueError): 32 | pass 33 | return False 34 | 35 | # Command line praser 36 | #---------------------------- 37 | # Do we want to convert the final structure into use primitive cell? 38 | parser = argparse.ArgumentParser(description='A script to find the the symmetry of unitcell and return refined structures.') 39 | parser.add_argument('--no_impose_sym', action="store_true", default=False, dest='no_ideal', 40 | help='Do not impose symmetry (do not change atomic position to ideal). (Default=False)') 41 | parser.add_argument('--no_primitive', action="store_false", default=True, dest='to_primitive', 42 | help='Do not change cell to primitive cell, if not set, cell will be primitive. (Default=False)') 43 | parser.add_argument('-v','--visualize', action="store_true", default=False, dest="visualize", 44 | help='Use ASE-GUI to visualize structure (Default=False)') 45 | parser.add_argument('-s','--sym_tol', action="store", default=float(0.01), dest="sym_tol", 46 | help='symmetry tolerance for finding symmetry (Default=1E-5)') 47 | parser.add_argument('-c','--POSCAR', action="store", default=str('POSCAR'), dest="POSCAR", 48 | help='input file name (Default=POSCAR)') 49 | prm = parser.parse_args() 50 | 51 | # Starting 52 | #---------------------------- 53 | starttime = time.time() 54 | print("Starting calculation at", end='') 55 | print(time.strftime("%H:%M:%S on %a %d %b %Y")) 56 | 57 | # check input 58 | if not os.path.isfile(prm.POSCAR): 59 | print("\n** ERROR: Initial position file %s was not found." % prm.POSCAR) 60 | sys.exit(0) 61 | 62 | if not is_number(prm.sym_tol): 63 | print("\n** ERROR: symmetry tolerance shoule be a number.") 64 | sys.exit(0) 65 | 66 | # Read information from command line 67 | # First specify location of POSCAR 68 | i_POSCAR=prm.POSCAR.lstrip() 69 | 70 | print("\nPosition file name: %s " % i_POSCAR) 71 | print("Symmetry tolerance: %s" % prm.sym_tol) 72 | 73 | # get cell informations 74 | #---------------------------- 75 | initial_pos = read(i_POSCAR) 76 | lattice = initial_pos.get_cell() 77 | positions = initial_pos.get_scaled_positions() 78 | numbers = initial_pos.get_atomic_numbers() 79 | # Magnetic moments are not considered in get_spacegroup method 80 | #magmoms = [np.ones(initial_pos.get_number_of_atoms())] 81 | initial_cell = (lattice, positions, numbers) 82 | 83 | print('\n===========================================') 84 | print('\nInitial Structure') 85 | print("\nLattice Matrix : (in Angstrom) ") 86 | print(lattice) 87 | print("\nAtomic Positions: (in direct coordinate) ") 88 | print(positions) 89 | print("\nAtomic numbers : (for each atom) ") 90 | print(numbers) 91 | print('\n===========================================') 92 | 93 | # visualize 94 | if prm.visualize==True: 95 | view(initial_pos) 96 | 97 | # find symmetry 98 | #---------------------------- 99 | spacegroup = spglib.get_spacegroup(initial_cell, symprec=float(prm.sym_tol)) 100 | print("Spacegroup: %s" % spacegroup) 101 | 102 | print('\n===========================================') 103 | # print("\nFinding primitive cell...") 104 | 105 | # impoer or not? 106 | if prm.no_ideal==False: 107 | print('\nImposing symmetry...') 108 | if prm.to_primitive: 109 | print('\nUsing primitive cell...') 110 | f_lattice, f_positions, f_numbers = spglib.standardize_cell(initial_cell, to_primitive=True, no_idealize=False, symprec=float(prm.sym_tol)) 111 | else: 112 | print('\nUsing original cell...') 113 | f_lattice, f_positions, f_numbers = spglib.standardize_cell(initial_cell, to_primitive=False, no_idealize=False, symprec=float(prm.sym_tol)) 114 | else: 115 | print('\nSymmetry is NOT imposed') 116 | if prm.to_primitive: 117 | print('\nFinding primitive cell...') 118 | f_lattice, f_positions, f_numbers = spglib.standardize_cell(initial_cell, to_primitive=True, no_idealize=True, symprec=float(prm.sym_tol)) 119 | else: 120 | print('\nUsing original cell...') 121 | f_lattice, f_positions, f_numbers = spglib.standardize_cell(initial_cell, to_primitive=False, no_idealize=True, symprec=float(prm.sym_tol)) 122 | 123 | # Final structure 124 | print("\nLattice Matrix : (in Angstrom) ") 125 | print(f_lattice) 126 | print("\nAtomic Positions: (in direct coordinate) ") 127 | # sort everything by types. 128 | f_positions=f_positions[f_numbers.argsort()] 129 | print(f_positions) 130 | print("\nAtomic numbers : (for each atom) ") 131 | f_numbers=f_numbers[f_numbers.argsort()] 132 | print(f_numbers) 133 | print('\n===========================================') 134 | 135 | 136 | # set cell informations 137 | #---------------------------- 138 | final_pos = Atoms(numbers=f_numbers, 139 | pbc=True, 140 | cell=f_lattice, 141 | scaled_positions=f_positions) 142 | # visualize 143 | if prm.visualize==True: 144 | view(final_pos) 145 | 146 | # Write final structure to file 147 | write(i_POSCAR+"_"+str(prm.sym_tol)+".vasp",final_pos,format='vasp') 148 | 149 | if float(sys.version.split()[0][:3]) < 3.0: 150 | # adding atomic species 151 | fin = [final_pos.get_chemical_symbols()[0]] 152 | for i in range(len(final_pos.get_chemical_symbols())): 153 | if i == len(final_pos.get_chemical_symbols())-1: break 154 | if final_pos.get_chemical_symbols()[i] != final_pos.get_chemical_symbols()[i+1]: 155 | fin.append(final_pos.get_chemical_symbols()[i+1]) 156 | 157 | f = open(i_POSCAR+"_"+str(prm.sym_tol)+".vasp", "r") 158 | contents = f.readlines() 159 | f.close() 160 | 161 | contents.insert(5, ' '.join(fin)+'\n') 162 | 163 | f = open(i_POSCAR+"_"+str(prm.sym_tol)+".vasp", "w") 164 | contents = "".join(contents) 165 | f.write(contents) 166 | f.close() 167 | 168 | print("\nOutput file name: %s " % str(i_POSCAR+"_"+str(prm.sym_tol)+".vasp")) 169 | # Post process 170 | #---------------------------- 171 | endtime = time.time() 172 | runtime = endtime-starttime 173 | print("\nEnd of calculation.") 174 | print("Program was running for %.2f seconds." % runtime) 175 | 176 | -------------------------------------------------------------------------------- /VASP/kp_gen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A script to make kpoints file 4 | """ 5 | 6 | from __future__ import print_function 7 | import seekpath 8 | import sys 9 | import ase 10 | import numpy as np 11 | import ase.io as io 12 | import argparse 13 | import time 14 | # import spglib 15 | 16 | 17 | parser = argparse.ArgumentParser(description='A script to make KPOINTS file.') 18 | parser.add_argument("-c", 19 | action="store", dest="input_file", default="POSCAR", 20 | help="The crystal structure. Default: POSCAR") 21 | parser.add_argument("-o", "--output", 22 | action="store", dest="output_file", default="KPOINTS.k_path", 23 | help="The file to which the new kpoints will be appended. Default: KPOINTS.kpgen.") 24 | parser.add_argument("-r", "--resolution", 25 | action="store", dest="resolution", default=0.1, 26 | help="a reference target distance between neighboring k-points in the path, in units of 1/ang.") 27 | parser.add_argument("-t", action="store_true", dest="time_reversal", 28 | help="Turns off time reversal symmetry.") 29 | parser.add_argument("-s", "--symprec", action="store", default=0.01, dest="symprec", 30 | help="precision for symmetry detection [spglib]. Default: 0.01 \AA") 31 | parser.add_argument("-e", "--explicit", action="store_false", default=True, dest="explicit", 32 | help="write explicit kpoints? Default: True") 33 | parser.add_argument("--hybrid", action="store_true", dest="hybrid", 34 | help="For hybrid bandstructure calculation?") 35 | parser.add_argument("--vdir", action="store", dest="vdir", default=None, 36 | help="vacuum dir? [0->x;1->y;2->z]") 37 | parser.add_argument("-v", action="store_true", dest="verbose", default=False, 38 | help="verbose output?") 39 | options = parser.parse_args() 40 | 41 | # Starting 42 | #---------------------------- 43 | if options.verbose == True: 44 | starttime = time.time() 45 | print("Starting calculation at", end='') 46 | print(time.strftime("%H:%M:%S on %a %d %b %Y\n")) 47 | 48 | # read in structure 49 | structure = io.read(options.input_file) 50 | numbers = structure.get_atomic_numbers() 51 | inp = (structure.cell,structure.get_scaled_positions(),numbers) 52 | 53 | # # find symmetry with spglib 54 | # #---------------------------- 55 | # print("Structure information [spglib]:") 56 | # spacegroup = spglib.get_spacegroup(inp, symprec=float(options.symprec)) 57 | # print("\tSpace group number: %s" % spacegroup.split()[1]) 58 | # print("\tSpace international symbol: %s" % spacegroup.split()[0]) 59 | 60 | 61 | # Turn off time reversal symmetry if necessary 62 | if not options.time_reversal: 63 | tr = True 64 | else: 65 | tr = False 66 | 67 | # get K-points 68 | explicit_data = seekpath.get_explicit_k_path(inp,with_time_reversal=tr, 69 | reference_distance=float(options.resolution), 70 | symprec=float(options.symprec)) 71 | kpath = explicit_data['explicit_kpoints_rel'] 72 | seg = np.array(explicit_data['explicit_segments']) 73 | labels = np.array(explicit_data['explicit_kpoints_labels']) 74 | 75 | # return symmetry 76 | if options.verbose == True: 77 | print("Structure information:") 78 | print("\tPrecision for finding symmetry: %8.6f \AA" % options.symprec) 79 | print("\tSpace group number: %s" % explicit_data['spacegroup_number']) 80 | print("\tSpace international symbol: %s" % explicit_data['spacegroup_international']) 81 | print("\nTime reversal symmtery: %s" % tr) 82 | 83 | 84 | # 2D material? 85 | seg_rm = [] 86 | if options.vdir!=None: 87 | for iseg in range(len(seg)): 88 | if kpath[seg[iseg,0],int(options.vdir)]!=0.0 or kpath[seg[iseg,1]-1,int(options.vdir)]!=0.0: 89 | seg_rm.append(iseg) 90 | seg = np.delete(seg, seg_rm, axis=0) 91 | 92 | # construct path 93 | fkpath = np.array([]).reshape(0,3) 94 | for iseg in range(len(seg)): 95 | fkpath=np.append(fkpath,kpath[seg[iseg,0]:seg[iseg,1]],axis=0) 96 | 97 | # construct label path 98 | flabels = np.array([]) 99 | for iseg in range(len(seg)): 100 | flabels=np.append(flabels,labels[seg[iseg,0]:seg[iseg,1]],axis=0) 101 | 102 | if options.verbose == True: 103 | print("k-point path:") 104 | for iseg in range(len(seg)): 105 | print("\t%s\t(%8.6f %8.6f %8.6f)\t->\t%s\t(%8.6f %8.6f %8.6f)" %(labels[seg[iseg,0]], 106 | kpath[seg[iseg,0],0], 107 | kpath[seg[iseg,0],1], 108 | kpath[seg[iseg,0],2], 109 | labels[seg[iseg,1]-1], 110 | kpath[seg[iseg,1]-1,0], 111 | kpath[seg[iseg,1]-1,1], 112 | kpath[seg[iseg,1]-1,2])) 113 | 114 | # construct label path: 115 | #------------------------ 116 | label_path = [] 117 | for iseg in range(len(seg)): 118 | label_path.append(f"""{kpath[seg[iseg,0],0]:+8.6f} {kpath[seg[iseg,0],1]:+8.6f} {kpath[seg[iseg,0],2]:+8.6f} !{labels[seg[iseg,0]]} 119 | {kpath[seg[iseg,1]-1,0]:+8.6f} {kpath[seg[iseg,1]-1,1]:+8.6f} {kpath[seg[iseg,1]-1,2]:+8.6f} !{labels[seg[iseg,1]-1]}\n\n""") 120 | 121 | #print(''.join(label_path)) 122 | 123 | # set k-point weight to zero? 124 | if options.hybrid: 125 | weight = 0. 126 | if options.verbose == True: 127 | print("For hybrid calculations.") 128 | else: 129 | weight = 1./len(fkpath) 130 | 131 | # write data 132 | with open(options.output_file,'w') as outfile: 133 | if options.explicit: 134 | outfile.write("File generated by kp_gen.py\n") 135 | outfile.write(str(len(fkpath))+"\n") 136 | outfile.write("Reciprocal\n") 137 | for ipoint in range(len(fkpath)): 138 | outfile.write("% 8.6f % 8.6f % 8.6f %5.3f !%s\n" % (fkpath[ipoint,0], 139 | fkpath[ipoint,1], 140 | fkpath[ipoint,2], 141 | weight, 142 | flabels[ipoint])) 143 | else: 144 | outfile.write("File generated by kp_gen.py\n") 145 | outfile.write(str(30)+"\n") 146 | outfile.write("Line-mode\n") 147 | outfile.write("rec\n") 148 | outfile.write(''.join(label_path)) 149 | 150 | if options.verbose == True: 151 | print('Output written to {}'.format(options.output_file)) 152 | endtime = time.time() 153 | runtime = endtime-starttime 154 | print("\nEnd of calculation.") 155 | print("Program was running for %.2f seconds." % runtime) 156 | 157 | # # Write new conventions cell, to ensure compliance with the kpoints 158 | # new_data = seekpath.get_path(inp) 159 | # 160 | # new_cell = ase.Atoms(positions=new_data['conv_positions'],cell=new_data['conv_lattice'],pbc=[True,True,True]) 161 | # new_cell.set_scaled_positions(new_data['conv_positions']) 162 | # new_cell.set_atomic_numbers(new_data['conv_types']) 163 | # numbers = new_cell.get_atomic_numbers() 164 | # 165 | # oup = (new_cell.cell,new_cell.get_scaled_positions(),numbers) 166 | # 167 | # 168 | # # find symmetry with spglib 169 | # #---------------------------- 170 | # print "Structure information [spglib]:" 171 | # spacegroup = spglib.get_spacegroup(oup, symprec=float(options.symprec)) 172 | # print "\tSpace group number: %s" % spacegroup.split()[1] 173 | # print "\tSpace international symbol: %s" % spacegroup.split()[0] 174 | # 175 | # if int(explicit_data['spacegroup_number'])!=int(spacegroup.split()[1][1:-1]): 176 | # sys.stdout.write("\033[1;31m" ) # set color red 177 | # print "symmetry changed!!!" 178 | # 179 | # 180 | # print 'New coordinates written to CONTCAR.conventional' 181 | # ase.io.vasp.write_vasp('CONTCAR.conventional',new_cell,sort=True,vasp5=True) 182 | # print 'Spacegroup: {} ({})'.format(new_data['spacegroup_international'], new_data['spacegroup_number']) 183 | # print 'Inversion symmetry?: {}'.format(new_data['has_inversion_symmetry']) 184 | # print 'I owe you nothing.' 185 | -------------------------------------------------------------------------------- /VASP/murn.f: -------------------------------------------------------------------------------- 1 | program murn 2 | c 3 | c modified from murn1.f : gps 6.12.90 4 | c modified from murn2.f : r.s 19.04.91 5 | c modified : bk 3.1.93 6 | c least-squares fit of e vs v by murnaghan equation of state 7 | c 8 | implicit double precision (a-h,o-z) 9 | double precision kb 10 | logical tzero 11 | dimension edata(50),vdata(50),x(40),aux(40) 12 | external fun 13 | 14 | c conversion factor from rydberg to eV, Boltzmann constant in Ha: 15 | c data convyy, kb /13.605826, 3.16666225714e-6/ 16 | data convyy, kb /1.d0, 3.16666225714e-6/ 17 | common /c/ edata,vdata, volmin,volmax,b0min,b0max,b0pmin,b0pmax, 18 | $ ula,nnn 19 | 20 | in=5 21 | iout=6 22 | ula=0.52917715 23 | write(iout,'("# unit of length =",f15.6," angstroem")') ula 24 | 25 | read(in,*)iunit 26 | if(iunit .eq. 1) then 27 | conv_inp = 27.2116168391d0/2.d0 28 | write(iout,1070) 29 | else if(iunit .eq. 2) then 30 | conv_inp = 1.d0 31 | write(iout,1080) 32 | else if(iunit .eq. 3) then 33 | conv_inp = 27.2116168391d0 34 | write(iout,1081) 35 | else 36 | write(iout,1090) 37 | stop 38 | end if 39 | 40 | 1070 format('# energies input in RYDBERGS') 41 | 1080 format('# energies input in ELECTRONVOLTS') 42 | 1081 format('# energies input in HARTREES') 43 | 1090 format('# only iunit = 1, 2 and 3 are recognized; stop.') 44 | 45 | c conversion factor from a**3 to the volume of unit cell 46 | c (e.g. 0.25, if the structure is such that v = a**3/4 ): 47 | read(in,*) convav 48 | write(iout,1020) convav 49 | 1020 format('# unit cell volume = a**3 *',f15.6) 50 | c 51 | c read in alat boundaries and number of points 52 | read(in,*) alat_min, alat_max, nr_alat 53 | write(iout, 54 | & '("# a(min)=",f20.7/,"# a(max)=",f20.7/,"# points:",i4)') 55 | & alat_min, alat_max, nr_alat 56 | if (nr_alat .lt. 2 .or. alat_max .le. alat_min) stop '# something w 57 | & rong with this range' 58 | 59 | c Zero point lattice energy correction by Moruzzi-Janak-Williams 60 | c Some values: 61 | c Gamma T(Debye) Volume/atom for T(Debye) 62 | c Al: 2.19 428 109.9 63 | c Fe: 1.66 467 78.95 64 | c Cu: 2.00 343 78.92 65 | 66 | c read in the values for zero point vibration energy correction - apsi 67 | c read(in,*) tzero, gamma, thetad, atvol 68 | 69 | if ( tzero ) then 70 | write(iout,'(a)') 71 | $ "# Zero point lattice energy by Moruzzi-Janak-Williams:" 72 | write(iout,'(a,f7.3,/,a,f6.2,/,a,f8.2)') 73 | $ "# Grueneisen constant = ", gamma, 74 | $ "# T(Debye) = ", thetad, 75 | $ "# Volume/at for T(Debye) = ", atvol 76 | write(iout,*) 77 | write(iout,'(a)') 78 | $ "# Tested only for fcc lattice (Al)" 79 | write(iout,*) 80 | end if 81 | 82 | c number of data points a, e(a): 83 | read(in,*) nnn 84 | write(iout,1030) nnn 85 | 1030 format('# number of data points: n =',i5) 86 | if (nnn .gt. 50) then 87 | write(iout,*)' n too large, nmax=50' 88 | stop 89 | endif 90 | 91 | write(iout,1120) 92 | write(iout,1040) 93 | 1040 format('# i',5x,'alatt',9x,'volume',12x,' E ') 94 | do 10 i=1,nnn 95 | read(in,*)alatt,eninp 96 | alatt=alatt 97 | vdata(i)=alatt**3*convav 98 | 99 | c Zero point vibrational correction - see above 100 | if ( tzero ) then 101 | eninporig = eninp 102 | eninp = eninp + 9.0/8.0 * kb*thetad * (atvol/vdata(i))**gamma 103 | end if 104 | 105 | edata(i)=eninp*conv_inp 106 | if ( tzero ) then 107 | write(iout,1115)i,alatt,vdata(i),eninp,eninporig 108 | 1115 format('#',1x,i5,2f15.6,1f19.10,2x,1f19.10) 109 | else 110 | write(iout,1110)i,alatt,vdata(i),eninp 111 | 1110 format('#',1x,i5,2f15.6,1f19.10) 112 | end if 113 | 10 continue 114 | write(iout,1120) 115 | 1120 format('#',10(1h-)) 116 | c 117 | c starting values for iteration: 118 | c 119 | write(iout,1130) 120 | 1130 format('#',5x,'alatt0',3x,'vol0 (ula**3)',2x,'b0 (mbar)', 121 | & 5x,'b0prime',6x,' e0') 122 | 123 | c mimimum in edata(i): 124 | e0min=1.d6 125 | volmin=1.d6 126 | do 100 i=1,nnn 127 | if(edata(i) .ge. e0min) go to 100 128 | e0min=edata(i) 129 | volmin=vdata(i) 130 | 100 continue 131 | 132 | vol0=volmin 133 | e0ev=e0min 134 | e0ry=e0*convyy 135 | alatt0=(vol0/convav)**(1.d0/3.d0) 136 | c 137 | c for other variables, we choose: 138 | c 139 | b0=1.d0 140 | b0prim=4.d0 141 | 142 | write(iout,1140)alatt0,vol0,b0,b0prim,e0ry 143 | 1140 format('# ',f9.4,3f13.5,1f13.5) 144 | 145 | almin=0.5d0*alatt0 146 | almax=1.5d0*alatt0 147 | b0min=0.01d0 148 | b0max=10.d0 149 | b0pmin=0.01d0 150 | b0pmax=10.d0 151 | 152 | volmin=almin**3.d0*convav 153 | volmax=almax**3.d0*convav 154 | write(iout,1210)almin,volmin,b0min,b0pmin,almax,volmax,b0max,b0pm 155 | & ax 156 | 1210 format('# min:',f9.4,3f13.5/,'# max:',f9.4,3f13.5) 157 | c 158 | c a uniform shift of all the energies 159 | c (will not influence the b0, b0prime, vol0, only shifts e0): 160 | c 161 | shift=-e0ev-1.d0 162 | do 20 i=1,nnn 163 | 20 edata(i)=edata(i)+shift 164 | 165 | c murnaghan least-squares fit: 166 | write(iout,1120) 167 | write(iout,1280) 168 | 1280 format('# fit by murnaghan equation equation of state') 169 | write(iout,1120) 170 | write(iout,1190) 171 | 1190 format('#iter, alatt0, vol0 (ula**3),' 172 | 1 ,' b0 (mbar), b0prime, e0, sq sum, ierr') 173 | 174 | x(1)=e0ev+shift 175 | x(2)=b0 176 | x(3)=b0prim 177 | x(4)=vol0 178 | nvar=4 179 | lim=20 180 | 181 | do 70 i = 1, 75 182 | call dfmnd(fun,x,fff,nvar,lim,aux,ierr) 183 | write(iout,'("# ",i3,f9.4,3f12.5,f14.7,f12.5,i2)') 184 | & 20*i,(x(4)/convav)**(1.d0/3.d0),x(4),x(2),x(3), 185 | & (x(1)-shift)/conv_inp,fff,ierr 186 | if (ierr .eq. 0) go to 80 187 | 70 continue 188 | 80 continue 189 | 190 | write(iout,1120) 191 | c write(iout,1130) 192 | vol0=x(4) 193 | alatt0=(vol0/convav)**(1.d0/3.d0) 194 | b0=x(2) 195 | b0prim=x(3) 196 | e0ev=x(1)-shift 197 | e0ry=e0ev/convyy 198 | c write(iout,'("# alat=",f10.5\,"# b0=", f10.4, " b0p=", f10.3," e0=", 199 | c & f11.6)') 200 | c & alatt0, b0, b0prim, e0ev / 27.212 201 | c write(iout,1140)alatt0,vol0,b0,b0prim,e0ev,e0ry 202 | c write(iout,1120) 203 | c 204 | c print out fitted energy values for nr_alat lattice 205 | c 206 | open (3,FILE='murn.gnu',STATUS='UNKNOWN',FORM='FORMATTED') 207 | do i=1, nnn 208 | write (3,'(f10.5,f18.6,f16.8)') 209 | & (vdata(i)/convav)**(1.d0/3.d0), 210 | & (edata(i)-shift)/conv_inp, 211 | & (edata(i)-shift)/conv_inp-e0ev/conv_inp 212 | end do 213 | write(iout,500) 214 | 500 format('# a (a.u.), E') 215 | write(iout,1120) 216 | do i=1,nr_alat 217 | c vol=0.6d0*vol0 + (i-1)*0.05*vol0 218 | c alatt=(vol/convav)**(1./3.) 219 | c alatt=alatt*ula 220 | alatt=alat_min + (i-1)*(alat_max-alat_min)/(nr_alat-1) 221 | vol = alatt**3 * convav 222 | alatt=alatt*ula 223 | call murng1(ula,vol,vol0,b0,b0prim,e0ev,etot) 224 | etotry=etot/convyy 225 | write(iout,'(f10.5,f18.6,f10.6)') 226 | & alatt/ula,etot/conv_inp,(etot-e0ev)/conv_inp 227 | c write(iout,502) alatt, etotry, alatt/ula, etotry/2 228 | c 502 format(2(f10.5,f20.7)) 229 | enddo 230 | c 231 | stop 232 | end 233 | c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 234 | double precision function fun(x) 235 | c function to be minimized in the least-squares fit (by subroutine dfmn 236 | c d) 237 | c function 238 | c calculates the sum of the a b s o l u t e deviations 239 | c (e(theor)-e(exp))**2 240 | c divided by the number of exp. points, 241 | c assuming for equation of state the murnaghan expression. 242 | c 243 | c meaning of variables: 244 | c x(1) .... e0 245 | c x(2) .... b0 246 | c x(3) .... b0prim 247 | c x(4) .... vol0 248 | c 249 | c 250 | implicit double precision (a-h,o-z) 251 | dimension edata(50),vdata(50),x(40) 252 | common /c/ edata,vdata, volmin,volmax,b0min,b0max,b0pmin,b0pmax, 253 | $ ula,nnn 254 | c 255 | c * * * * * * 256 | e0=x(1) 257 | b0=x(2) 258 | b0prim=x(3) 259 | vol0=x(4) 260 | c 261 | sum=0.d0 262 | c the sum of squares: 263 | do 10 i=1,nnn 264 | volact=vdata(i) 265 | call murng1(ula,volact,vol0,b0,b0prim,e0,etot) 266 | sum=sum+(etot-edata(i))**2 267 | 10 continue 268 | fun=sum/dfloat(nnn) 269 | return 270 | end 271 | c ----------------------------------------------------------------- 272 | subroutine murng1(ula,vol,vol0,b0,b0prim,e0,etot) 273 | c evaluation of the murnaghan expression for energy as a function 274 | c of volume. 275 | c 276 | c input data: 277 | c 278 | c ula ..... unit of length, in angstroems, used here. 279 | c vol ..... volume, in the above units of length cubed. 280 | c vol0 .... volume at the energy minimum, in the same units. 281 | c b0 ...... bulk modulus, in units megabar. 282 | c b0prim .. pressure derivative of the bulk modulus. 283 | c should be close neither to 0 nor to 1. 284 | c e0 ...... an additive constant (in electronvolts), added 285 | c to the energy expression. 286 | c (see, pr b28, p 5484: fu and ho) 287 | c 288 | c output data: 289 | c 290 | c etot .... the energy, including the e0 constant, in electronvolts 291 | c 292 | c if b0 differs from 0. or from 1. by less than 1.d-6, then 293 | c etot is set at +111111.111111 electronvolts. 294 | c 295 | c * * * * * * * * 296 | c 297 | implicit double precision (a-h,o-z) 298 | c 299 | c conversion factor from erg to electronvolt: 300 | parameter( convxx = 1.60209d0 ) 301 | c 1 electronvolt = 1.60209 d-12 erg 302 | c 303 | c 304 | if(dabs(b0prim)-1.d0 .lt. 1.d-6 .or. 305 | 1 dabs(b0prim) .lt. 1.d-6) then 306 | etot=+111111.111111d0 307 | return 308 | end if 309 | c 310 | if(vol .lt. 0.d0 .or. vol0 .lt. 0.d0) then 311 | etot=+111111.111111d0 312 | return 313 | end if 314 | c 315 | etot = e0 - b0*vol0/b0prim * 316 | 1 (((vol/vol0)**(1.d0-b0prim)-1.d0)/(1.d0-b0prim)-vol/vol0+1.d0) 317 | 2 *ula**3/convxx 318 | c 319 | return 320 | end 321 | c -------- 322 | subroutine dfmnd(f,x,y,n,lim,aux,ier) 323 | c 324 | c ****************************************************************** 325 | c * minimization of a function of several variables * 326 | c * using powell's algorithm without derivatives * 327 | c ****************************************************************** 328 | c 329 | double precision f,x,y,aux,eps,eta,tol, 330 | 1 da,db,dc,dm,dq,fa,fb,fc,fl,fm,fs,hd,hq,hx 331 | dimension x(1),aux(1) 332 | c 333 | c subroutines required: the external function f. 334 | c 335 | c input data: 336 | c f .... the function of n variables x(1)...x(n) to be minimized 337 | c x .... x(1) ... x(n) = starting guess for the variables; 338 | c beware: x has to be dimensioned in the main program 339 | c to considerably more than n. 340 | c n .... number of variables; the dimension of x and aux in the 341 | c calling program must be, however, much higher: 342 | c - perhaps 10 times? 343 | c lim .. maximum number of iterations 344 | c aux .. auxiliary array of the same dimension as x. 345 | c output data: 346 | c x .... x(1) ... x(n) the resulting minimum 347 | c y .... value of the function at the minimum 348 | c ier .. some error indication 349 | c ierr=0 means 'convergence achieved'. 350 | c 351 | c * * * * * * * * 352 | c 353 | isw =ier 354 | ier =0 355 | if (n) 1,1,2 356 | 1 ier =1000 357 | goto 109 358 | 2 if (lim) 3,3,4 359 | 3 ier =2000 360 | goto 109 361 | c 362 | c set initial values and save initial argument 363 | c 364 | 4 n1 =n+1 365 | n2 =n+n 366 | n3 =n+n2 367 | n4 =n+n3 368 | n5 =n*n+n4 369 | eps =1.d-15 370 | eta =n*eps 371 | do 5 k=1,n 372 | aux(k)=x(k) 373 | j =n3+k 374 | 5 aux(j)=1.d0 375 | fs =f(aux) 376 | fb =fs 377 | i =1 378 | ic =1 379 | it =0 380 | m =n4 381 | mf =0 382 | is =1 383 | c 384 | c start iteration cycle 385 | c 386 | 6 it =it+1 387 | fl =fs 388 | do 7 k=n1,n2 389 | 7 aux(k)=0.d0 390 | id =i 391 | i =ic 392 | iw =0 393 | c 394 | c start minimization along next direction 395 | c 396 | 8 ns =0 397 | ip =0 398 | db =0.d0 399 | if (iw) 10,9,10 400 | 9 hx =aux(i) 401 | 10 if (it-1) 11,11,14 402 | 11 if (is-1) 14,12,14 403 | 12 dm =.1d0 404 | if (dabs(hx)-1.d0) 38,38,13 405 | 13 dm =-dm*hx 406 | goto 38 407 | 14 if (is-2) 18,15,18 408 | 15 if (it-1) 17,16,17 409 | 16 dm =hq 410 | goto 38 411 | 17 dm =dq 412 | goto 38 413 | c 414 | c interpolation using estimate of second derivative 415 | c 416 | 18 if (iw-1) 20,19,20 417 | 19 j =n2+i 418 | goto 21 419 | 20 j =n3+i 420 | 21 hd =aux(j) 421 | dc =1.d-2 422 | if (it-2) 23,23,22 423 | 22 dc =hq 424 | 23 dm =dc 425 | mk =1 426 | goto 51 427 | 24 dm =dc*hd 428 | if (dm) 26,25,26 429 | 25 dm =1.d0 430 | 26 dm =.5d0*dc-(fm-fb)/dm 431 | mk =2 432 | if (fm-fb) 27,29,29 433 | 27 fc =fb 434 | fb =fm 435 | db =dc 436 | if (dm-db) 28,67,28 437 | 28 dc =0.d0 438 | goto 51 439 | 29 if (dm-db) 31,30,31 440 | 30 da =dc 441 | fa =fm 442 | goto 37 443 | 31 fc =fm 444 | goto 51 445 | c 446 | c analyse interpolated function value 447 | c 448 | 32 if (fm-fb) 34,33,33 449 | 33 da =dm 450 | fa =fm 451 | goto 35 452 | 34 da =db 453 | fa =fb 454 | db =dm 455 | fb =fm 456 | 35 if ((dc-da)/(db-da)) 36,36,50 457 | 36 if (db) 67,37,67 458 | 37 ns =1 459 | dm =-dc 460 | c 461 | c linear search for smaller function values 462 | c along current direction 463 | c 464 | 38 if (ns-15) 43,43,39 465 | 39 if (fs-fm) 41,40,41 466 | 40 mf =n+2 467 | db =0.d0 468 | goto 67 469 | 41 if (dabs(dm)-1.d6) 43,43,42 470 | 42 ier =100 471 | goto 67 472 | 43 ns =ns+1 473 | mk =3 474 | goto 51 475 | 44 if (fm-fb) 45,46,47 476 | 45 da =db 477 | fa =fb 478 | db =dm 479 | fb =fm 480 | dm =dm+dm 481 | goto 38 482 | 46 if (fs-fb) 47,45,47 483 | 47 if (ns-1) 48,48,49 484 | 48 da =dm 485 | fa =fm 486 | dm =-dm 487 | goto 38 488 | 49 dc =dm 489 | fc =fm 490 | c 491 | c refine minimum using quadratic interpolation 492 | c 493 | 50 hd =(fc-fb)/(dc-db)+(fa-fb)/(db-da) 494 | dm =.5d0*(da+dc)+(fa-fc)/(hd+hd) 495 | ip =ip+1 496 | mk =4 497 | c 498 | c step argument vector and calculate function value 499 | c 500 | 51 if (iw-1) 54,52,54 501 | 52 do 53 k=1,n 502 | l =m+k 503 | 53 aux(k)=x(k)+dm*aux(l) 504 | goto 55 505 | 54 aux(i)=hx+dm 506 | 55 fm =f(aux) 507 | goto (24,32,44,56),mk 508 | c 509 | c analyse interpolated function value 510 | c 511 | 56 if (fm-fb) 61,61,57 512 | 57 if (ip-3) 58,62,62 513 | 58 if ((dc-db)/(dm-db)) 60,60,59 514 | 59 dc =dm 515 | fc =fm 516 | goto 50 517 | 60 da =dm 518 | fa =fm 519 | goto 50 520 | 61 db =dm 521 | fb =fm 522 | c 523 | c calculate new estimate of second derivative 524 | c along the current direction 525 | c 526 | 62 hd =(hd+hd)/(dc-da) 527 | if (iw-1) 64,63,64 528 | 63 j =n2+i 529 | goto 65 530 | 64 j =n3+i 531 | 65 aux(j)=hd 532 | if (fb-fs) 67,66,67 533 | 66 db =0.d0 534 | c 535 | c save argument vector with smallest function value found 536 | c 537 | 67 if (iw-1) 70,68,70 538 | 68 do 69 k=1,n 539 | l =m+k 540 | j =n+k 541 | hd =db*aux(l) 542 | aux(j)=aux(j)+hd 543 | hd =x(k)+hd 544 | aux(k)=hd 545 | 69 x(k) =hd 546 | goto 71 547 | 70 j =n+i 548 | aux(j)=aux(j)+db 549 | hd =hx+db 550 | aux(i)=hd 551 | x(i) =hd 552 | 71 if (ier-100) 72,108,72 553 | c 554 | c determine direction for next linear search 555 | c 556 | 72 fs =fb 557 | if (i-n) 74,73,73 558 | 73 i =0 559 | 74 i =i+1 560 | if (is) 75,75,80 561 | 75 if (db) 77,76,77 562 | 76 if (i-ic) 8,77,8 563 | 77 ic =i 564 | is =1 565 | if (it-n) 79,79,78 566 | 78 iw =1 567 | 79 i =id 568 | goto 8 569 | 80 m =m+n 570 | if (m-n5) 82,81,81 571 | 81 m =n4 572 | 82 if (is-1) 83,83,94 573 | 83 if (i-1) 84,84,85 574 | 84 iw =1 575 | 85 if (i-id) 8,86,8 576 | 86 hq =0.d0 577 | do 87 k=n1,n2 578 | 87 hq =hq+aux(k)*aux(k) 579 | if (hq) 90,88,90 580 | 88 if (mf-n1) 108,108,89 581 | 89 ier =200 582 | goto 108 583 | 90 dq =dsqrt(hq) 584 | hq =dq 585 | if (hq-1.d0) 92,92,91 586 | 91 hq =1.d0 587 | 92 do 93 k=n1,n2 588 | l =m+k-n 589 | 93 aux(l)=aux(k)/dq 590 | is =2 591 | goto 8 592 | c 593 | c end of iteration cycle 594 | c test for termination of minimization 595 | c 596 | 94 is =0 597 | tol =eps 598 | if (dabs(fs)-1.d0) 96,96,95 599 | 95 tol =eps*dabs(fs) 600 | 96 if (fl-fs-tol) 100,100,97 601 | 97 if (it-lim) 99,99,98 602 | 98 ier =10 603 | goto 108 604 | 99 mf =0 605 | goto 6 606 | 100 if (mf-n1) 102,102,101 607 | 101 ier =200 608 | goto 108 609 | 102 mf =mf+1 610 | dq =0.d0 611 | do 105 k=1,n 612 | j =n+k 613 | if (dabs(aux(k))-1.d0) 103,103,104 614 | 103 dq =dq+dabs(aux(j)) 615 | goto 105 616 | 104 dq =dq+dabs(aux(j)/aux(k)) 617 | 105 continue 618 | if (dq-eta) 108,108,106 619 | 106 if (mf-n) 6,6,107 620 | 107 ier =1 621 | 108 y =fb 622 | if (ier) 111,111,109 623 | 109 if (isw+12345) 110,111,110 624 | c 110 call wier(ier,20212) 625 | 110 continue 626 | 111 return 627 | end 628 | -------------------------------------------------------------------------------- /VASP/p4vmod.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A script to replace some naming convention in vasprun.xml 4 | 5 | 6 | v5.4.4 v5.4.1 7 | 8 | x2-y2 --> dx2 9 | fy3x2 --> f1 10 | fxyz --> f2 11 | fyz2 --> f3 12 | fz3 --> f4 13 | fxz2 --> f5 14 | fzx2 --> f6 15 | fx3 --> f7 16 | 17 | usage ./p4vmod.py vasprun.xml 18 | """ 19 | import sys 20 | import os 21 | 22 | # Find out how many arguments were on the command line, 23 | nsubtract = len(sys.argv)-1 24 | if nsubtract > 1: 25 | print "\n** ERROR: Must specify only one file." 26 | print "eg. ./chgdiff.py vasprun.xml" 27 | sys.exit(0) 28 | 29 | elif nsubtract == 1 and not os.path.isfile(sys.argv[1]): 30 | print "\n** ERROR: Input file %s was not found." % sys.argv[1] 31 | sys.exit(0) 32 | 33 | elif nsubtract == 1 and os.path.isfile(sys.argv[1]): 34 | filename = sys.argv[1].lstrip() 35 | 36 | elif nsubtract == 0: 37 | print "\n** Warning: Defult to vasprun.xml." 38 | filename = "vasprun.xml" 39 | 40 | 41 | # open file 42 | f = open(filename, "r") 43 | contents = f.readlines() 44 | f.close() 45 | 46 | # concatenat 47 | contents = "".join(contents) 48 | 49 | # replace 50 | contents = contents.replace("x2-y2"," dx2") 51 | contents = contents.replace("fy3x2"," f1") 52 | contents = contents.replace(" fxyz"," f2") 53 | contents = contents.replace(" fyz2"," f3") 54 | contents = contents.replace(" fz3"," f4") 55 | contents = contents.replace(" fxz2"," f5") 56 | contents = contents.replace(" fzx2"," f6") 57 | contents = contents.replace(" fx3"," f7") 58 | 59 | # output 60 | f = open(filename+".541.xml", "w") 61 | f.write(contents) 62 | f.close() 63 | -------------------------------------------------------------------------------- /VASP/pp_gen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A script to make generate PP for VASP 4 | 5 | set env -> VASP_PP_PATH to your PP dir 6 | LDA -> $VASP_PP_PATH/potpaw 7 | PBE -> $VASP_PP_PATH/potpaw_PBE 8 | """ 9 | 10 | from __future__ import print_function 11 | import argparse 12 | import os 13 | import sys 14 | import datetime 15 | import time 16 | 17 | # Command line praser 18 | #-------------------- 19 | parser = argparse.ArgumentParser(description='A script to make supercell(transformed supercell) and measure atomic distances.') 20 | parser.add_argument('-v', '--verbose', action="store_false", default=True, dest="prt", 21 | help='print out info? (Default=False)') 22 | parser.add_argument('-o','--overwrite', action="store_true", default=False, dest='over', 23 | help='Overwrite POTCAR?. (Default=False)') 24 | parser.add_argument('-c','--POSCAR', action="store", default="POSCAR", dest="POSCAR", 25 | help='Input file name.') 26 | parser.add_argument('-i', action="store", default=None, dest="atom_list", 27 | help='atom list (Default=None)') 28 | parser.add_argument('-s', action="store", default="recommended", dest="setup", 29 | help='setup (minimal | recommended | materialsproject | gw | manual)') 30 | parser.add_argument('-xc', action="store", default="PBE", dest="xc", 31 | help='setup (PBE | LDA)') 32 | 33 | prm = parser.parse_args() 34 | 35 | # Starting 36 | #--------- 37 | if prm.prt == True: 38 | starttime = time.time() 39 | print("Starting at",end='') 40 | print(time.strftime("%H:%M:%S on %a %d %b %Y")) 41 | 42 | # check input 43 | if prm.atom_list == None and not os.path.isfile(prm.POSCAR): 44 | sys.stdout.write("\033[1;31m" ) # set color red 45 | print("\n** ERROR: Initial position file %s was not found." % prm.POSCAR) 46 | sys.stdout.write("\033[0;0m") # reset color 47 | sys.exit(0) 48 | 49 | if prm.atom_list == None: 50 | f = open(prm.POSCAR) 51 | a = f.readlines() 52 | atom_list = a[5].strip("\n").split() 53 | f.close() 54 | elif prm.POSCAR != "POSAR" and prm.atom_list != None: 55 | sys.stdout.write("\033[1;31m" ) # set color red 56 | print("\n** WARNING: -i override -c") 57 | sys.stdout.write("\033[0;0m") # reset color 58 | atom_list = prm.atom_list.split() 59 | else: 60 | sys.stdout.write("\033[1;31m" ) # set color red 61 | print("\n** ERROR: no atom species specified.") 62 | sys.stdout.write("\033[0;0m") # reset color 63 | sys.exit(0) 64 | 65 | # print out atom_list 66 | if prm.prt == True: 67 | print("\ninput atom species: %s " % atom_list) 68 | print("input xc: %s " % prm.xc) 69 | print("input setup: %s " % prm.setup) 70 | 71 | # Dictionary containing all data 72 | #------------------------------- 73 | if prm.xc == "PBE": 74 | PP_dir = os.environ.get("VASP_PP_PATH")+"/potpaw_PBE/" 75 | minimal = { 76 | "Ac" : ["Ac"], 77 | "Ag" : ["Ag","Ag_pv"], 78 | "Al" : ["Al"], 79 | "Am" : ["Am"], 80 | "Ar" : ["Ar"], 81 | "As" : ["As","As_d"], 82 | "At" : ["At"], 83 | "Au" : ["Au"], 84 | "B" : ["B","B_h","B_s"], 85 | "Ba" : ["Ba_sv"], 86 | "Be" : ["Be", "Be_sv"], 87 | "Bi" : ["Bi", "Bi_d"], 88 | "Br" : ["Br"], 89 | "C" : ["C","C_h","C_s"], 90 | "Ca" : ["Ca_pv","Ca_sv"], 91 | "Cd" : ["Cd"], 92 | "Ce" : ["Ce","Ce_3","Ce_h"], 93 | "Cf" : ["Cf"], 94 | "Cl" : ["Cl","Cl_h"], 95 | "Cm" : ["Cm"], 96 | "Co" : ["Co","Co_pv","Co_sv"], 97 | "Cr" : ["Cr","Cr_pv","Cr_sv"], 98 | "Cs" : ["Cs_sv"], 99 | "Cu" : ["Cu","Cu_pv"], 100 | "Dy" : ["Dy","Dy_3"], 101 | "Er" : ["Er","Er_2","Er_3"], 102 | "Eu" : ["Eu","Eu_2","Eu_3"], 103 | "F" : ["F","F_h","F_s"], 104 | "Fe" : ["Fe","Fe_pv","Fe_sv"], 105 | "Fr" : ["Fr_sv"], 106 | "Ga" : ["Ga","Ga_d","Ga_h"], 107 | "Gd" : ["Gd","Gd_3"], 108 | "Ge" : ["Ge","Ge_d","Ge_h"], 109 | "H" : ["H","H.25","H.33","H.42","H.5","H.58","H.66","H.75","H1.25","H1.33","H1.5","H1.66","H1.75","H_AE","H_h","H_s"], 110 | "He" : ["He","He_AE"], 111 | "Hf" : ["Hf","Hf_pv","Hf_sv"], 112 | "Hg" : ["Hg"], 113 | "Ho" : ["Ho","Ho_3"], 114 | "I" : ["I"], 115 | "In" : ["In","In_d"], 116 | "Ir" : ["Ir"], 117 | "K" : ["K_pv","K_sv"], 118 | "Kr" : ["Kr"], 119 | "La" : ["La","La_s"], 120 | "Li" : ["Li","Li_sv"], 121 | "Lu" : ["Lu","Lu_3"], 122 | "Mg" : ["Mg","Mg_pv","Mg_sv"], 123 | "Mn" : ["Mn","Mn_pv","Mn_sv"], 124 | "Mo" : ["Mo","Mo_pv","Mo_sv"], 125 | "N" : ["N","N_h","N_s"], 126 | "Na" : ["Na","Na_pv","Na_sv"], 127 | "Nb" : ["Nb_pv","Nb_sv"], 128 | "Nd" : ["Nd","Nd_3"], 129 | "Ne" : ["Ne"], 130 | "Ni" : ["Ni","Ni_pv"], 131 | "Np" : ["Np","Np_s"], 132 | "O" : ["O","O_h","O_s"], 133 | "Os" : ["Os","Os_pv"], 134 | "P" : ["P","P_h"], 135 | "Pa" : ["Pa","Pa_s"], 136 | "Pb" : ["Pb","Pb_d"], 137 | "Pd" : ["Pd","Pd_pv"], 138 | "Pm" : ["Pm","Pm_3"], 139 | "Po" : ["Po","Po_d"], 140 | "Pr" : ["Pr","Pr_3"], 141 | "Pt" : ["Pt","Pt_pv"], 142 | "Pu" : ["Pu","Pu_s"], 143 | "Ra" : ["Ra_sv"], 144 | "Rb" : ["Rb_pv","Rb_sv"], 145 | "Re" : ["Re","Re_pv"], 146 | "Rh" : ["Rh","Rh_pv"], 147 | "Rn" : ["Rn"], 148 | "Ru" : ["Ru","Ru_pv","Ru_sv"], 149 | "S" : ["S","S_h"], 150 | "Sb" : ["Sb"], 151 | "Sc" : ["Sc","Sc_sv"], 152 | "Se" : ["Se"], 153 | "Si" : ["Si"], 154 | "Sm" : ["Sm","Sm_3"], 155 | "Sn" : ["Sn","Sn_d"], 156 | "Sr" : ["Sr_sv"], 157 | "Ta" : ["Ta","Ta_pv"], 158 | "Tb" : ["Tb","Tb_3"], 159 | "Tc" : ["Tc","Tc_pv","Tc_sv"], 160 | "Te" : ["Te"], 161 | "Th" : ["Th","Th_s"], 162 | "Ti" : ["Ti","Ti_pv","Ti_sv"], 163 | "Tl" : ["Tl","Tl_d"], 164 | "Tm" : ["Tm","Tm_3"], 165 | "U" : ["U","U_s"], 166 | "V" : ["V","V_pv","V_sv"], 167 | "W" : ["W","W_pv","W_sv"], 168 | "Xe" : ["Xe"], 169 | "Y" : ["Y_sv"], 170 | "Yb" : ["Yb","Yb_2","Yb_3"], 171 | "Zn" : ["Zn"], 172 | "Zr" : ["Zr_sv"] 173 | } 174 | 175 | #https://cms.mpi.univie.ac.at/vasp/vasp/Recommended_PAW_potentials_DFT_calculations_using_vasp_5_2.html 176 | recommended = { 177 | "Ac" : ["Ac"], 178 | "Ag" : ["Ag_pv","Ag"], 179 | "Al" : ["Al"], 180 | "Am" : ["Am"], 181 | "Ar" : ["Ar"], 182 | "As" : ["As","As_d"], 183 | "At" : ["At"], 184 | "Au" : ["Au"], 185 | "B" : ["B","B_h","B_s"], 186 | "Ba" : ["Ba_sv"], 187 | "Be" : ["Be", "Be_sv"], 188 | "Bi" : ["Bi_d","Bi"], 189 | "Br" : ["Br"], 190 | "C" : ["C","C_h","C_s"], 191 | "Ca" : ["Ca_sv","Ca_pv"], 192 | "Cd" : ["Cd"], 193 | "Ce" : ["Ce","Ce_3","Ce_h"], 194 | "Cf" : ["Cf"], 195 | "Cl" : ["Cl","Cl_h"], 196 | "Cm" : ["Cm"], 197 | "Co" : ["Co","Co_pv","Co_sv"], 198 | "Cr" : ["Cr_pv","Cr","Cr_sv"], 199 | "Cs" : ["Cs_sv"], 200 | "Cu" : ["Cu","Cu_pv"], 201 | "Dy" : ["Dy_3","Dy"], 202 | "Er" : ["Er_3","Er","Er_2"], 203 | "Eu" : ["Eu_2","Eu","Eu_3"], 204 | "F" : ["F","F_h","F_s"], 205 | "Fe" : ["Fe","Fe_pv","Fe_sv"], 206 | "Fr" : ["Fr_sv"], 207 | "Ga" : ["Ga_d","Ga","Ga_h"], 208 | "Gd" : ["Gd_3","Gd"], 209 | "Ge" : ["Ge_d","Ge","Ge_h"], 210 | "H" : ["H","H.25","H.33","H.42","H.5","H.58","H.66","H.75","H1.25","H1.33","H1.5","H1.66","H1.75","H_AE","H_h","H_s"], 211 | "He" : ["He","He_AE"], 212 | "Hf" : ["Hf_pv","Hf","Hf_sv"], 213 | "Hg" : ["Hg"], 214 | "Ho" : ["Ho_3","Ho"], 215 | "I" : ["I"], 216 | "In" : ["In_d","In"], 217 | "Ir" : ["Ir"], 218 | "K" : ["K_sv","K_pv"], 219 | "Kr" : ["Kr"], 220 | "La" : ["La","La_s"], 221 | "Li" : ["Li_sv","Li"], 222 | "Lu" : ["Lu_3","Lu"], 223 | "Mg" : ["Mg","Mg_pv","Mg_sv"], 224 | "Mn" : ["Mn_pv","Mn","Mn_sv"], 225 | "Mo" : ["Mo_sv","Mo","Mo_pv"], 226 | "N" : ["N","N_h","N_s"], 227 | "Na" : ["Na_pv","Na","Na_sv"], 228 | "Nb" : ["Nb_sv","Nb_pv"], 229 | "Nd" : ["Nd_3","Nd"], 230 | "Ne" : ["Ne"], 231 | "Ni" : ["Ni","Ni_pv"], 232 | "Np" : ["Np","Np_s"], 233 | "O" : ["O","O_h","O_s"], 234 | "Os" : ["Os","Os_pv"], 235 | "P" : ["P","P_h"], 236 | "Pa" : ["Pa","Pa_s"], 237 | "Pb" : ["Pb_d","Pb"], 238 | "Pd" : ["Pd","Pd_pv"], 239 | "Pm" : ["Pm_3","Pm"], 240 | "Po" : ["Po_d","Po"], 241 | "Pr" : ["Pr_3","Pr"], 242 | "Pt" : ["Pt","Pt_pv"], 243 | "Pu" : ["Pu","Pu_s"], 244 | "Ra" : ["Ra_sv"], 245 | "Rb" : ["Rb_sv","Rb_pv"], 246 | "Re" : ["Re","Re_pv"], 247 | "Rh" : ["Rh_pv","Rh"], 248 | "Rn" : ["Rn"], 249 | "Ru" : ["Ru_pv","Ru","Ru_sv"], 250 | "S" : ["S","S_h"], 251 | "Sb" : ["Sb"], 252 | "Sc" : ["Sc_sv","Sc"], 253 | "Se" : ["Se"], 254 | "Si" : ["Si"], 255 | "Sm" : ["Sm_3","Sm"], 256 | "Sn" : ["Sn_d","Sn"], 257 | "Sr" : ["Sr_sv"], 258 | "Ta" : ["Ta_pv","Ta"], 259 | "Tb" : ["Tb_3","Tb"], 260 | "Tc" : ["Tc_pv","Tc","Tc_sv"], 261 | "Te" : ["Te"], 262 | "Th" : ["Th","Th_s"], 263 | "Ti" : ["Ti_sv","Ti","Ti_pv"], 264 | "Tl" : ["Tl_d","Tl"], 265 | "Tm" : ["Tm_3","Tm"], 266 | "U" : ["U","U_s"], 267 | "V" : ["V_sv","V","V_pv"], 268 | "W" : ["W_sv","W","W_pv"], 269 | "Xe" : ["Xe"], 270 | "Y" : ["Y_sv"], 271 | "Yb" : ["Yb_2","Yb","Yb_3"], 272 | "Zn" : ["Zn"], 273 | "Zr" : ["Zr_sv"] 274 | } 275 | gw = { 276 | "Ag" : ["Ag_sv_GW","Ag_GW"], 277 | "Al" : ["Al_GW","Al_sv_GW"], 278 | "Ar" : ["Ar_GW"], 279 | "As" : ["As_GW","As_sv_GW"], 280 | "At" : ["At_d_GW","At_sv_GW"], 281 | "Au" : ["Au_sv_GW","Au_GW"], 282 | "B" : ["B_GW"], 283 | "Ba" : ["Ba_sv_GW"], 284 | "Be" : ["Be_sv_GW","Be_GW"], 285 | "Bi" : ["Bi_d_GW","Bi_GW","Bi_sv_GW"], 286 | "Br" : ["Br_GW","Br_sv_GW"], 287 | "C" : ["C_GW","C_GW_new","C_h_GW"], 288 | "Ca" : ["Ca_sv_GW"], 289 | "Cd" : ["Cd_sv_GW","Cd_GW"], 290 | "Ce" : ["Ce_GW"], 291 | "Cl" : ["Cl_GW"], 292 | "Co" : ["Co_sv_GW","Co_GW"], 293 | "Cr" : ["Cr_sv_GW"], 294 | "Cs" : ["Cs_sv_GW"], 295 | "Cu" : ["Cu_sv_GW","Cu_GW"], 296 | "F" : ["F_GW","F_GW_new","F_h_GW"], 297 | "Fe" : ["Fe_sv_GW","Fe_GW",], 298 | "Ga" : ["Ga_d_GW","Ga_GW","Ga_sv_GW"], 299 | "Ge" : ["Ge_d_GW","Ge_GW","Ge_sv_GW"], 300 | "H" : ["H_GW","H_h_GW"], 301 | "He" : ["He_GW"], 302 | "Hf" : ["Hf_sv_GW"], 303 | "Hg" : ["Hg_sv_GW"], 304 | "I" : ["I_GW","I_sv_GW"], 305 | "In" : ["In_d_GW","In_sv_GW"], 306 | "Ir" : ["Ir_sv_GW"], 307 | "K" : ["K_sv_GW"], 308 | "Kr" : ["Kr_GW"], 309 | "La" : ["La_GW"], 310 | "Li" : ["Li_sv_GW","Li_AE_GW","Li_GW"], 311 | "Mg" : ["Mg_sv_GW","Mg_GW","Mg_pv_GW"], 312 | "Mn" : ["Mn_sv_GW","Mn_GW"], 313 | "Mo" : ["Mo_sv_GW"], 314 | "N" : ["N_GW","N_GW_new","N_h_GW","N_s_GW"], 315 | "Na" : ["Na_sv_GW"], 316 | "Nb" : ["Nb_sv_GW"], 317 | "Ne" : ["Ne_GW","Ne_s_GW"], 318 | "Ni" : ["Ni_sv_GW","Ni_GW"], 319 | "O" : ["O_GW","O_GW_new","O_h_GW","O_s_GW"], 320 | "Os" : ["Os_sv_GW"], 321 | "P" : ["P_GW"], 322 | "Pb" : ["Pb_sv_GW","Pb_d_GW","Pd_GW"], 323 | "Pb" : ["Pd_sv_GW"], 324 | "Po" : ["Po_d_GW","Po_sv_GW"], 325 | "Pt" : ["Pt_sv_GW","Pt_GW"], 326 | "Rb" : ["Rb_sv_GW"], 327 | "Re" : ["Re_sv_GW"], 328 | "Rh" : ["Rh_sv_GW","Rh_GW"], 329 | "Rn" : ["Rn_d_GW","Rn_sv_GW"], 330 | "Ru" : ["Ru_sv_GW"], 331 | "S" : ["S_GW"], 332 | "Sb" : ["Sb_d_GW","Sb_GW","Sb_sv_GW"], 333 | "Sc" : ["Sc_sv_GW"], 334 | "Se" : ["Se_GW","Se_sv_GW"], 335 | "Si" : ["Si_GW","Si_sv_GW"], 336 | "Sn" : ["Sn_d_GW","Sn_sv_GW"], 337 | "Sr" : ["Sr_sv_GW"], 338 | "Ta" : ["Ta_sv_GW"], 339 | "Tc" : ["Tc_sv_GW"], 340 | "Te" : ["Te_GW","Te_sv_GW"], 341 | "Ti" : ["Ti_sv_GW"], 342 | "Tl" : ["Tl_d_GW","Tl_sv_GW"], 343 | "V" : ["V_sv_GW"], 344 | "W" : ["W_sv_GW"], 345 | "Xe" : ["Xe_GW","Xe_sv_GW"], 346 | "Y" : ["Y_sv_GW"], 347 | "Zn" : ["Zn_sv_GW","Zn_GW"], 348 | "Zr" : ["Zr_sv_GW"] 349 | } 350 | materialsproject = { 351 | "Ac" : ["Ac"], 352 | "Ag" : ["Ag"], 353 | "Al" : ["Al"], 354 | "Am" : ["Am"], 355 | "Ar" : [], 356 | "As" : ["As"], 357 | "At" : ["At_d"], 358 | "Au" : ["Au"], 359 | "B" : ["B"], 360 | "Ba" : ["Ba_sv"], 361 | "Be" : ["Be_sv"], 362 | "Bi" : ["Bi_d"], 363 | "Br" : ["Br"], 364 | "C" : ["C"], 365 | "Ca" : ["Ca_sv"], 366 | "Cd" : ["Cd"], 367 | "Ce" : ["Ce"], 368 | "Cf" : [], 369 | "Cl" : ["Cl"], 370 | "Cm" : [], 371 | "Co" : ["Co"], 372 | "Cr" : ["Cr_pv"], 373 | "Cs" : ["Cs_sv"], 374 | "Cu" : ["Cu_pv"], 375 | "Dy" : ["Dy_3"], 376 | "Er" : ["Er_3"], 377 | "Eu" : ["Eu"], 378 | "F" : ["F"], 379 | "Fe" : ["Fe_pv"], 380 | "Fr" : [], 381 | "Ga" : ["Ga_d"], 382 | "Gd" : ["Gd"], 383 | "Ge" : ["Ge_d"], 384 | "H" : ["H"], 385 | "He" : ["He"], 386 | "Hf" : ["Hf_pv"], 387 | "Hg" : ["Hg"], 388 | "Ho" : ["Ho_3"], 389 | "I" : [], 390 | "In" : ["In_d"], 391 | "Ir" : ["Ir"], 392 | "K" : ["K_sv"], 393 | "Kr" : [], 394 | "La" : ["La"], 395 | "Li" : ["Li_sv"], 396 | "Lu" : ["Lu_3"], 397 | "Mg" : ["Mg_pv"], 398 | "Mn" : ["Mn_pv"], 399 | "Mo" : ["Mo_pv"], 400 | "N" : ["N"], 401 | "Na" : ["Na_pv"], 402 | "Nb" : ["Nb_pv"], 403 | "Nd" : ["Nd_3"], 404 | "Ne" : [], 405 | "Ni" : ["Ni_pv"], 406 | "Np" : ["Np"], 407 | "O" : ["O"], 408 | "Os" : ["Os_pv"], 409 | "P" : ["P"], 410 | "Pa" : ["Pa"], 411 | "Pb" : ["Pb_d"], 412 | "Pd" : ["Pd"], 413 | "Pm" : ["Pm_3"], 414 | "Po" : ["Po"], 415 | "Pr" : ["Pr_3"], 416 | "Pt" : ["Pt"], 417 | "Pu" : ["Pu"], 418 | "Ra" : [], 419 | "Rb" : ["Rb_sv"], 420 | "Re" : ["Re_pv"], 421 | "Rh" : ["Rh_pv"], 422 | "Rn" : [], 423 | "Ru" : ["Ru_pv"], 424 | "S" : ["S"], 425 | "Sb" : [], 426 | "Sc" : ["Sc_sv"], 427 | "Se" : ["Se"], 428 | "Si" : ["Si"], 429 | "Sm" : ["Sm_3"], 430 | "Sn" : ["Sn_d"], 431 | "Sr" : ["Sr_sv"], 432 | "Ta" : ["Ta_pv"], 433 | "Tb" : ["Tb_3"], 434 | "Tc" : ["Tc_pv"], 435 | "Te" : [], 436 | "Th" : ["Th"], 437 | "Ti" : ["Ti_pv"], 438 | "Tl" : ["Tl_d"], 439 | "Tm" : ["Tm_3"], 440 | "U" : ["U"], 441 | "V" : ["V_sv"], 442 | "W" : ["W_pv"], 443 | "Xe" : [], 444 | "Y" : ["Y_sv"], 445 | "Yb" : ["Yb"], 446 | "Zn" : ["Zn"], 447 | "Zr" : ["Zr_sv"] 448 | } 449 | 450 | elif prm.xc == "LDA": 451 | PP_dir = os.environ.get("VASP_PP_PATH")+"/potpaw/" 452 | minimal = { 453 | "Ac" : ["Ac"], 454 | "Ag" : ["Ag","Ag_pv"], 455 | "Al" : ["Al"], 456 | "Am" : ["Am"], 457 | "Ar" : ["Ar"], 458 | "As" : ["As","As_d"], 459 | "At" : ["At"], 460 | "Au" : ["Au"], 461 | "B" : ["B","B_h","B_s"], 462 | "Ba" : ["Ba_sv"], 463 | "Be" : ["Be", "Be_sv"], 464 | "Bi" : ["Bi", "Bi_d"], 465 | "Br" : ["Br"], 466 | "C" : ["C","C_h","C_s"], 467 | "Ca" : ["Ca_pv","Ca_sv"], 468 | "Cd" : ["Cd"], 469 | "Ce" : ["Ce","Ce_h"], 470 | "Cl" : ["Cl","Cl_h"], 471 | "Cm" : ["Cm"], 472 | "Co" : ["Co","Co_pv","Co_sv"], 473 | "Cr" : ["Cr","Cr_pv","Cr_sv"], 474 | "Cs" : ["Cs_sv"], 475 | "Cu" : ["Cu","Cu_pv"], 476 | "F" : ["F","F_h","F_s"], 477 | "Fe" : ["Fe","Fe_pv","Fe_sv"], 478 | "Fr" : ["Fr_sv"], 479 | "Ga" : ["Ga","Ga_d","Ga_h"], 480 | "Ge" : ["Ge","Ge_d","Ge_h"], 481 | "H" : ["H","H.25","H.33","H.42","H.5","H.58","H.66","H.75","H1.25","H1.33","H1.5","H1.66","H1.75","H_AE","H_h","H_s"], 482 | "He" : ["He"], 483 | "Hf" : ["Hf","Hf_pv","Hf_sv"], 484 | "Hg" : ["Hg"], 485 | "I" : ["I"], 486 | "In" : ["In","In_d"], 487 | "Ir" : ["Ir"], 488 | "K" : ["K_pv","K_sv"], 489 | "Kr" : ["Kr"], 490 | "La" : ["La","La_s"], 491 | "Li" : ["Li","Li_sv"], 492 | "Mg" : ["Mg","Mg_pv","Mg_sv"], 493 | "Mn" : ["Mn","Mn_pv","Mn_sv"], 494 | "Mo" : ["Mo","Mo_pv","Mo_sv"], 495 | "N" : ["N","N_h","N_s"], 496 | "Na" : ["Na","Na_pv","Na_sv"], 497 | "Nb" : ["Nb_pv","Nb_sv"], 498 | "Ne" : ["Ne"], 499 | "Ni" : ["Ni","Ni_pv"], 500 | "Np" : ["Np","Np_s"], 501 | "O" : ["O","O_h","O_s"], 502 | "Os" : ["Os","Os_pv"], 503 | "P" : ["P","P_h"], 504 | "Pa" : ["Pa","Pa_s"], 505 | "Pb" : ["Pb","Pb_d"], 506 | "Pd" : ["Pd","Pd_pv"], 507 | "Po" : ["Po","Po_d"], 508 | "Pt" : ["Pt","Pt_pv"], 509 | "Pu" : ["Pu","Pu_s"], 510 | "Ra" : ["Ra_sv"], 511 | "Rb" : ["Rb_pv","Rb_sv"], 512 | "Re" : ["Re","Re_pv"], 513 | "Rh" : ["Rh","Rh_pv"], 514 | "Rn" : ["Rn"], 515 | "Ru" : ["Ru","Ru_pv","Ru_sv"], 516 | "S" : ["S","S_h"], 517 | "Sb" : ["Sb"], 518 | "Sc" : ["Sc","Sc_sv"], 519 | "Se" : ["Se"], 520 | "Si" : ["Si"], 521 | "Sn" : ["Sn","Sn_d"], 522 | "Sr" : ["Sr_sv"], 523 | "Ta" : ["Ta","Ta_pv"], 524 | "Tc" : ["Tc","Tc_pv","Tc_sv"], 525 | "Te" : ["Te"], 526 | "Th" : ["Th","Th_s"], 527 | "Ti" : ["Ti","Ti_pv","Ti_sv"], 528 | "Tl" : ["Tl","Tl_d"], 529 | "U" : ["U","U_s"], 530 | "V" : ["V","V_pv","V_sv"], 531 | "W" : ["W","W_pv","W_sv"], 532 | "Xe" : ["Xe"], 533 | "Y" : ["Y_sv"], 534 | "Zn" : ["Zn"], 535 | "Zr" : ["Zr_sv"] 536 | } 537 | 538 | #https://cms.mpi.univie.ac.at/vasp/vasp/Recommended_PAW_potentials_DFT_calculations_using_vasp_5_2.html 539 | recommended = { 540 | "Ac" : ["Ac"], 541 | "Ag" : ["Ag_pv","Ag"], 542 | "Al" : ["Al"], 543 | "Am" : ["Am"], 544 | "Ar" : ["Ar"], 545 | "As" : ["As","As_d"], 546 | "At" : ["At"], 547 | "Au" : ["Au"], 548 | "B" : ["B","B_h","B_s"], 549 | "Ba" : ["Ba_sv"], 550 | "Be" : ["Be", "Be_sv"], 551 | "Bi" : ["Bi_d","Bi"], 552 | "Br" : ["Br"], 553 | "C" : ["C","C_h","C_s"], 554 | "Ca" : ["Ca_sv","Ca_pv"], 555 | "Cd" : ["Cd"], 556 | "Ce" : ["Ce","Ce_h"], 557 | "Cl" : ["Cl","Cl_h"], 558 | "Cm" : ["Cm"], 559 | "Co" : ["Co","Co_pv","Co_sv"], 560 | "Cr" : ["Cr_pv","Cr","Cr_sv"], 561 | "Cs" : ["Cs_sv"], 562 | "Cu" : ["Cu","Cu_pv"], 563 | "F" : ["F","F_h","F_s"], 564 | "Fe" : ["Fe","Fe_pv","Fe_sv"], 565 | "Fr" : ["Fr_sv"], 566 | "Ga" : ["Ga_d","Ga","Ga_h"], 567 | "Ge" : ["Ge_d","Ge","Ge_h"], 568 | "H" : ["H","H.25","H.33","H.42","H.5","H.58","H.66","H.75","H1.25","H1.33","H1.5","H1.66","H1.75","H_AE","H_h","H_s"], 569 | "He" : ["He"], 570 | "Hf" : ["Hf_pv","Hf","Hf_sv"], 571 | "Hg" : ["Hg"], 572 | "I" : ["I"], 573 | "In" : ["In_d","In"], 574 | "Ir" : ["Ir"], 575 | "K" : ["K_sv","K_pv"], 576 | "Kr" : ["Kr"], 577 | "La" : ["La","La_s"], 578 | "Li" : ["Li_sv","Li"], 579 | "Mg" : ["Mg","Mg_pv","Mg_sv"], 580 | "Mn" : ["Mn_pv","Mn","Mn_sv"], 581 | "Mo" : ["Mo_sv","Mo","Mo_pv"], 582 | "N" : ["N","N_h","N_s"], 583 | "Na" : ["Na_pv","Na","Na_sv"], 584 | "Nb" : ["Nb_sv","Nb_pv"], 585 | "Ne" : ["Ne"], 586 | "Ni" : ["Ni","Ni_pv"], 587 | "Np" : ["Np","Np_s"], 588 | "O" : ["O","O_h","O_s"], 589 | "Os" : ["Os","Os_pv"], 590 | "P" : ["P","P_h"], 591 | "Pa" : ["Pa","Pa_s"], 592 | "Pb" : ["Pb_d","Pb"], 593 | "Pd" : ["Pd","Pd_pv"], 594 | "Po" : ["Po_d","Po"], 595 | "Pt" : ["Pt","Pt_pv"], 596 | "Pu" : ["Pu","Pu_s"], 597 | "Ra" : ["Ra_sv"], 598 | "Rb" : ["Rb_sv","Rb_pv"], 599 | "Re" : ["Re","Re_pv"], 600 | "Rh" : ["Rh_pv","Rh"], 601 | "Rn" : ["Rn"], 602 | "Ru" : ["Ru_pv","Ru","Ru_sv"], 603 | "S" : ["S","S_h"], 604 | "Sb" : ["Sb"], 605 | "Sc" : ["Sc_sv","Sc"], 606 | "Se" : ["Se"], 607 | "Si" : ["Si"], 608 | "Sn" : ["Sn_d","Sn"], 609 | "Sr" : ["Sr_sv"], 610 | "Ta" : ["Ta_pv","Ta"], 611 | "Tc" : ["Tc_pv","Tc","Tc_sv"], 612 | "Te" : ["Te"], 613 | "Th" : ["Th","Th_s"], 614 | "Ti" : ["Ti_sv","Ti","Ti_pv"], 615 | "Tl" : ["Tl_d","Tl"], 616 | "U" : ["U","U_s"], 617 | "V" : ["V_sv","V","V_pv"], 618 | "W" : ["W_sv","W","W_pv"], 619 | "Xe" : ["Xe"], 620 | "Y" : ["Y_sv"], 621 | "Zn" : ["Zn"], 622 | "Zr" : ["Zr_sv"] 623 | } 624 | gw = { 625 | "Ag" : ["Ag_sv_GW","Ag_GW"], 626 | "Al" : ["Al_GW","Al_sv_GW"], 627 | "Ar" : ["Ar_GW"], 628 | "As" : ["As_GW","As_sv_GW"], 629 | "At" : ["At_d_GW","At_sv_GW"], 630 | "Au" : ["Au_sv_GW","Au_GW"], 631 | "B" : ["B_GW"], 632 | "Ba" : ["Ba_sv_GW"], 633 | "Be" : ["Be_sv_GW","Be_GW"], 634 | "Bi" : ["Bi_d_GW","Bi_GW","Bi_sv_GW"], 635 | "Br" : ["Br_GW","Br_sv_GW"], 636 | "C" : ["C_GW","C_GW_new","C_h_GW"], 637 | "Ca" : ["Ca_sv_GW"], 638 | "Cd" : ["Cd_sv_GW","Cd_GW"], 639 | "Ce" : ["Ce_GW"], 640 | "Cl" : ["Cl_GW"], 641 | "Co" : ["Co_sv_GW","Co_GW"], 642 | "Cr" : ["Cr_sv_GW"], 643 | "Cs" : ["Cs_sv_GW"], 644 | "Cu" : ["Cu_sv_GW","Cu_GW"], 645 | "F" : ["F_GW","F_GW_new","F_h_GW"], 646 | "Fe" : ["Fe_sv_GW","Fe_GW",], 647 | "Ga" : ["Ga_d_GW","Ga_GW","Ga_sv_GW"], 648 | "Ge" : ["Ge_d_GW","Ge_GW","Ge_sv_GW"], 649 | "H" : ["H_GW","H_h_GW"], 650 | "He" : ["He_GW"], 651 | "Hf" : ["Hf_sv_GW"], 652 | "Hg" : ["Hg_sv_GW"], 653 | "I" : ["I_GW","I_sv_GW"], 654 | "In" : ["In_d_GW","In_sv_GW"], 655 | "Ir" : ["Ir_sv_GW"], 656 | "K" : ["K_sv_GW"], 657 | "Kr" : ["Kr_GW"], 658 | "La" : ["La_GW"], 659 | "Li" : ["Li_sv_GW","Li_AE_GW","Li_GW"], 660 | "Mg" : ["Mg_sv_GW","Mg_GW","Mg_pv_GW"], 661 | "Mn" : ["Mn_sv_GW","Mn_GW"], 662 | "Mo" : ["Mo_sv_GW"], 663 | "N" : ["N_GW","N_GW_new","N_h_GW","N_s_GW"], 664 | "Na" : ["Na_sv_GW"], 665 | "Nb" : ["Nb_sv_GW"], 666 | "Ne" : ["Ne_GW","Ne_s_GW"], 667 | "Ni" : ["Ni_sv_GW","Ni_GW"], 668 | "O" : ["O_GW","O_GW_new","O_h_GW","O_s_GW"], 669 | "Os" : ["Os_sv_GW"], 670 | "P" : ["P_GW"], 671 | "Pb" : ["Pb_sv_GW","Pb_d_GW","Pd_GW"], 672 | "Pb" : ["Pd_sv_GW"], 673 | "Po" : ["Po_d_GW","Po_sv_GW"], 674 | "Pt" : ["Pt_sv_GW","Pt_GW"], 675 | "Rb" : ["Rb_sv_GW"], 676 | "Re" : ["Re_sv_GW"], 677 | "Rh" : ["Rh_sv_GW","Rh_GW"], 678 | "Rn" : ["Rn_d_GW","Rn_sv_GW"], 679 | "Ru" : ["Ru_sv_GW"], 680 | "S" : ["S_GW"], 681 | "Sb" : ["Sb_d_GW","Sb_GW","Sb_sv_GW"], 682 | "Sc" : ["Sc_sv_GW"], 683 | "Se" : ["Se_GW","Se_sv_GW"], 684 | "Si" : ["Si_GW","Si_sv_GW"], 685 | "Sn" : ["Sn_d_GW","Sn_sv_GW"], 686 | "Sr" : ["Sr_sv_GW"], 687 | "Ta" : ["Ta_sv_GW"], 688 | "Tc" : ["Tc_sv_GW"], 689 | "Te" : ["Te_GW","Te_sv_GW"], 690 | "Ti" : ["Ti_sv_GW"], 691 | "Tl" : ["Tl_d_GW","Tl_sv_GW"], 692 | "V" : ["V_sv_GW"], 693 | "W" : ["W_sv_GW"], 694 | "Xe" : ["Xe_GW","Xe_sv_GW"], 695 | "Y" : ["Y_sv_GW"], 696 | "Zn" : ["Zn_sv_GW","Zn_GW"], 697 | "Zr" : ["Zr_sv_GW"] 698 | } 699 | 700 | # construct a list of POTCAR names 701 | #--------------------------------- 702 | file_list = [] 703 | if prm.setup == "recommended": 704 | for i in atom_list: 705 | file_list.append(recommended[i][0]) 706 | elif prm.setup == "minimal": 707 | for i in atom_list: 708 | file_list.append(minimal[i][0]) 709 | elif prm.setup == "gw": 710 | for i in atom_list: 711 | file_list.append(gw[i][0]) 712 | elif prm.setup == "materialsproject": 713 | if prm.xc == "PBE": 714 | for i in atom_list: 715 | if len(materialsproject[i]) == 0: 716 | sys.stdout.write("\033[1;31m" ) # set color red 717 | print("\n** ERROR: Not implemented. Choose from below:") 718 | sys.stdout.write("\033[0;0m") # reset color 719 | print(i+": ",recommended[i]) 720 | if float(sys.version.split()[0][:3]) < 3.0: 721 | inputstr = raw_input("--->>>:") 722 | else: 723 | inputstr = input("--->>>:") 724 | file_list.append(inputstr) 725 | else: 726 | file_list.append(materialsproject[i][0]) 727 | elif prm.xc == "LDA": 728 | sys.stdout.write("\033[1;31m" ) # set color red 729 | print("\n** ERROR: materialsproject option not implemented with LDA.") 730 | print("\n use PBE instead.") 731 | sys.stdout.write("\033[0;0m") # reset color 732 | sys.exit(0) 733 | elif prm.setup == "manual": 734 | for i in atom_list: 735 | print(i+": ",recommended[i]) 736 | if float(sys.version.split()[0][:3]) < 3.0: 737 | inputstr = raw_input("--->>>:") 738 | else: 739 | inputstr = input("--->>>:") 740 | file_list.append(inputstr) 741 | else: 742 | sys.stdout.write("\033[1;31m" ) # set color red 743 | print("** ERROR: wrong setup.") 744 | sys.stdout.write("\033[0;0m") # reset color 745 | sys.exit(0) 746 | 747 | # Combine file_list 748 | #------------------ 749 | if prm.over == True or prm.over == False and os.path.exists("POTCAR") == False: 750 | with open('POTCAR', 'w+') as outfile: 751 | for fname in file_list: 752 | with open(PP_dir+fname+"/POTCAR") as infile: 753 | for line in infile: 754 | outfile.write(line) 755 | elif prm.over == False and os.path.exists("POTCAR") == True: 756 | sys.stdout.write("\033[1;31m" ) # set color red 757 | print("\n** ERROR: POTCAR exist. use -o to override.") 758 | sys.stdout.write("\033[0;0m") # reset color 759 | sys.exit(0) 760 | 761 | 762 | 763 | if prm.prt == True: 764 | # Post process 765 | #------------- 766 | endtime = time.time() 767 | runtime = endtime-starttime 768 | print("\nFinished.") 769 | print("Program was running for %.2f seconds." % runtime) 770 | -------------------------------------------------------------------------------- /VASP/spincar.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A script to extract spindensity form CHGCAR file. 4 | User must specify filename in command line. 5 | eg. python spincar.py CHGCAR 6 | ** Does NOT work with Molecular dynamics output. 7 | Depends on ase 8 | """ 9 | 10 | from __future__ import print_function 11 | import argparse 12 | import os 13 | import sys 14 | import numpy as np 15 | import math 16 | import string 17 | import datetime 18 | import time 19 | from ase.calculators.vasp import VaspChargeDensity 20 | 21 | 22 | # Command line praser 23 | #---------------------------- 24 | parser = argparse.ArgumentParser(description='A script to calculate the spin density.') 25 | parser.add_argument('CHGCAR', nargs='*', help="name of the CHGCAR files.") 26 | 27 | prm = parser.parse_args() 28 | 29 | starttime = time.time() 30 | print("Starting calculation at",end='') 31 | print(time.strftime("%H:%M:%S on %a %d %b %Y")) 32 | 33 | 34 | # Find out how many arguments were on the command line, 35 | nsubtract = len(prm.CHGCAR) 36 | if not nsubtract == 1: 37 | print("\n** ERROR: Must specify the name of file on command line.") 38 | print("eg. chgdiff.py CHGCAR") 39 | print("Only one file name are allowed") 40 | sys.exit(0) 41 | 42 | if not os.path.isfile(prm.CHGCAR[0]): 43 | print("\n** ERROR: Input file %s was not found." % prm.CHGCAR[0]) 44 | sys.exit(0) 45 | 46 | 47 | # Read information from command line 48 | # First specify location of CHGCAR 49 | CHGCARfile = prm.CHGCAR[0].lstrip() 50 | 51 | 52 | # Open geometry and density class objects 53 | #----------------------------------------- 54 | vasp_charge = VaspChargeDensity(filename = CHGCARfile) 55 | if len(vasp_charge.chgdiff) == 3: 56 | spin=3 57 | print("\nReading spin orbital potential data from file %s ... " % CHGCARfile,end='') 58 | sys.stdout.flush() 59 | atoms = vasp_charge.atoms[-1] 60 | potl_total = vasp_charge.chg[-1] 61 | potl_x = vasp_charge.chgdiff[0] 62 | potl_y = vasp_charge.chgdiff[1] 63 | potl_z = vasp_charge.chgdiff[2] 64 | if not potl_total.shape == potl_x.shape == potl_y.shape == potl_z.shape: 65 | print("\n**ERROR: Two sets of data are not on the same grid.") 66 | print("Data from data block 1 on %dx%dx%d grid." % (potl_total.shape[0],potl_total.shape[1],potl_total.shape[2])) 67 | print("Data from data block 2 on %dx%dx%d grid." % (potl_x.shape[0],potl_x.shape[1],potl_x.shape[2])) 68 | print("Data from data block 3 on %dx%dx%d grid." % (potl_y.shape[0],potl_y.shape[1],potl_y.shape[2])) 69 | print("Data from data block 4 on %dx%dx%d grid." % (potl_z.shape[0],potl_z.shape[1],potl_z.shape[2])) 70 | sys.exit(0) 71 | else: 72 | print('done.') 73 | 74 | elif len(vasp_charge.chgdiff) == 1: 75 | spin=2 76 | print("\nReading spin polarized potential data from file %s ... " % CHGCARfile,end='') 77 | sys.stdout.flush() 78 | atoms = vasp_charge.atoms[-1] 79 | potl_updown = vasp_charge.chg[-1] 80 | potl_upmdown = vasp_charge.chgdiff[0] 81 | if not potl_updown.shape == potl_upmdown.shape: 82 | print("\n**ERROR: Two sets of data are not on the same grid.") 83 | print("Data from data block 1 on %dx%dx%d grid." % (potl_updown.shape[0],potl_updown.shape[1],potl_updown.shape[2])) 84 | print("Data from data block 2 on %dx%dx%d grid." % (potl_updown.shape[0],potl_upmdown.shape[1],potl_upmdown.shape[2])) 85 | sys.exit(0) 86 | else: 87 | # get density for each spin channels 88 | potl_up = (potl_updown+potl_upmdown)/2 89 | potl_down = (potl_updown-potl_upmdown)/2 90 | print('done.') 91 | 92 | elif len(vasp_charge.chgdiff) == 0: 93 | spin=1 94 | print("\nReading spin paired potential data from file %s ... " % CHGCARfile, end='') 95 | sys.stdout.flush() 96 | print("\nFile only contains one block of data, check if is polarized calculation.") 97 | sys.exit(0) 98 | 99 | else: 100 | print("\n** ERROR: CHGCAR data block error, total of %s data blocks was found." % len(vasp_charge.chg)) 101 | sys.exit(0) 102 | 103 | del vasp_charge 104 | 105 | 106 | # Exctract data 107 | #------------------------ 108 | if spin == 3: # SOC 109 | chg_total = VaspChargeDensity(filename=None) 110 | chg_total.atoms=[atoms,] 111 | chg_total.chg=[potl_total,] 112 | 113 | chg_x = VaspChargeDensity(filename=None) 114 | chg_x.atoms=[atoms,] 115 | chg_x.chg=[potl_x,] 116 | 117 | chg_y = VaspChargeDensity(filename=None) 118 | chg_y.atoms=[atoms,] 119 | chg_y.chg=[potl_y,] 120 | 121 | chg_z = VaspChargeDensity(filename=None) 122 | chg_z.atoms=[atoms,] 123 | chg_z.chg=[potl_z,] 124 | 125 | # Print out charge density 126 | #-------------------------- 127 | # Check whether CHGDIFF exists 128 | for chgfiles in ['SPINCAR_total.vasp','SPINCAR_x.vasp','SPINCAR_y.vasp','SPINCAR_z.vasp']: 129 | if os.path.isfile("./"+i): 130 | print("\n**WARNING: A file called CHGDIFF already exists in this directory.") 131 | if float(sys.version.split()[0][:3]) < 3.0: 132 | yesno=raw_input("Type y to continue and overwrite it, any other key to stop\n") 133 | else: 134 | yesno=input("Type y to continue and overwrite it, any other key to stop\n") 135 | if yesno!="y": 136 | sys.exit(0) 137 | # Writing data ... 138 | print("Writing density difference data to file ...", end='') 139 | sys.stdout.flush() 140 | chg_total.write(filename="SPINCAR_total.vasp",format="chgcar") 141 | chg_x.write(filename="SPINCAR_x.vasp",format="chgcar") 142 | chg_y.write(filename="SPINCAR_y.vasp",format="chgcar") 143 | chg_z.write(filename="SPINCAR_z.vasp",format="chgcar") 144 | # adding atomic species 145 | fin = [atoms.get_chemical_symbols()[0]] 146 | for i in range(len(atoms.get_chemical_symbols())): 147 | if i == len(atoms.get_chemical_symbols())-1: break 148 | if atoms.get_chemical_symbols()[i] != atoms.get_chemical_symbols()[i+1]: 149 | fin.append(atoms.get_chemical_symbols()[i+1]) 150 | 151 | for chgfiles in ['SPINCAR_total.vasp','SPINCAR_x.vasp','SPINCAR_y.vasp','SPINCAR_z.vasp']: 152 | f = open(chgfiles, "r") 153 | contents = f.readlines() 154 | f.close() 155 | 156 | contents.insert(5, ' '.join(fin)+'\n') 157 | 158 | f = open(chgfiles, "w") 159 | contents = "".join(contents) 160 | f.write(contents) 161 | f.close() 162 | print("done.") 163 | 164 | if spin == 2: # Spin polarized 165 | chg_updown = VaspChargeDensity(filename=None) 166 | chg_updown.atoms=[atoms,] 167 | chg_updown.chg=[potl_updown,] 168 | 169 | chg_upmdown = VaspChargeDensity(filename=None) 170 | chg_upmdown.atoms=[atoms,] 171 | chg_upmdown.chg=[potl_upmdown,] 172 | 173 | chg_up = VaspChargeDensity(filename=None) 174 | chg_up.atoms=[atoms,] 175 | chg_up.chg=[potl_up,] 176 | 177 | chg_down = VaspChargeDensity(filename=None) 178 | chg_down.atoms=[atoms,] 179 | chg_down.chg=[potl_down,] 180 | 181 | # Print out charge density 182 | #-------------------------- 183 | # Check whether CHGDIFF exists 184 | for chgfiles in ['SPINCAR_up+down.vasp','SPINCAR_up-down.vasp','SPINCAR_up.vasp','SPINCAR_down.vasp']: 185 | if os.path.isfile("./"+chgfiles): 186 | print("\n**WARNING: A file called ' " + chgfiles + " ' already exists in this directory.") 187 | if float(sys.version.split()[0][:3]) < 3.0: 188 | yesno=raw_input("Type y to continue and overwrite it, any other key to stop\n") 189 | else: 190 | yesno=input("Type y to continue and overwrite it, any other key to stop\n") 191 | if yesno!="y": 192 | sys.exit(0) 193 | # Writing data ... 194 | print("\nWriting density difference data to file ...", end='') 195 | sys.stdout.flush() 196 | chg_updown.write(filename="SPINCAR_up+down.vasp",format="chgcar") 197 | chg_upmdown.write(filename="SPINCAR_up-down.vasp",format="chgcar") 198 | chg_up.write(filename="SPINCAR_up.vasp",format="chgcar") 199 | chg_down.write(filename="SPINCAR_down.vasp",format="chgcar") 200 | 201 | if float(sys.version.split()[0][:3]) < 3.0: 202 | # adding atomic species 203 | fin = [atoms.get_chemical_symbols()[0]] 204 | for i in range(len(atoms.get_chemical_symbols())): 205 | if i == len(atoms.get_chemical_symbols())-1: break 206 | if atoms.get_chemical_symbols()[i] != atoms.get_chemical_symbols()[i+1]: 207 | fin.append(atoms.get_chemical_symbols()[i+1]) 208 | 209 | for chgfiles in ['SPINCAR_up+down.vasp','SPINCAR_up-down.vasp','SPINCAR_up.vasp','SPINCAR_down.vasp']: 210 | f = open(chgfiles, "r") 211 | contents = f.readlines() 212 | f.close() 213 | 214 | contents.insert(5, ' '.join(fin)+'\n') 215 | 216 | f = open(chgfiles, "w") 217 | contents = "".join(contents) 218 | f.write(contents) 219 | f.close() 220 | print("done.") 221 | 222 | # Post process 223 | #------------------- 224 | endtime = time.time() 225 | runtime = endtime-starttime 226 | print("\nEnd of calculation.") 227 | print("Program was running for %.2f seconds." % runtime) 228 | -------------------------------------------------------------------------------- /VASP/vasp_clean.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A script to clean current working dir. 4 | """ 5 | 6 | from __future__ import print_function 7 | import os 8 | import sys 9 | import argparse 10 | 11 | # Command line praser 12 | #---------------------------- 13 | parser = argparse.ArgumentParser(description='A script to clean current working dir.') 14 | parser.add_argument('-f','--force', action="store_true", default=False, dest='force', 15 | help='Remove without warning? (Default=False)') 16 | parser.add_argument('-a','--add', nargs='+', action="store", default=None, dest="additional", 17 | help='Additional files to retain.') 18 | 19 | prm = parser.parse_args() 20 | 21 | # get a list of objects under current dir 22 | dir_file = os.listdir('./') 23 | 24 | # target files 25 | files = ['INCAR', 'KPOINTS', 'POSCAR', 'POTCAR', 'vdw_kernel.bindat', '.pbs', 'wanier90'] 26 | 27 | if prm.additional != None: 28 | files += prm.additional 29 | 30 | # exclude target files 31 | for i in files: 32 | dir_file = [x for x in dir_file if not x.startswith(i)] 33 | dir_file = [x for x in dir_file if not x.endswith(i)] 34 | 35 | # exclude directories 36 | dir_file = [i for i in dir_file if not os.path.isdir(i)] 37 | 38 | if prm.force == False: 39 | # Warning is very much needed! 40 | print('Removing:\n\t','\n\t'.join(dir_file)) 41 | if float(sys.version.split()[0][:3]) < 3.0: 42 | val = raw_input("Are you sure? (y/n) ") 43 | else: 44 | val = input("Are you sure? (y/n) ") 45 | if val == 'y': 46 | # remove files 47 | for file in dir_file: 48 | os.remove(file) 49 | print('done.') 50 | elif val == 'n': 51 | print("exiting...") 52 | else: 53 | print('Input not accepted, exiting...') 54 | exit() 55 | else: 56 | # remove files 57 | for file in dir_file: 58 | os.remove(file) 59 | -------------------------------------------------------------------------------- /VASP/vaspwfc/plotwfc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A wrapper to plot VASP's pseudo wave-functions 4 | Depends on vasp_constant and vaspwfc 5 | """ 6 | 7 | from __future__ import print_function 8 | import argparse, os 9 | from vaspwfc import vaspwfc 10 | 11 | # Command line praser 12 | #---------------------------- 13 | # Do we want to convert the final structure into use primitive cell? 14 | parser = argparse.ArgumentParser(description="A script to plot VASP's pseudo-wavefunction and related densities.") 15 | parser.add_argument('-elf', action="store_true", default=False, dest="lelf", 16 | help='Calculate ELF? (Default=False)') 17 | parser.add_argument('-chg', action="store_true", default=False, dest="lchg", 18 | help='Calculate band decomposed charge? (Default=False)') 19 | parser.add_argument('-soc', '-ncl',action="store_true", default=False, dest='lsorbit', 20 | help='is spinor WAVECAR?. (Default=False)') 21 | parser.add_argument('-s', action="store", default=1, type=int, dest="ispin", 22 | help='spin component (Default=1; 1->up, 2->down, 3->both)') 23 | parser.add_argument('-ssoc', action="store", default=1, type=int, dest="ispinsoc", 24 | help='spin component (Default=1; 1->up, 2->down, 3->both)') 25 | parser.add_argument('-b', action="store", default=1, type=int, dest="iband", 26 | help='band number (Default=1)') 27 | parser.add_argument('-k', action="store", default=1, type=int, dest="ikpt", 28 | help='k-point number (Default=1)') 29 | parser.add_argument('-o','--OUTCAR', action="store", default=str('./OUTCAR'), dest="OUTCAR", 30 | help='input OUTCAR name (Default=./OUTCAR)') 31 | parser.add_argument('-w','--WAVECAR', action="store", default=str('./WAVECAR'), dest="WAVECAR", 32 | help='input WAVECAR name (Default=./WAVECAR)') 33 | parser.add_argument('-c','--POSCAR', action="store", default=str('./POSCAR'), dest="POSCAR", 34 | help='input POSCAR name (Default=./POSCAR)') 35 | parser.add_argument('-g', '--gamma', action="store_true", default=False, dest="lgamma", 36 | help='vasp_gam ? (Default=False)') 37 | prm = parser.parse_args() 38 | 39 | # Starting 40 | #---------------------------- 41 | #starttime = time.clock() 42 | #print "Starting calculation at", 43 | #print time.strftime("%H:%M:%S on %a %d %b %Y") 44 | 45 | # check input 46 | #---------------------------- 47 | if not os.path.isfile(prm.OUTCAR): 48 | print("\n** ERROR: file %s not found." % prm.OURCAR) 49 | sys.exit(0) 50 | 51 | if not os.path.isfile(prm.WAVECAR): 52 | print("\n** ERROR: file %s not found." % prm.WAVECAR) 53 | sys.exit(0) 54 | 55 | if not os.path.isfile(prm.POSCAR): 56 | print("\n** ERROR: file %s not found." % prm.POSCAR) 57 | sys.exit(0) 58 | 59 | # Reading wfc 60 | #---------------------------- 61 | if prm.lgamma: 62 | wav = vaspwfc(prm.WAVECAR, lsorbit=prm.lsorbit, lgamma=True, gamma_half='x') 63 | else: 64 | wav = vaspwfc(prm.WAVECAR, lsorbit=prm.lsorbit) 65 | # KS orbital in real space, double the size of the FT grid 66 | phi = wav.wfc_r(ispin=prm.ispin,ikpt=prm.ikpt, iband=prm.iband, ngrid=wav._ngrid * 2) 67 | 68 | # Processing data 69 | #---------------------------- 70 | if prm.lelf == True: 71 | warning = """ 72 | #-------------------------- WARNING ------------------------------# 73 | * ELF mode only suuports ISYM=-1. * 74 | #-----------------------------------------------------------------# 75 | """ 76 | print(warning) 77 | # get weight of each kpt 78 | kptw = [] 79 | with open('IBZKPT') as fp: 80 | lines = fp.readlines() 81 | num_kpts = int(lines[1].rstrip("\n")) 82 | for i in lines[3:3+num_kpts]: 83 | kptw.append(int(i.rstrip("\n").split()[3])) 84 | # Calculate elf 85 | fin_elf = wav.elf(kptw,warn=False) 86 | # Save elf 87 | wav.save2vesta(fin_elf[0], prefix="ELF", lreal=True, poscar=prm.POSCAR) 88 | # Rename elf 89 | os.rename("ELF_r.vasp", "ELFCAR_WAV.vasp") 90 | elif prm.lelf == False: 91 | if prm.lsorbit == False: 92 | if prm.lchg == True: 93 | wav.save2vesta(phi, prefix="WAV."+str(prm.ikpt).zfill(4)+'.'+str(prm.iband).zfill(4)+'.'+str(prm.ispin).zfill(1), poscar=prm.POSCAR, lchg=True) 94 | else: 95 | wav.save2vesta(phi, prefix="WAV."+str(prm.ikpt).zfill(4)+'.'+str(prm.iband).zfill(4)+'.'+str(prm.ispin).zfill(1), poscar=prm.POSCAR) 96 | elif prm.lsorbit == True: 97 | if prm.lchg == True: 98 | print("\n** ERROR: charge plot does not support SOC.") 99 | else: 100 | print("spin component:",prm.ispinsoc) 101 | wav.save2vesta(phi[prm.ispinsoc], prefix='socWAV.'+str(prm.ikpt).zfill(4)+'.'+str(prm.iband).zfill(4)+'.'+str(prm.ispin).zfill(1), poscar=prm.POSCAR) 102 | else: 103 | print("\n** ERROR: something wrong.") 104 | sys.exit(0) 105 | else: 106 | print("\n** ERROR: something wrong.") 107 | sys.exit(0) 108 | -------------------------------------------------------------------------------- /VASP/vaspwfc/vasp_constant.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | Physical constants used in VASP 4 | ''' 5 | 6 | # Some important Parameters, to convert to a.u. 7 | # - AUTOA = 1. a.u. in Angstroem 8 | # - RYTOEV = 1 Ry in Ev 9 | # - EVTOJ = 1 eV in Joule 10 | # - AMTOKG = 1 atomic mass unit ("proton mass") in kg 11 | # - BOLKEV = Boltzmanns constant in eV/K 12 | # - BOLK = Boltzmanns constant in Joule/K 13 | 14 | AUTOA = 0.529177249 15 | RYTOEV = 13.605826 16 | CLIGHT = 137.037 # speed of light in a.u. 17 | EVTOJ = 1.60217733E-19 18 | AMTOKG = 1.6605402E-27 19 | BOLKEV = 8.6173857E-5 20 | BOLK = BOLKEV * EVTOJ 21 | EVTOKCAL = 23.06 22 | 23 | # FELECT = (the electronic charge)/(4*pi*the permittivity of free space) 24 | # in atomic units this is just e^2 25 | # EDEPS = electron charge divided by the permittivity of free space 26 | # in atomic units this is just 4 pi e^2 27 | # HSQDTM = (plancks CONSTANT/(2*PI))**2/(2*ELECTRON MASS) 28 | # 29 | PI = 3.141592653589793238 30 | TPI = 2 * PI 31 | CITPI = 1j * TPI 32 | FELECT = 2 * AUTOA * RYTOEV 33 | EDEPS = 4 * PI * 2 * RYTOEV * AUTOA 34 | HSQDTM = RYTOEV * AUTOA * AUTOA 35 | 36 | # vector field A times momentum times e/ (2 m_e c) is an energy 37 | # magnetic moments are supplied in Bohr magnetons 38 | # e / (2 m_e c) A(r) p(r) = energy 39 | # e / (2 m_e c) m_s x ( r - r_s) / (r-r_s)^3 hbar nabla = 40 | # e^2 hbar^2 / (2 m_e^2 c^2) 1/ lenght^3 = energy 41 | # conversion factor from magnetic moment to energy 42 | # checked independently in SI by Gilles de Wijs 43 | 44 | MAGMOMTOENERGY = 1 / CLIGHT**2 * AUTOA**3 * RYTOEV 45 | 46 | # dimensionless number connecting input and output magnetic moments 47 | # AUTOA e^2 (2 m_e c^2) 48 | MOMTOMOM = AUTOA / CLIGHT / CLIGHT / 2 49 | AUTOA2 = AUTOA * AUTOA 50 | AUTOA3 = AUTOA2 * AUTOA 51 | AUTOA4 = AUTOA2 * AUTOA2 52 | AUTOA5 = AUTOA3 * AUTOA2 53 | 54 | # dipole moment in atomic units to Debye 55 | AUTDEBYE = 2.541746 56 | -------------------------------------------------------------------------------- /VASP/vaspwfc/vaspwfc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import numpy as np 6 | from math import sqrt 7 | from vasp_constant import * 8 | from multiprocessing import cpu_count 9 | from scipy.fftpack import fftfreq, fftn, ifftn 10 | 11 | ############################################################ 12 | def save2vesta(phi=None, poscar='POSCAR', prefix='wfc', 13 | lgam=False, lreal=False, lchg=False, ncol=10): 14 | ''' 15 | Save the real space pseudo-wavefunction as vesta format. 16 | ''' 17 | nx, ny, nz = phi.shape 18 | try: 19 | pos = open(poscar, 'r') 20 | head = '' 21 | for line in pos: 22 | if line.strip(): 23 | head += line 24 | else: 25 | break 26 | head += '\n%5d%5d%5d\n' % (nx, ny, nz) 27 | except: 28 | raise IOError('Failed to open %s' % poscar) 29 | 30 | # Faster IO 31 | nrow = phi.size // ncol 32 | nrem = phi.size % ncol 33 | fmt = "%16.8E" 34 | 35 | psi = phi.copy() 36 | psi = psi.flatten(order='F') 37 | psi_h = psi[:nrow * ncol].reshape((nrow, ncol)) 38 | psi_r = psi[nrow * ncol:] 39 | 40 | if not lchg: 41 | with open(prefix + '_r.vasp', 'w') as out: 42 | out.write(head) 43 | out.write( 44 | '\n'.join([''.join([fmt % xx for xx in row]) 45 | for row in psi_h.real]) 46 | ) 47 | out.write("\n" + ''.join([fmt % xx for xx in psi_r.real])) 48 | if not (lgam or lreal): 49 | with open(prefix + '_i.vasp', 'w') as out: 50 | out.write(head) 51 | out.write( 52 | '\n'.join([''.join([fmt % xx for xx in row]) 53 | for row in psi_h.imag]) 54 | ) 55 | out.write("\n" + ''.join([fmt % xx for xx in psi_r.imag])) 56 | else: 57 | with open(prefix + '_chg.vasp', 'w') as out: 58 | out.write(head) 59 | out.write( 60 | '\n'.join([''.join([fmt % xx for xx in row]) 61 | for row in (psi_h.real**2 + psi_h.imag**2)]) 62 | ) 63 | out.write("\n" + ''.join([fmt % xx for xx in (psi_r.real**2 + psi_r.imag**2)])) 64 | 65 | ############################################################ 66 | 67 | class vaspwfc(object): 68 | ''' 69 | Class for processing VASP Pseudowavefunction stored in WAVECAR. This 70 | program is motivated by PIESTA written by Ren Hao . 71 | 72 | The format of VASP WAVECAR, as shown in 73 | http://www.andrew.cmu.edu/user/feenstra/wavetrans/ 74 | is: 75 | Record-length #spin components RTAG(a value specifying the precision) 76 | #k-points #bands ENCUT(maximum energy for plane waves) 77 | LatVec-A 78 | LatVec-B 79 | LatVec-C 80 | Loop over spin 81 | Loop over k-points 82 | #plane waves, k vector 83 | Loop over bands 84 | band energy, band occupation 85 | End loop over bands 86 | Loop over bands 87 | Loop over plane waves 88 | Plane-wave coefficient 89 | End loop over plane waves 90 | End loop over bands 91 | End loop over k-points 92 | End loop over spin 93 | ''' 94 | 95 | def __init__(self, fnm='WAVECAR', lsorbit=False, lgamma=False, 96 | gamma_half='z', omp_num_threads=1): 97 | ''' 98 | Initialization. 99 | ''' 100 | 101 | self._fname = fnm 102 | # the directory containing the input file 103 | self._dname = os.path.dirname(fnm) 104 | if self._dname == '': 105 | self._dname = '.' 106 | 107 | self._lsoc = lsorbit 108 | self._lgam = lgamma 109 | self._gam_half = gamma_half.lower() 110 | 111 | # It seems that some modules in scipy uses OPENMP, it is therefore 112 | # desirable to set the OMP_NUM_THREADS to tune the parallization. 113 | os.environ['OMP_NUM_THREADS'] = str(omp_num_threads) 114 | 115 | assert not (lsorbit and lgamma), 'The two settings conflict!' 116 | assert self._gam_half == 'x' or self._gam_half == 'z', \ 117 | 'Gamma_half must be "x" or "z"' 118 | 119 | try: 120 | self._wfc = open(self._fname, 'rb') 121 | except: 122 | raise IOError('Failed to open %s' % self._fname) 123 | 124 | # read the basic information 125 | self.readWFHeader() 126 | # read the band information 127 | self.readWFBand() 128 | 129 | if self._lsoc: 130 | assert self._nspin == 1, "NSPIN = 1 for noncollinear version WAVECAR!" 131 | 132 | def set_omp_num_threads(self, nproc): 133 | ''' 134 | Set the OMP_NUM_THREADS envrionment variable 135 | ''' 136 | assert 1 <= nproc <= cpu_count() 137 | 138 | os.envrion['OMP_NUM_THREADS'] = str(nproc) 139 | 140 | def isSocWfc(self): 141 | """ 142 | Is the WAVECAR from an SOC calculation? 143 | """ 144 | return True if self._lsoc else False 145 | 146 | def isGammaWfc(self): 147 | """ 148 | Is the WAVECAR from an SOC calculation? 149 | """ 150 | return True if self._lgam else False 151 | 152 | def readWFHeader(self): 153 | ''' 154 | Read the system information from WAVECAR, which is written in the first 155 | two record. 156 | 157 | rec1: recl, nspin, rtag 158 | rec2: nkpts, nbands, encut, ((cell(i,j) i=1, 3), j=1, 3) 159 | ''' 160 | 161 | # goto the start of the file and read the first record 162 | self._wfc.seek(0) 163 | self._recl, self._nspin, self._rtag = np.array( 164 | np.fromfile(self._wfc, dtype=float, count=3), 165 | dtype=int 166 | ) 167 | self._WFPrec = self.setWFPrec() 168 | # the second record 169 | self._wfc.seek(self._recl) 170 | dump = np.fromfile(self._wfc, dtype=float, count=12) 171 | 172 | self._nkpts = int(dump[0]) # No. of k-points 173 | self._nbands = int(dump[1]) # No. of bands 174 | self._encut = dump[2] # Energy cutoff 175 | self._Acell = dump[3:].reshape((3,3)) # real space supercell basis 176 | self._Omega = np.linalg.det(self._Acell) # real space supercell volume 177 | self._Bcell = np.linalg.inv(self._Acell).T # reciprocal space supercell volume 178 | 179 | # Minimum FFT grid size 180 | Anorm = np.linalg.norm(self._Acell, axis=1) 181 | CUTOF = np.ceil( 182 | sqrt(self._encut / RYTOEV) / (TPI / (Anorm / AUTOA)) 183 | ) 184 | self._ngrid = np.array(2 * CUTOF + 1, dtype=int) 185 | 186 | def setWFPrec(self): 187 | ''' 188 | Set wavefunction coefficients precision: 189 | TAG = 45200: single precision complex, np.complex64, or complex(qs) 190 | TAG = 45210: double precision complex, np.complex128, or complex(q) 191 | ''' 192 | if self._rtag == 45200: 193 | return np.complex64 194 | elif self._rtag == 45210: 195 | return np.complex128 196 | elif self._rtag == 53300: 197 | raise ValueError("VASP5 WAVECAR format, not implemented yet") 198 | elif self._rtag == 53310: 199 | raise ValueError("VASP5 WAVECAR format with double precision " 200 | +"coefficients, not implemented yet") 201 | else: 202 | raise ValueError("Invalid TAG values: {}".format(self._rtag)) 203 | 204 | def readWFBand(self): 205 | ''' 206 | Extract KS energies and Fermi occupations from WAVECAR. 207 | ''' 208 | 209 | self._nplws = np.zeros(self._nkpts, dtype=int) 210 | self._kvecs = np.zeros((self._nkpts, 3), dtype=float) 211 | self._bands = np.zeros((self._nspin, self._nkpts, self._nbands), dtype=float) 212 | self._occs = np.zeros((self._nspin, self._nkpts, self._nbands), dtype=float) 213 | 214 | for ii in range(self._nspin): 215 | for jj in range(self._nkpts): 216 | rec = self.whereRec(ii+1, jj+1, 1) - 1 217 | self._wfc.seek(rec * self._recl) 218 | dump = np.fromfile(self._wfc, dtype=float, count=4+3*self._nbands) 219 | if ii == 0: 220 | self._nplws[jj] = int(dump[0]) 221 | self._kvecs[jj] = dump[1:4] 222 | dump = dump[4:].reshape((-1, 3)) 223 | self._bands[ii,jj,:] = dump[:,0] 224 | self._occs[ii,jj,:] = dump[:,2] 225 | 226 | if self._nkpts > 1: 227 | tmp = np.linalg.norm( 228 | np.dot(np.diff(self._kvecs, axis=0), self._Bcell), axis=1) 229 | self._kpath = np.concatenate(([0,], np.cumsum(tmp))) 230 | else: 231 | self._kpath = None 232 | return self._kpath, self._bands 233 | 234 | def get_kpath(self, nkseg=None): 235 | ''' 236 | Construct k-point path, find out the k-path boundary if possible. 237 | 238 | nkseg is the number of k-points in each k-path segments. 239 | ''' 240 | 241 | if nkseg is None: 242 | if os.path.isfile(self._dname + "/KPOINTS"): 243 | kfile = open(self._dname + "/KPOINTS").readlines() 244 | if kfile[2][0].upper() == 'L': 245 | nkseg = int(kfile[1].split()[0]) 246 | else: 247 | raise ValueError('Error reading number of k-points from KPOINTS') 248 | assert nkseg > 0 249 | 250 | nsec = self._nkpts // nkseg 251 | 252 | v = self._kvecs.copy() 253 | for ii in range(nsec): 254 | ki = ii * nkseg 255 | kj = (ii + 1) * nkseg 256 | v[ki:kj,:] -= v[ki] 257 | 258 | self._kpath = np.linalg.norm(np.dot(v, self._Bcell), axis=1) 259 | for ii in range(1, nsec): 260 | ki = ii * nkseg 261 | kj = (ii + 1) * nkseg 262 | self._kpath[ki:kj] += self._kpath[ki - 1] 263 | 264 | self._kbound = np.concatenate((self._kpath[0::nkseg], [self._kpath[-1],])) 265 | 266 | return self._kpath, self._kbound 267 | 268 | def gvectors(self, ikpt=1, force_Gamma=False, check_consistency=True): 269 | ''' 270 | Generate the G-vectors that satisfies the following relation 271 | (G + k)**2 / 2 < ENCUT 272 | ''' 273 | assert 1 <= ikpt <= self._nkpts, 'Invalid kpoint index!' 274 | 275 | kvec = self._kvecs[ikpt-1] 276 | # fx, fy, fz = [fftfreq(n) * n for n in self._ngrid] 277 | # fftfreq in scipy.fftpack is a little different with VASP frequencies 278 | fx = [ii if ii < self._ngrid[0] / 2 + 1 else ii - self._ngrid[0] 279 | for ii in range(self._ngrid[0])] 280 | fy = [jj if jj < self._ngrid[1] / 2 + 1 else jj - self._ngrid[1] 281 | for jj in range(self._ngrid[1])] 282 | fz = [kk if kk < self._ngrid[2] / 2 + 1 else kk - self._ngrid[2] 283 | for kk in range(self._ngrid[2])] 284 | 285 | # force_Gamma: consider gamma-only case regardless of the real setting 286 | lgam = True if force_Gamma else self._lgam 287 | if lgam: 288 | # parallel gamma version of VASP WAVECAR exclude some planewave 289 | # components, -DwNGZHalf 290 | if self._gam_half == 'z': 291 | kgrid = np.array([(fx[ii], fy[jj], fz[kk]) 292 | for kk in range(self._ngrid[2]) 293 | for jj in range(self._ngrid[1]) 294 | for ii in range(self._ngrid[0]) 295 | if ( 296 | (fz[kk] > 0) or 297 | (fz[kk] == 0 and fy[jj] > 0) or 298 | (fz[kk] == 0 and fy[jj] == 0 and fx[ii] >= 0) 299 | )], dtype=float) 300 | else: 301 | kgrid = np.array([(fx[ii], fy[jj], fz[kk]) 302 | for kk in range(self._ngrid[2]) 303 | for jj in range(self._ngrid[1]) 304 | for ii in range(self._ngrid[0]) 305 | if ( 306 | (fx[ii] > 0) or 307 | (fx[ii] == 0 and fy[jj] > 0) or 308 | (fx[ii] == 0 and fy[jj] == 0 and fz[kk] >= 0) 309 | )], dtype=float) 310 | else: 311 | kgrid = np.array([(fx[ii], fy[jj], fz[kk]) 312 | for kk in range(self._ngrid[2]) 313 | for jj in range(self._ngrid[1]) 314 | for ii in range(self._ngrid[0])], dtype=float) 315 | 316 | # Kinetic_Energy = (G + k)**2 / 2 317 | # HSQDTM = hbar**2/(2*ELECTRON MASS) 318 | KENERGY = HSQDTM * np.linalg.norm( 319 | np.dot(kgrid + kvec[np.newaxis,:] , TPI*self._Bcell), axis=1 320 | )**2 321 | # find Gvectors where (G + k)**2 / 2 < ENCUT 322 | Gvec = kgrid[np.where(KENERGY < self._encut)[0]] 323 | 324 | # Check if the calculated number of planewaves and the one recorded in the 325 | # WAVECAR are equal 326 | if check_consistency: 327 | if self._lsoc: 328 | assert Gvec.shape[0] == self._nplws[ikpt - 1] / 2, \ 329 | 'No. of planewaves not consistent for an SOC WAVECAR! %d %d %d' % \ 330 | (Gvec.shape[0], self._nplws[ikpt -1], np.prod(self._ngrid)) 331 | else: 332 | assert Gvec.shape[0] == self._nplws[ikpt - 1], 'No. of planewaves not consistent! %d %d %d' % \ 333 | (Gvec.shape[0], self._nplws[ikpt -1], np.prod(self._ngrid)) 334 | 335 | return np.asarray(Gvec, dtype=int) 336 | 337 | def save2vesta(self, phi=None, lreal=False, lchg=False, poscar='POSCAR', prefix='wfc', 338 | ncol=10): 339 | ''' 340 | Save the real space pseudo-wavefunction as vesta format. 341 | ''' 342 | nx, ny, nz = phi.shape 343 | try: 344 | pos = open(poscar, 'r') 345 | head = '' 346 | for line in pos: 347 | if line.strip(): 348 | head += line 349 | else: 350 | break 351 | head += '\n%5d%5d%5d\n' % (nx, ny, nz) 352 | except: 353 | raise IOError('Failed to open %s' % poscar) 354 | 355 | # Faster IO 356 | nrow = phi.size // ncol 357 | nrem = phi.size % ncol 358 | fmt = "%16.8E" 359 | 360 | psi = phi.copy() 361 | psi = psi.flatten(order='F') 362 | psi_h = psi[:nrow * ncol].reshape((nrow, ncol)) 363 | psi_r = psi[nrow * ncol:] 364 | 365 | if not lchg: 366 | with open(prefix + '_r.vasp', 'w') as out: 367 | out.write(head) 368 | out.write( 369 | '\n'.join([''.join([fmt % xx for xx in row]) 370 | for row in psi_h.real]) 371 | ) 372 | out.write("\n" + ''.join([fmt % xx for xx in psi_r.real])) 373 | if not (self._lgam or lreal): 374 | with open(prefix + '_i.vasp', 'w') as out: 375 | out.write(head) 376 | out.write( 377 | '\n'.join([''.join([fmt % xx for xx in row]) 378 | for row in psi_h.imag]) 379 | ) 380 | out.write("\n" + ''.join([fmt % xx for xx in psi_r.imag])) 381 | else: 382 | with open(prefix + '_chg.vasp', 'w') as out: 383 | out.write(head) 384 | out.write( 385 | '\n'.join([''.join([fmt % xx for xx in row]) 386 | for row in (psi_h.real**2 + psi_h.imag**2)]) 387 | ) 388 | out.write("\n" + ''.join([fmt % xx for xx in (psi_r.real**2 + psi_r.imag**2)])) 389 | 390 | 391 | def wfc_r(self, ispin=1, ikpt=1, iband=1, 392 | gvec=None, Cg=None, ngrid=None, 393 | rescale=None, 394 | norm=True): 395 | ''' 396 | Obtain the pseudo-wavefunction of the specified KS states in real space 397 | by performing FT transform on the reciprocal space planewave 398 | coefficients. The 3D FT grid size is determined by ngrid, which 399 | defaults to self._ngrid if not given. Gvectors of the KS states is used 400 | to put 1D planewave coefficients back to 3D grid. 401 | 402 | Inputs: 403 | ispin : spin index of the desired KS states, starting from 1 404 | ikpt : k-point index of the desired KS states, starting from 1 405 | iband : band index of the desired KS states, starting from 1 406 | gvec : the G-vectors correspond to the plane-wave coefficients 407 | Cg : the plane-wave coefficients. If None, read from WAVECAR 408 | ngrid : the FFT grid size 409 | norm : normalized Cg? 410 | 411 | The return wavefunctions are normalized in a way that 412 | 413 | \sum_{ijk} | \phi_{ijk} | ^ 2 = 1 414 | 415 | ''' 416 | self.checkIndex(ispin, ikpt, iband) 417 | 418 | if ngrid is None: 419 | ngrid = self._ngrid.copy() * 2 420 | else: 421 | ngrid = np.array(ngrid, dtype=int) 422 | assert ngrid.shape == (3,) 423 | assert np.all(ngrid >= self._ngrid), \ 424 | "Minium FT grid size: (%d, %d, %d)" % \ 425 | (self._ngrid[0], self._ngrid[1], self._ngrid[2]) 426 | 427 | # The default normalization of np.fft.fftn has the direct transforms 428 | # unscaled and the inverse transforms are scaled by 1/n. It is possible 429 | # to obtain unitary transforms by setting the keyword argument norm to 430 | # "ortho" (default is None) so that both direct and inverse transforms 431 | # will be scaled by 1/\sqrt{n}. 432 | 433 | # default normalization factor so that 434 | # \sum_{ijk} | \phi_{ijk} | ^ 2 = 1 435 | normFac = rescale if rescale is not None else np.sqrt(np.prod(ngrid)) 436 | 437 | if gvec is None: 438 | gvec = self.gvectors(ikpt) 439 | 440 | if self._lgam: 441 | if self._gam_half == 'z': 442 | phi_k = np.zeros((ngrid[0], ngrid[1], ngrid[2]/2 + 1), dtype=np.complex128) 443 | else: 444 | phi_k = np.zeros((int(ngrid[0]/2 + 1), ngrid[1], ngrid[2]), dtype=np.complex128) 445 | else: 446 | phi_k = np.zeros(ngrid, dtype=np.complex128) 447 | 448 | gvec %= ngrid[np.newaxis,:] 449 | 450 | if self._lsoc: 451 | wfc_spinor = [] 452 | if Cg: 453 | dump = Cg 454 | else: 455 | dump = self.readBandCoeff(ispin, ikpt, iband, norm) 456 | nplw = dump.shape[0] / 2 457 | 458 | # spinor up 459 | phi_k[gvec[:,0], gvec[:,1], gvec[:,2]] = dump[:nplw] 460 | wfc_spinor.append(ifftn(phi_k) * normFac) 461 | # spinor down 462 | phi_k[:,:,:] = 0.0j 463 | phi_k[gvec[:,0], gvec[:,1], gvec[:,2]] = dump[nplw:] 464 | wfc_spinor.append(ifftn(phi_k) * normFac) 465 | 466 | del dump 467 | return wfc_spinor 468 | 469 | else: 470 | if Cg is not None: 471 | phi_k[gvec[:,0], gvec[:,1], gvec[:,2]] = Cg 472 | else: 473 | phi_k[gvec[:,0], gvec[:,1], gvec[:,2]] = self.readBandCoeff(ispin, ikpt, iband, norm) 474 | 475 | if self._lgam: 476 | # add some components that are excluded and perform c2r FFT 477 | if self._gam_half == 'z': 478 | for ii in range(ngrid[0]): 479 | for jj in range(ngrid[1]): 480 | fx = ii if ii < ngrid[0] / 2 + 1 else ii - ngrid[0] 481 | fy = jj if jj < ngrid[1] / 2 + 1 else jj - ngrid[1] 482 | if (fy > 0) or (fy == 0 and fx >= 0): 483 | continue 484 | phi_k[ii,jj,0] = phi_k[-ii,-jj,0].conjugate() 485 | 486 | phi_k /= np.sqrt(2.) 487 | phi_k[0,0,0] *= np.sqrt(2.) 488 | return np.fft.irfftn(phi_k, s=ngrid) * normFac 489 | elif self._gam_half == 'x': 490 | for jj in range(ngrid[1]): 491 | for kk in range(ngrid[2]): 492 | fy = jj if jj < ngrid[1] / 2 + 1 else jj - ngrid[1] 493 | fz = kk if kk < ngrid[2] / 2 + 1 else kk - ngrid[2] 494 | if (fy > 0) or (fy == 0 and fz >= 0): 495 | continue 496 | phi_k[0,jj,kk] = phi_k[0,-jj,-kk].conjugate() 497 | 498 | phi_k /= np.sqrt(2.) 499 | phi_k[0,0,0] *= np.sqrt(2.) 500 | phi_k = np.swapaxes(phi_k, 0, 2) 501 | tmp = np.fft.irfftn(phi_k, s=(ngrid[2], ngrid[1], ngrid[0])) * normFac 502 | return np.swapaxes(tmp, 0, 2) 503 | else: 504 | # perform complex2complex FFT 505 | return ifftn(phi_k * normFac) 506 | 507 | def readBandCoeff(self, ispin=1, ikpt=1, iband=1, norm=False): 508 | ''' 509 | Read the planewave coefficients of specified KS states. 510 | ''' 511 | 512 | self.checkIndex(ispin, ikpt, iband) 513 | 514 | rec = self.whereRec(ispin, ikpt, iband) 515 | self._wfc.seek(rec * self._recl) 516 | 517 | nplw = self._nplws[ikpt - 1] 518 | dump = np.fromfile(self._wfc, dtype=self._WFPrec, count=nplw) 519 | 520 | cg = np.asarray(dump, dtype=np.complex128) 521 | if norm: 522 | cg /= np.linalg.norm(cg) 523 | return cg 524 | 525 | def whereRec(self, ispin=1, ikpt=1, iband=1): 526 | ''' 527 | Return the rec position for specified KS state. 528 | ''' 529 | 530 | self.checkIndex(ispin, ikpt, iband) 531 | 532 | rec = 2 + (ispin - 1) * self._nkpts * (self._nbands + 1) + \ 533 | (ikpt - 1) * (self._nbands + 1) + \ 534 | iband 535 | return rec 536 | 537 | def checkIndex(self, ispin, ikpt, iband): 538 | ''' 539 | Check if the index is valid! 540 | ''' 541 | assert 1 <= ispin <= self._nspin, 'Invalid spin index!' 542 | assert 1 <= ikpt <= self._nkpts, 'Invalid kpoint index!' 543 | assert 1 <= iband <= self._nbands, 'Invalid band index!' 544 | 545 | def TransitionDipoleMoment(self, ks_i, ks_j, norm=True, 546 | realspace=False): 547 | ''' 548 | calculate Transition Dipole Moment (TDM) between two KS states. 549 | 550 | If "realspace = False", the TDM will be evaluated in momentum space 551 | according to the formula in: 552 | https://en.wikipedia.org/wiki/Transition_dipole_moment 553 | 554 | i⋅h 555 | = -------------- ⋅ 556 | m⋅(Eb - Ea) 557 | 558 | 2 ____ 559 | h ╲ 560 | = ------------- ⋅ ╲ Cai⋅Cbi⋅Gi 561 | m⋅(Eb - Ea) ╱ 562 | ╱ 563 | ‾‾‾‾ 564 | i 565 | 566 | Otherwise, the TDM will be evaluated in real space. 567 | 568 | Note: |psi_a> and |psi_b> should be bloch function with 569 | the same k vector. 570 | 571 | The KS states ks_i (ks_j) is specified by list of index (ispin, ikpt, iband). 572 | ''' 573 | 574 | ks_i = list(ks_i); ks_j = list(ks_j) 575 | assert len(ks_i) == len(ks_j) == 3, 'Must be three indexes!' 576 | assert ks_i[1] == ks_j[1], 'k-point of the two states differ!' 577 | self.checkIndex(*ks_i) 578 | self.checkIndex(*ks_j) 579 | 580 | # energy differences between the two states 581 | E1 = self._bands[ks_i[0]-1, ks_i[1]-1, ks_i[2]-1] 582 | E2 = self._bands[ks_j[0]-1, ks_j[1]-1, ks_j[2]-1] 583 | dE = E2 - E1 584 | 585 | if realspace: 586 | fx = np.linspace(0, 1, self._ngrid[0], endpoint=False) 587 | fy = np.linspace(0, 1, self._ngrid[1], endpoint=False) 588 | fz = np.linspace(0, 1, self._ngrid[2], endpoint=False) 589 | 590 | Dx, Dy, Dz = np.meshgrid(fx, fy, fz, indexing='ij') 591 | Rx, Ry, Rz = np.tensordot(self._Acell, [Dx, Dy, Dz], axes=[0,0]) 592 | 593 | fac = np.sqrt(np.prod(self._ngrid) / self._Omega) 594 | phi_i = self.wfc_r(*ks_i, norm=True, ngrid=self._ngrid) 595 | phi_j = self.wfc_r(*ks_j, norm=True, ngrid=self._ngrid) 596 | 597 | pij = phi_i.conjugate() * phi_j 598 | tdm = np.array([ 599 | np.sum(pij * Rx), 600 | np.sum(pij * Ry), 601 | np.sum(pij * Rz) 602 | ]) 603 | ovlap = pij.sum() 604 | else: 605 | # according to the above equation, G = 0 does NOT contribute to TDM. 606 | gvec = np.dot(self.gvectors(ikpt=ks_i[1]), self._Bcell*TPI) 607 | # planewave coefficients of the two states 608 | phi_i = self.readBandCoeff(*ks_i, norm=norm) 609 | phi_j = self.readBandCoeff(*ks_j, norm=norm) 610 | 611 | tmp1 = phi_i.conjugate() * phi_j 612 | ovlap = np.sum(tmp1) 613 | if self._lgam: 614 | tmp2 = phi_i * phi_j.conjugate() 615 | # according to the above equation, G = 0 does NOT contribute to TDM. 616 | tdm = (np.sum(tmp1[:,np.newaxis] * gvec, axis=0) - 617 | np.sum(tmp2[:,np.newaxis] * gvec, axis=0)) / 2. 618 | else: 619 | tdm = np.sum(tmp1[:,np.newaxis] * gvec, axis=0) 620 | 621 | tdm = 1j / (dE / (2*RYTOEV)) * tdm * AUTOA * AUTDEBYE 622 | 623 | return E1, E2, dE, ovlap, tdm 624 | 625 | def inverse_participation_ratio(self, norm=True): 626 | ''' 627 | Calculate Inverse Paticipation Ratio (IPR) from the wavefunction. IPR is 628 | a measure of the localization of Kohn-Sham states. For a particular KS 629 | state \phi_j, it is defined as 630 | 631 | \sum_n |\phi_j(n)|^4 632 | IPR(\phi_j) = ------------------------- 633 | |\sum_n |\phi_j(n)|^2||^2 634 | 635 | where n iters over the number of grid points. 636 | ''' 637 | 638 | self.ipr = np.zeros((self._nspin, self._nkpts, self._nbands, 3)) 639 | 640 | for ispin in range(self._nspin): 641 | for ikpt in range(self._nkpts): 642 | for iband in range(self._nbands): 643 | phi_j = self.wfc_r(ispin+1, ikpt+1, iband+1, 644 | norm=norm) 645 | phi_j_abs = np.abs(phi_j) 646 | 647 | print('Calculating IPR of #spin %4d, #kpt %4d, #band %4d' % (ispin+1, ikpt+1, iband+1)) 648 | self.ipr[ispin, ikpt, iband, 0] = self._kpath[ikpt] if self._kpath is not None else 0 649 | self.ipr[ispin, ikpt, iband, 1] = self._bands[ispin, ikpt, iband] 650 | self.ipr[ispin, ikpt, iband, 2] = np.sum(phi_j_abs**4) / np.sum(phi_j_abs**2)**2 651 | 652 | np.save('ipr.npy', self.ipr) 653 | return self.ipr 654 | 655 | def elf(self, kptw, ngrid=None, warn=True): 656 | ''' 657 | Calculate the electron localization function (ELF) from WAVECAR. 658 | 659 | The following formula was extracted from VASP ELF.F: 660 | _ 661 | h^2 * 2 T.........kinetic energy 662 | T = -2 --- Psi grad Psi T+TCORR...pos.definite kinetic energy 663 | ^ 2 m TBOS......T of an ideal Bose-gas 664 | ^ 665 | I am not sure if we need to times 2 here, use 1 in this 666 | script. 667 | 668 | _ (=infimum of T+TCORR) 669 | 1 h^2 2 DH........T of hom.non-interact.e- - gas 670 | TCORR= - --- grad rho (acc.to Fermi) 671 | 2 2 m ELF.......electron-localization-function 672 | _ 2 673 | 1 h^2 |grad rho| 674 | TBOS = - --- ---------- D = T + TCORR - TBOS 675 | 4 2 m rho 676 | _ \ 1 677 | 3 h^2 2/3 5/3 =====> ELF = ------------ 678 | DH = - --- (3 Pi^2) rho / D 2 679 | 5 2 m 1 + ( ---- ) 680 | DH 681 | 682 | REF: 683 | 1. Nature, 371, 683-686 (1994) 684 | 2. Becke and Edgecombe, J. Chem. Phys., 92, 5397(1990) 685 | 3. M. Kohout and A. Savin, Int. J. Quantum Chem., 60, 875-882(1996) 686 | 4. http://www2.cpfs.mpg.de/ELF/index.php?content=06interpr.txt 687 | ''' 688 | 689 | if warn: 690 | warning = """ 691 | ################################################################### 692 | If you are using VESTA to view the resulting ELF, please rename the 693 | output file as ELFCAR, otherwise there will be some error in the 694 | isosurface plot! 695 | 696 | When CHG*/PARCHG/*.vasp are read in to visualize isosurfaces and 697 | sections, data values are divided by volume in the unit of bohr^3. 698 | The unit of charge densities input by VESTA is, therefore, bohr^−3. 699 | 700 | For LOCPOT/ELFCAR files, volume data are kept intact. 701 | 702 | You can turn off this warning by setting "warn=False" in the "elf" 703 | method. 704 | ################################################################### 705 | """ 706 | print(warning) 707 | 708 | # the k-point weights 709 | kptw = np.array(kptw, dtype=float) 710 | assert kptw.shape == (self._nkpts,), "K-point weights must be provided \ 711 | to calculate charge density!" 712 | # normalization 713 | kptw /= kptw.sum() 714 | 715 | if ngrid is None: 716 | ngrid = self._ngrid * 2 717 | else: 718 | ngrid = np.array(ngrid, dtype=int) 719 | assert ngrid.shape == (3,) 720 | assert np.alltrue(ngrid >= self._ngrid), \ 721 | "Minium FT grid size: (%d, %d, %d)" % \ 722 | (self._ngrid[0], self._ngrid[1], self._ngrid[2]) 723 | 724 | fx = [ii if ii < ngrid[0] / 2 + 1 else ii - ngrid[0] 725 | for ii in range(ngrid[0])] 726 | fy = [jj if jj < ngrid[1] / 2 + 1 else jj - ngrid[1] 727 | for jj in range(ngrid[1])] 728 | fz = [kk if kk < ngrid[2] / 2 + 1 else kk - ngrid[2] 729 | for kk in range(ngrid[2])] 730 | 731 | # plane-waves: Reciprocal coordinate 732 | # indexing = 'ij' so that outputs are of shape (ngrid[0], ngrid[1], ngrid[2]) 733 | Dx, Dy, Dz = np.meshgrid(fx, fy, fz, indexing='ij') 734 | # plane-waves: Cartesian coordinate 735 | Gx, Gy, Gz = np.tensordot(self._Bcell * np.pi * 2, [Dx, Dy, Dz], axes=(0,0)) 736 | # the norm squared of the G-vectors 737 | G2 = Gx**2 + Gy**2 + Gz**2 738 | # k-points vectors in Cartesian coordinate 739 | vkpts = np.dot(self._kvecs, self._Bcell * 2 * np.pi) 740 | 741 | # normalization factor so that 742 | # \sum_{ijk} | \phi_{ijk} | ^ 2 * volume / Ngrid = 1 743 | normFac = np.sqrt(np.prod(ngrid) / self._Omega) 744 | 745 | # electron localization function 746 | ElectronLocalizationFunction = [] 747 | # Charge density 748 | rho = np.zeros(ngrid, dtype=complex) 749 | # Kinetic energy density 750 | tau = np.zeros(ngrid, dtype=complex) 751 | 752 | for ispin in range(self._nspin): 753 | # initialization 754 | rho[...] = 0.0 755 | tau[...] = 0.0 756 | 757 | for ikpt in range(self._nkpts): 758 | 759 | # plane-wave G-vectors 760 | igvec = self.gvectors(ikpt+1) 761 | # for gamma-only version, complete the missing -G vectors 762 | if self._lgam: 763 | tmp = np.array([-k for k in igvec[1:]], dtype=int) 764 | igvec = np.vstack([igvec, tmp]) 765 | # plane-wave G-vectors in Cartesian coordinate 766 | rgvec = np.dot(igvec, self._Bcell * 2 * np.pi) 767 | 768 | k = vkpts[ikpt] # k 769 | gk = rgvec + k[np.newaxis,:] # G + k 770 | gk2 = np.linalg.norm(gk, axis=1)**2 # | G + k |^2 771 | 772 | for iband in range(self._nbands): 773 | # omit the empty bands 774 | if self._occs[ispin, ikpt, iband] == 0.0: continue 775 | 776 | rspin = 2.0 if self._nspin == 1 else 1.0 777 | weight = rspin * kptw[ikpt] * self._occs[ispin, ikpt, iband] 778 | 779 | # if self._lgam: 780 | # ######################################## 781 | # # slower 782 | # ######################################## 783 | # # wavefunction in real space 784 | # # VASP does NOT do normalization in elf.F 785 | # phi_r = self.wfc_r(ispin=ispin+1, ikpt=ikpt+1, 786 | # iband=iband+1, 787 | # ngrid=ngrid, 788 | # norm=False) * normFac 789 | # # wavefunction in reciprocal space 790 | # phi_q = np.fft.fftn(phi_r, norm='ortho') 791 | # # grad^2 \phi in reciprocal space 792 | # lap_phi_q = -gk2 * phi_q 793 | # # grad^2 \phi in real space 794 | # lap_phi_r = np.fft.ifftn(lap_phi_q, norm='ortho') 795 | # else: 796 | 797 | ######################################## 798 | # faster 799 | ######################################## 800 | # wavefunction in reciprocal space 801 | # VASP does NOT do normalization in elf.F 802 | phi_q = self.readBandCoeff(ispin=ispin+1, ikpt=ikpt+1, 803 | iband=iband+1, 804 | norm=False) 805 | # pad the missing planewave coefficients for -G vectors 806 | if self._lgam: 807 | tmp = [x.conj() for x in phi_q[1:]] 808 | phi_q = np.concatenate([phi_q, tmp]) 809 | # Gamma only, divide a factor of sqrt(2.0) except for 810 | # G=0 811 | phi_q /= np.sqrt(2.0) 812 | phi_q[0] *= np.sqrt(2.0) 813 | # wavefunction in real space 814 | phi_r = self.wfc_r(ispin=ispin+1, ikpt=ikpt+1, 815 | iband=iband+1, 816 | ngrid=ngrid, 817 | gvec=igvec, 818 | Cg=phi_q, 819 | norm=True) * normFac 820 | # grad^2 \phi in reciprocal space 821 | lap_phi_q = -gk2 * phi_q 822 | # grad^2 \phi in real space 823 | lap_phi_r = self.wfc_r(ispin=ispin+1, ikpt=ikpt+1, 824 | iband=iband+1, 825 | ngrid=ngrid, 826 | gvec=igvec, 827 | Cg=lap_phi_q) * normFac 828 | 829 | # \phi* grad^2 \phi in real space --> kinetic energy density 830 | tau += -phi_r * lap_phi_r.conj() * weight 831 | 832 | # charge density in real space 833 | rho += phi_r.conj() * phi_r * weight 834 | 835 | # charge density in reciprocal space 836 | rho_q = np.fft.fftn(rho, norm='ortho') 837 | 838 | # grad^2 rho: laplacian of charge density 839 | lap_rho_q = -G2 * rho_q 840 | lap_rho_r = np.fft.ifftn(lap_rho_q, norm='ortho') 841 | 842 | # charge density gradient: grad rho 843 | ######################################## 844 | # wrong method for gradient using FFT 845 | ######################################## 846 | # grad_rho_x = np.fft.ifft(1j * Gx * np.fft.fft(rho, axis=0), axis=0) 847 | # grad_rho_y = np.fft.ifft(1j * Gy * np.fft.fft(rho, axis=1), axis=1) 848 | # grad_rho_z = np.fft.ifft(1j * Gz * np.fft.fft(rho, axis=2), axis=2) 849 | 850 | ######################################## 851 | # correct method for gradient using FFT 852 | ######################################## 853 | grad_rho_x = np.fft.ifftn(1j * Gx * rho_q, norm='ortho') 854 | grad_rho_y = np.fft.ifftn(1j * Gy * rho_q, norm='ortho') 855 | grad_rho_z = np.fft.ifftn(1j * Gz * rho_q, norm='ortho') 856 | 857 | grad_rho_sq = np.abs(grad_rho_x)**2 \ 858 | + np.abs(grad_rho_y)**2 \ 859 | + np.abs(grad_rho_z)**2 860 | 861 | rho = rho.real 862 | tau = tau.real 863 | lap_rho_r = lap_rho_r.real 864 | 865 | Cf = 3./5 * (3.0 * np.pi**2)**(2./3) 866 | Dh = np.where(rho > 0.0, 867 | Cf * rho**(5./3), 868 | 0.0) 869 | eps = 1E-8 / HSQDTM 870 | Dh[Dh < eps] = eps 871 | # D0 = T + TCORR - TBOS 872 | D0 = tau + 0.5 * lap_rho_r - 0.25 * grad_rho_sq / rho 873 | 874 | ElectronLocalizationFunction.append(1. / (1. + (D0 / Dh)**2)) 875 | 876 | return ElectronLocalizationFunction 877 | 878 | ############################################################ 879 | 880 | if __name__ == '__main__': 881 | # xx = vaspwfc('wavecar') 882 | # phi = xx.wfc_r(1, 30, 17, ngrid=(28, 28, 252)) 883 | # xx.save2vesta(phi, poscar='POSCAR') 884 | 885 | # xx = vaspwfc('./gamma/WAVECAR') 886 | # phi = xx.wfc_r(1, 1, 317, ngrid=(60, 108, 160), 887 | # gamma=True) 888 | # xx.save2vesta(phi, poscar='./gamma/POSCAR',gamma=True) 889 | 890 | # xx = vaspwfc('WAVECAR') 891 | # dE, ovlap, tdm = xx.TransitionDipoleMoment([1,30,17], [1,30,18], norm=True) 892 | # print dE, ovlap.real, np.abs(tdm)**2 893 | 894 | # print xx._recl, xx._nspin, xx._rtag 895 | # print xx._nkpts, xx._nbands, xx._encut 896 | # print xx._Acell, xx._Bcell 897 | # # print np.linalg.norm(xx._Acell, axis=1) 898 | # print xx._ngrid 899 | # print xx._bands[0,0,:] 900 | # print xx._kvecs 901 | # print xx._kpath 902 | # b = xx.readBandCoeff(1,1,1) 903 | # xx = np.savetxt('kaka.dat', xx.gvectors(2), fmt='%5d') 904 | # gvec = xx.gvectors(1) 905 | # gvec %= xx._ngrid[np.newaxis, :] 906 | # print gvec 907 | 908 | # ngrid=(28, 28, 252) 909 | # phi = xx.wfc_r(1, 30, 17, ngrid=(28, 28, 252)) 910 | # header = open('POSCAR').read() 911 | # with open('wave_real.vasp', 'w') as out: 912 | # out.write(header) 913 | # out.write('%5d%5d%5d\n' % (ngrid[0], ngrid[1], ngrid[2])) 914 | # nwrite=0 915 | # for kk in range(ngrid[2]): 916 | # for jj in range(ngrid[1]): 917 | # for ii in range(ngrid[0]): 918 | # nwrite += 1 919 | # out.write('%22.16f ' % phi.real[ii,jj,kk]) 920 | # if nwrite % 10 == 0: 921 | # out.write('\n') 922 | # with open('wave_imag.vasp', 'w') as out: 923 | # out.write(header) 924 | # out.write('%5d%5d%5d\n' % (ngrid[0], ngrid[1], ngrid[2])) 925 | # nwrite=0 926 | # for kk in range(ngrid[2]): 927 | # for jj in range(ngrid[1]): 928 | # for ii in range(ngrid[0]): 929 | # nwrite += 1 930 | # out.write('%22.16f ' % phi.imag[ii,jj,kk]) 931 | # if nwrite % 10 == 0: 932 | # out.write('\n') 933 | 934 | # xx = vaspwfc('wave_tyz') 935 | # ipr = xx.inverse_participation_ratio() 936 | # print xx._nbands, xx._nkpts 937 | # 938 | # import matplotlib as mpl 939 | # import matplotlib.pyplot as plt 940 | # 941 | # fig = plt.figure() 942 | # ax = plt.subplot() 943 | # 944 | # ax.scatter(ipr[...,0], ipr[..., 1], s=ipr[..., 2] / ipr[..., 2].max() * 10, c=ipr[..., 2], 945 | # cmap='jet_r') 946 | # 947 | # plt.show() 948 | 949 | wfc = vaspwfc('WAVECAR', lgamma=True, gamma_half='x') 950 | # ngrid = [80, 140, 210] 951 | phi = wfc.wfc_r(iband=190) 952 | 953 | rho = np.abs(phi)**2 954 | # rho2 = VaspChargeDensity('PARCHG.0158.ALLK').chg[0] 955 | # rho /= rho.sum() 956 | # rho2 /= rho2.sum() 957 | # rho3 = rho - rho2 958 | 959 | wfc.save2vesta(rho, lreal=True) 960 | 961 | pass 962 | -------------------------------------------------------------------------------- /VASP/view_atoms.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A script to read POSCAR/CONTCAR files and visualize them using ase.gui 4 | Depends on ase 5 | """ 6 | 7 | from __future__ import print_function 8 | import sys, os 9 | import argparse 10 | from ase.io import read 11 | from ase.visualize import view 12 | 13 | # Command line praser 14 | #---------------------------- 15 | parser = argparse.ArgumentParser(description='A script to view atomic structure.') 16 | parser.add_argument('POSCAR', nargs='*', help="name of the CHGCAR files.") 17 | 18 | prm = parser.parse_args() 19 | 20 | # Find out how many arguments were on the command line, 21 | # nsubtract = len(sys.argv)-2 22 | nsubtract = len(prm.POSCAR) 23 | if nsubtract > 1: 24 | print("\n** ERROR: Can only view one file at a time.") 25 | print("eg. view_atoms.py POSCAR") 26 | sys.exit(0) 27 | 28 | # Check that files exist 29 | for name in prm.POSCAR: 30 | if not os.path.isfile(name): 31 | print("\n** ERROR: Input file %s was not found." % name) 32 | sys.exit(0) 33 | 34 | # Read information from command line 35 | File = prm.POSCAR[0].lstrip() 36 | 37 | atoms = read(File, format='vasp') 38 | view(atoms) 39 | -------------------------------------------------------------------------------- /VASP/vtotav.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | A script which averages a CHGCAR or LOCPOT file in one direction to make a 1D curve. 4 | User must specify filename and direction on command line. 5 | Depends on ase 6 | """ 7 | 8 | from __future__ import print_function 9 | import os 10 | import sys 11 | import numpy as np 12 | import math 13 | import string 14 | import datetime 15 | import time 16 | import argparse 17 | from ase.calculators.vasp import VaspChargeDensity 18 | from scipy import interpolate 19 | 20 | # Command line praser 21 | #---------------------------- 22 | parser = argparse.ArgumentParser(description='A script to calculate planar and macroscopic average along certain axis.') 23 | parser.add_argument('-c', action="store", default="LOCPOT", dest="LOCPOT", 24 | help='Input file name.') 25 | parser.add_argument('-chg','--chg', action="store_true", default=False, dest="chg", 26 | help='Is density quantity? (Default=False)') 27 | parser.add_argument('-d', action="store", default="z", dest="dir", 28 | help='direction(Default=Z)') 29 | parser.add_argument('-macro', action="store_true", default=False, dest="macro", 30 | help='macroscopic average? (Default=False). \ 31 | Will print out intrpolated planar and macro average. ') 32 | parser.add_argument('--len', action="store", default="0.1", type=np.float, dest="macro_len", 33 | help='atomic plane length. (in $\AA$)') 34 | 35 | prm = parser.parse_args() 36 | 37 | 38 | starttime = time.time() 39 | print("Starting calculation at", end='') 40 | print(time.strftime("%H:%M:%S on %a %d %b %Y")) 41 | 42 | # if len(sys.argv) != 3: 43 | # print "\n** ERROR: Must specify name of file and direction on command line." 44 | # print "eg. vtotav.py LOCPOT z." 45 | # sys.exit(0) 46 | 47 | if not os.path.isfile(prm.LOCPOT): 48 | print("\n** ERROR: Input file %s was not found." % prm.LOCPOT) 49 | sys.exit(0) 50 | 51 | # Read information from command line 52 | # First specify location of LOCPOT 53 | LOCPOTfile = prm.LOCPOT.lstrip() 54 | 55 | # Next the direction to make average in 56 | # input should be x y z, or X Y Z. Default is Z. 57 | allowed = "xyzXYZ" 58 | direction = prm.dir.lstrip() 59 | if allowed.find(direction) == -1 or len(direction)!=1 : 60 | print("** WARNING: The direction was input incorrectly.") 61 | print("** Setting to z-direction by default.") 62 | if direction.islower(): 63 | direction = direction.upper() 64 | filesuffix = "_%s" % direction 65 | 66 | # Open geometry and density class objects 67 | #----------------------------------------- 68 | vasp_charge = VaspChargeDensity(filename = LOCPOTfile) 69 | potl = vasp_charge.chg[-1] 70 | atoms = vasp_charge.atoms[-1] 71 | del vasp_charge 72 | 73 | # For LOCPOT files we multiply by the volume to get back to eV 74 | if 'LOCPOT' in LOCPOTfile: 75 | potl=potl*atoms.get_volume() 76 | 77 | print("\nReading file: %s" % LOCPOTfile) 78 | print("Performing average in %s direction" % direction) 79 | 80 | # Read in lattice parameters and scale factor 81 | #--------------------------------------------- 82 | cell = atoms.cell 83 | 84 | # Find length of lattice vectors 85 | #-------------------------------- 86 | latticelength = np.dot(cell, cell.T).diagonal() 87 | latticelength = latticelength**0.5 88 | 89 | # Read in potential data 90 | #------------------------ 91 | ngridpts = np.array(potl.shape) 92 | totgridpts = ngridpts.prod() 93 | print("Potential stored on a %dx%dx%d grid" % (ngridpts[0],ngridpts[1],ngridpts[2])) 94 | print("Total number of points is %d" % totgridpts) 95 | print("Reading potential data from file...", end='') 96 | sys.stdout.flush() 97 | print("done.") 98 | 99 | # Perform average 100 | #----------------- 101 | if direction=="X": 102 | idir = 0 103 | a = 1 104 | b = 2 105 | elif direction=="Y": 106 | a = 0 107 | idir = 1 108 | b = 2 109 | else: 110 | a = 0 111 | b = 1 112 | idir = 2 113 | a = (idir+1)%3 114 | b = (idir+2)%3 115 | # At each point, sum over other two indices 116 | average = np.zeros(ngridpts[idir],np.float) 117 | for ipt in range(ngridpts[idir]): 118 | if direction=="X": 119 | average[ipt] = potl[ipt,:,:].sum() 120 | elif direction=="Y": 121 | average[ipt] = potl[:,ipt,:].sum() 122 | else: 123 | average[ipt] = potl[:,:,ipt].sum() 124 | 125 | # if 'LOCPOT' in LOCPOTfile: 126 | if not prm.chg: 127 | # Scale by number of grid points in the plane. 128 | # The resulting unit will be eV. 129 | average /= ngridpts[a]*ngridpts[b] 130 | else: 131 | # Scale by size of area element in the plane, 132 | # gives unit e/Ang. I.e. integrating the resulting 133 | # CHG_dir file should give the total charge. 134 | area = np.linalg.det([ (cell[a,a], cell[a,b] ), 135 | (cell[b,a], cell[b,b])]) 136 | dA = area/(ngridpts[a]*ngridpts[b]) 137 | average *= dA 138 | 139 | if prm.macro == True: 140 | average_m = np.zeros(ngridpts[idir]*50,np.float) 141 | interval = prm.macro_len 142 | dr = np.sqrt((cell[idir]**2).sum())/ngridpts[idir] 143 | dr_interp = dr/50. 144 | number = np.floor(np.round(interval/dr)/2) 145 | number_interp = np.floor(np.round(interval/dr_interp)/2) 146 | 147 | # linear interpolate (50X dense) 148 | #------------------- 149 | # x = np.linspace(0, dr*(ngridpts[idir]+1), ngridpts[idir], endpoint=False) 150 | # y = average 151 | # xvals = np.linspace(0, dr*(ngridpts[idir]+1), ngridpts[idir]*50, endpoint=False) 152 | # average_interp = np.interp(xvals, x, y) 153 | 154 | # cubic spline (50X dense) 155 | #------------------- 156 | x = np.linspace(0, dr*(ngridpts[idir]+1), ngridpts[idir], endpoint=False) 157 | y = average 158 | tck = interpolate.splrep(x, y, s=0) 159 | xvals = np.linspace(0, dr*(ngridpts[idir]+1), ngridpts[idir]*50, endpoint=False) 160 | average_interp = interpolate.splev(xvals, tck, der=0) 161 | 162 | # another cubic spline (50X dense) 163 | #------------------- 164 | # x = np.linspace(0, dr*(ngridpts[idir]+1), ngridpts[idir], endpoint=False) 165 | # y = average 166 | # tck = interpolate.interp1d(x, y, kind='cubic') 167 | # xvals = np.linspace(0, dr*(ngridpts[idir]), ngridpts[idir]*50, endpoint=False) 168 | # average_interp = tck(xvals) 169 | 170 | 171 | for ipt in range(ngridpts[idir]*50): 172 | average_m[ipt] = np.array([average_interp[i%(ngridpts[idir]*50)] \ 173 | for i in np.array(np.arange(ipt-number_interp,ipt+number_interp+1,1),dtype=np.int)]).sum() 174 | 175 | # original no interpolation method 176 | #------------------- 177 | # for ipt in range(ngridpts[idir]): 178 | # average_m[ipt] = np.array([average[i%ngridpts[idir]] \ 179 | # for i in np.array(np.arange(ipt-number,ipt+number+1,1),dtype=np.int)]).sum() 180 | # print [i%ngridpts[idir] \ 181 | # for i in np.array(np.arange(ipt-number,ipt+number+1,1),dtype=np.int)] 182 | 183 | # # interpolate again? 184 | #------------------- 185 | # for ii in range(1): 186 | # average_mm = np.zeros(ngridpts[idir]*50,np.float) 187 | # for ipt in range(ngridpts[idir]*50): 188 | # average_mm[ipt] = np.array([average_m[i%(ngridpts[idir]*50)] \ 189 | # for i in np.array(np.arange(ipt-number_interp,ipt+number_interp,1),dtype=np.int)]).sum() 190 | # average_m = average_mm/(2*number_interp+1) 191 | 192 | average = average_m /(2*number_interp+1) 193 | 194 | # Print out average macro 195 | #------------------- 196 | if prm.macro == True: 197 | averagefile = LOCPOTfile + filesuffix + '_macro' 198 | print("Writing macroscopic averaged data to file %s..." % averagefile, end='') 199 | sys.stdout.flush() 200 | outputfile = open(averagefile,"w") 201 | if 'LOCPOT' in LOCPOTfile: 202 | outputfile.write("# Distance(Ang) Potential(eV)\n") 203 | else: 204 | outputfile.write("# Distance(Ang) Chg. density (e/Ang)\n") 205 | # (50X dense) 206 | xdiff = latticelength[idir]/float(ngridpts[idir]*50) 207 | for i in range(ngridpts[idir]*50): 208 | x = i*xdiff 209 | outputfile.write("%15.8g %15.8g\n" % (x,average[i])) 210 | outputfile.close() 211 | print("done.") 212 | 213 | # Print out average 214 | #------------------- 215 | averagefile = LOCPOTfile + filesuffix 216 | print("Writing averaged data to file %s..." % averagefile, end='') 217 | sys.stdout.flush() 218 | outputfile = open(averagefile,"w") 219 | if 'LOCPOT' in LOCPOTfile: 220 | outputfile.write("# Distance(Ang) Potential(eV)\n") 221 | else: 222 | outputfile.write("# Distance(Ang) Chg. density (e/Ang)\n") 223 | if prm.macro == True: 224 | # (50X dense) 225 | xdiff = latticelength[idir]/float(ngridpts[idir]*50) 226 | for i in range(ngridpts[idir]*50): 227 | x = i*xdiff 228 | outputfile.write("%15.8g %15.8g\n" % (x,average_interp[i])) 229 | else: 230 | xdiff = latticelength[idir]/float(ngridpts[idir]) 231 | for i in range(ngridpts[idir]): 232 | x = i*xdiff 233 | outputfile.write("%15.8g %15.8g\n" % (x,average[i])) 234 | outputfile.close() 235 | print("done.") 236 | 237 | 238 | endtime = time.time() 239 | runtime = endtime-starttime 240 | print("\nEnd of calculation.") 241 | print("Program was running for %.2f seconds." % runtime) 242 | --------------------------------------------------------------------------------