From 76449de151bc7207e913ba88cf1bcaf245723c2c Mon Sep 17 00:00:00 2001 From: Dmitry Aksenov Date: Thu, 5 Jul 2018 13:47:03 +0300 Subject: [PATCH] auto --- classes.py | 9 + project_template/project_conf.py | 4 +- tutorials/Bi2Se3/Bi2Se3.bader/1.CONTCAR | 19 ++ tutorials/Bi2Se3/Bi2Se3.bader/1.POSCAR | 13 + .../Bi2Se3/Bi2Se3.bader/Bi2Se3.bader.run | 32 ++ .../Bi2Se3_mp-541837_computed.POSCAR | 13 + tutorials/Bi2Se3/Bi2Se3.bader/INCAR | 27 ++ tutorials/Bi2Se3/Bi2Se3.bader/KPOINTS | 5 + tutorials/Configure.ipynb | 8 +- tutorials/bader.ipynb | 322 ++++++++++++++++++ tutorials/calc.gdbm3 | Bin 19494 -> 24433 bytes tutorials/only_calc.gdbm3 | Bin 372174 -> 372174 bytes tutorials/run | 5 +- 13 files changed, 453 insertions(+), 4 deletions(-) create mode 100644 tutorials/Bi2Se3/Bi2Se3.bader/1.CONTCAR create mode 100644 tutorials/Bi2Se3/Bi2Se3.bader/1.POSCAR create mode 100644 tutorials/Bi2Se3/Bi2Se3.bader/Bi2Se3.bader.run create mode 100644 tutorials/Bi2Se3/Bi2Se3.bader/Bi2Se3_mp-541837_computed.POSCAR create mode 100644 tutorials/Bi2Se3/Bi2Se3.bader/INCAR create mode 100644 tutorials/Bi2Se3/Bi2Se3.bader/KPOINTS create mode 100644 tutorials/bader.ipynb diff --git a/classes.py b/classes.py index 3a3eccc..b2669f1 100755 --- a/classes.py +++ b/classes.py @@ -5197,6 +5197,8 @@ def get_bader_ACF(self, p = 0): command1 = "cd "+path+"; ~/tools/vts/chgsum.pl "+AECCAR0+" "+AECCAR2+"; "+\ "mv CHGCAR_sum "+CHGCAR_sum+";" # on cluster + command_chg_gunzip = 'gunzip '+CHG+'.gz ' # on cluster + command2 = "rsync "+CHG_scratch_gz+' '+path+' ; gunzip '+CHG+'.gz ' # on cluster mv = v+".bader.log; mv ACF.dat "+v+".ACF.dat; mv AVF.dat "+v+".AVF.dat; mv BCF.dat "+v+".BCF.dat; cat "+v+".bader.log" @@ -5210,11 +5212,18 @@ def get_bader_ACF(self, p = 0): command_cat_ACF = " cat "+path+v+".ACF.dat" # run_on_server() + + #Calculate CHGCAR_sum if run_on_server(command_check_CHG_sum, self.cluster_address): print_and_log( CHGCAR_sum, "does not exist. trying to calculate it ", imp = 'Y') printlog( run_on_server(command1, self.cluster_address)+'\n', imp = 'Y' ) # sys.exit() + #Check chgcar + if run_on_server(command_check_CHG, self.cluster_address): #true if file not exists + printlog( 'Warning! File ', CHG, "does not exist. Checking .gz .. ", imp = 'Y') + + printlog( run_on_server(command_chg_gunzip, self.cluster_address)+'\n', imp = 'y' ) if run_on_server(command_check_CHG, self.cluster_address): #true if file not exists printlog( 'Warning! File ', CHG, "does not exist. Trying to restore it from archive .. ", imp = 'Y') diff --git a/project_template/project_conf.py b/project_template/project_conf.py index 869fcdc..1f88755 100644 --- a/project_template/project_conf.py +++ b/project_template/project_conf.py @@ -43,8 +43,10 @@ 'vasp_com':'mpirun vasp_std', 'homepath':'/home/Dmitry.Aksenov/', 'schedule':'PBS', +'walltime':72, 'corenum':16, -'pythonpath':'/usr/lib64/python2.7/site-packages/numpy' +'pythonpath':'/usr/lib64/python2.7/site-packages/numpy', +'modules':'module load Compilers/Intel/psxe_2015.6; module load MPI/intel/5.1.3.258/intel; module load QCh/VASP/5.4.1p1/psxe2015.6; module load ScriptLang/python/2.7', } CLUSTERS['bsu'] = {'address':'aleksenov_d@95.167.109.79', diff --git a/tutorials/Bi2Se3/Bi2Se3.bader/1.CONTCAR b/tutorials/Bi2Se3/Bi2Se3.bader/1.CONTCAR new file mode 100644 index 0000000..25a6329 --- /dev/null +++ b/tutorials/Bi2Se3/Bi2Se3.bader/1.CONTCAR @@ -0,0 +1,19 @@ +i2a=[Bi,Se] ; Bi2Se3_mp-541837_computed + 1.00000000000000 + 4.1030970000000000 0.0000000000000000 9.4098670000000002 + 1.9623290000000000 3.6034240000000000 9.4098670000000002 + 0.0000000000000000 0.0000000000000000 10.2655250000000002 + Bi Se + 2 3 +Direct + 0.3984349999999992 0.3984349999999992 0.3984349999999992 + 0.6015650000000008 0.6015650000000008 0.6015650000000008 + 0.0000000000000000 0.0000000000000000 0.0000000000000000 + 0.2157150000000030 0.2157150000000030 0.2157150000000030 + 0.7842849999999970 0.7842849999999970 0.7842849999999970 + + 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 + 0.00000000E+00 0.00000000E+00 0.00000000E+00 diff --git a/tutorials/Bi2Se3/Bi2Se3.bader/1.POSCAR b/tutorials/Bi2Se3/Bi2Se3.bader/1.POSCAR new file mode 100644 index 0000000..220feab --- /dev/null +++ b/tutorials/Bi2Se3/Bi2Se3.bader/1.POSCAR @@ -0,0 +1,13 @@ +i2a=[Bi,Se] ; Bi2Se3_mp-541837_computed + 1.000000000000000 + 4.103097 0.000000 9.409867 + 1.962329 3.603424 9.409867 + 0.000000 0.000000 10.265525 +Bi Se +2 3 +Direct + 0.3984350000000000 0.3984350000000000 0.3984350000000000 + 0.6015650000000000 0.6015650000000000 0.6015650000000000 + 0.0000000000000000 0.0000000000000000 0.0000000000000000 + 0.2157150000000000 0.2157150000000000 0.2157150000000000 + 0.7842850000000000 0.7842850000000000 0.7842850000000000 diff --git a/tutorials/Bi2Se3/Bi2Se3.bader/Bi2Se3.bader.run b/tutorials/Bi2Se3/Bi2Se3.bader/Bi2Se3.bader.run new file mode 100644 index 0000000..f20be23 --- /dev/null +++ b/tutorials/Bi2Se3/Bi2Se3.bader/Bi2Se3.bader.run @@ -0,0 +1,32 @@ +#!/bin/bash +#SBATCH -J Bi2Se3.bader +#SBATCH -t 250:00:00 +#SBATCH -N 1 +#SBATCH -n 16 +#SBATCH -o /home/aksenov/topologic/Bi2Se3//Bi2Se3.bader/sbatch.out +#SBATCH -e /home/aksenov/topologic/Bi2Se3//Bi2Se3.bader/sbatch.err +#SBATCH --mem-per-cpu=7675 +cd /home/aksenov/topologic/Bi2Se3//Bi2Se3.bader/ +export OMP_NUM_THREADS=1 +module add prun/1.0 +module add intel/16.0.2.181 +module add impi/5.1.3.181 +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/aksenov/tools/lib64:/home/aksenov/tools/atlas +export PATH=$PATH:/home/aksenov/tools +touch RUNNING +#Basic run: +cp 1.POSCAR POSCAR +prun /opt/vasp/bin/vasp5.4.1MPI >Bi2Se3.bader.1.log +sleep 20 +mv OUTCAR 1.OUTCAR +mv CONTCAR 1.CONTCAR +cp CHGCAR 1.CHGCAR +gzip -f 1.CHGCAR +mv AECCAR0 1.AECCAR0 +mv AECCAR2 1.AECCAR2 +mv vasprun.xml 1.vasprun.xml +rm WAVECAR # rm_chg_wav flag + +#Footer section: +rm PROCAR DOSCAR OSZICAR PCDAT REPORT XDATCAR vasprun.xml +rm RUNNING diff --git a/tutorials/Bi2Se3/Bi2Se3.bader/Bi2Se3_mp-541837_computed.POSCAR b/tutorials/Bi2Se3/Bi2Se3.bader/Bi2Se3_mp-541837_computed.POSCAR new file mode 100644 index 0000000..510fa96 --- /dev/null +++ b/tutorials/Bi2Se3/Bi2Se3.bader/Bi2Se3_mp-541837_computed.POSCAR @@ -0,0 +1,13 @@ +Bi2 Se3 +1.0 +4.103097 0.000000 9.409867 +1.962329 3.603424 9.409867 +0.000000 0.000000 10.265525 +Bi Se +2 3 +direct +0.398435 0.398435 0.398435 Bi +0.601565 0.601565 0.601565 Bi +0.000000 0.000000 0.000000 Se +0.215715 0.215715 0.215715 Se +0.784285 0.784285 0.784285 Se diff --git a/tutorials/Bi2Se3/Bi2Se3.bader/INCAR b/tutorials/Bi2Se3/Bi2Se3.bader/INCAR new file mode 100644 index 0000000..26cfd11 --- /dev/null +++ b/tutorials/Bi2Se3/Bi2Se3.bader/INCAR @@ -0,0 +1,27 @@ +SYSTEM = auto add_des ; no description for these set, see history +ADDGRID = .TRUE. +ALGO = Normal +EDIFF = 1e-08 +EDIFFG = 0 +ENAUG = 776.16 +ENCUT = 441.0 +IBRION = 1 +ICHARG = 1 +ISIF = 2 +ISMEAR = 2 +ISTART = 0 +KGAMMA = .TRUE. +LAECHG = .TRUE. +LPLANE = .TRUE. +LREAL = Auto +LSCALU = .FALSE. +MAXMIX = 40 +NBANDS = 38 +NELM = 100 +NELMIN = 4 +NPAR = 1 +NSIM = 4 +NSW = 0 +PREC = Accurate +SIGMA = 0.2 + diff --git a/tutorials/Bi2Se3/Bi2Se3.bader/KPOINTS b/tutorials/Bi2Se3/Bi2Se3.bader/KPOINTS new file mode 100644 index 0000000..99a0213 --- /dev/null +++ b/tutorials/Bi2Se3/Bi2Se3.bader/KPOINTS @@ -0,0 +1,5 @@ +Automatic Mesh +0 +Gamma +8 8 8 +0 0 0 diff --git a/tutorials/Configure.ipynb b/tutorials/Configure.ipynb index a12dbe0..68af2d7 100644 --- a/tutorials/Configure.ipynb +++ b/tutorials/Configure.ipynb @@ -1,7 +1,7 @@ { "metadata": { "name": "", - "signature": "sha256:443892cd776f9de1ef7d55829a60f6c3a1ae1169187dd95cdb26451b04b9efcd" + "signature": "sha256:739a52c62ead6d3e233e7d5792bf2d9d596d60be0adae4bfad6615088c246d57" }, "nbformat": 3, "nbformat_minor": 0, @@ -58,7 +58,11 @@ "'pythonpath':'/usr/lib64/python2.7/site-packages/numpy',\n", "'vasp_com':'prun /opt/vasp/bin/vasp5.4.1MPI', # path to vasp binary\n", "#optional parameters:\n", - "'sshpath':True # use sshpath in rsync commands \n", + "'sshpath':True # use sshpath in rsync commands\n", + "'modules':'module load Compilers/Intel/psxe_2015.6; \\\n", + " module load MPI/intel/5.1.3.258/intel; \\\n", + " module load QCh/VASP/5.4.1p1/psxe2015.6; \\\n", + " module load ScriptLang/python/2.7' # additional commands for PBS script, such as load of moudli\n", "}\n", "\n" ], diff --git a/tutorials/bader.ipynb b/tutorials/bader.ipynb new file mode 100644 index 0000000..6d3200f --- /dev/null +++ b/tutorials/bader.ipynb @@ -0,0 +1,322 @@ +{ + "metadata": { + "name": "", + "signature": "sha256:c9b8042f2a5a522f4549d8592cc63f9152da7c15e14725837a1c24c850cb4879" + }, + "nbformat": 3, + "nbformat_minor": 0, + "worksheets": [ + { + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#Calculation of Bader charges\n", + "The approach uses additional tool developled in [Henkelman group](http://theory.cm.utexas.edu/henkelman/code/bader/).\n", + "\n", + "Download [binary 'bader'](http://theory.cm.utexas.edu/henkelman/code/bader/download/bader_lnx_64.tar.gz) for Bader analysis and put it to *~/tools/* folder on your cluster.\n" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "#Usual preamble\n", + "import sys\n", + "sys.path.extend(['/home/aksenov/Simulation_wrapper/siman'])\n", + "from SSHTools import SSHTools\n", + "from calc_manage import add_loop, res_loop\n", + "from set_functions import read_vasp_sets\n", + "from database import read_database, write_database\n", + "import header\n", + "from header import db\n", + "read_database()\n", + "header.PATH2PROJECT = 'topologic' # path to project relative to your home folder on cluster\n", + "header.PATH2POTENTIALS = '/home/aksenov/scientific_projects/PAW_PBE_VASP' #path to VASP POTENTIALS\n", + "header.varset['static'].potdir = {83:'Bi_pv', 34:'Se'} #subfolders with required potentials\n", + "header.ssh_object = SSHTools()\n", + "header.ssh_object.setup(user=\"aksenov\",host=\"10.30.16.62\",pkey=\"/home/aksenov/.ssh/id_rsa\")" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 1 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "#Creating new set 'bader' with parameters for Bader charges calculation\n", + "bader_pack = {'PREC':'Accurate', 'ADDGRID':'.TRUE.', 'EDIFF':1e-08, \n", + " 'LAECHG':'.TRUE.', 'NELM':100, 'NSW':0, 'ICHARG':1, 'savefile' : 'acox'}\n", + "read_vasp_sets([('bader', 'static', bader_pack, 'override')]) #new set 'bader' from 'static'" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "Attention! You have chosen to override set bader\n", + " \n", + "\n", + "Warning! You did not change NSW in bader set\n", + " \n", + "\n" + ] + }, + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 5, + "text": [ + "{'dos': ,\n", + " 'band': ,\n", + " 'static': ,\n", + " 'opt': ,\n", + " 'bader': }" + ] + } + ], + "prompt_number": 5 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "add_loop('Bi2Se3', 'bader', 1, input_geo_file = 'Bi2Se3_mp-541837_computed.POSCAR', run = 1) # Submitting VASP job" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "-- Attention!, cluster None is not found, using default cee \n", + "\n", + "-- check_kpoints(): Kpoint mesh is: [8, 8, 8] \n", + "\n" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "-- check_kpoints(): The actual k-spacings are [ 0.22 0.22 0.22] \n", + "\n", + "-- POSCAR was written to Bi2Se3//Bi2Se3.bader/1.POSCAR \n", + "\n", + "-- Attention! ngkpt = [8, 8, 8] is adopted from struct_des which you provided for it Bi2Se3 and kspacing = 0.235 \n", + "\n", + "\n", + "Calculation ('Bi2Se3', 'bader', 1) successfully created\n", + "\n", + " \n", + "\n" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)\n", + " 169829 AMG KVPO516. aksenov R 2-23:23:45 1 node-amg01\n", + " 168188 AMG LTP_sa2_ asergeev R 6-14:04:15 1 node-amg04\n", + "Submitted batch job 180604\n", + " JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)\n", + " 180604 AMG Bi2Se3.b aksenov PD 0:00 1 (None)\n", + " 169829 AMG KVPO516. aksenov R 2-23:23:45 1 node-amg01\n", + " 168188 AMG LTP_sa2_ asergeev R 6-14:04:15 1 node-amg04 \n", + "\n" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "-- To read results use res_loop('Bi2Se3', ['bader'], [1], show = 'fo' ) # , on 2018-07-05 ; possible options for show: fit, fo, fop, en, mag, magp, smag, maga, occ, occ1, mep, mepp \n", + "\n" + ] + }, + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 7, + "text": [ + "'Bi2Se3'" + ] + } + ], + "prompt_number": 7 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "res_loop('Bi2Se3', 'bader', 1) #reading results after the job is finished\n", + "write_database() # writing database" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "\n", + "Max. F. tot (meV/A) = \n", + "[59]; \n", + "\n", + "-- name | energy(eV)| Vector lenghts (A) | Stresses (MPa) | N MD, N SCF \n", + "-- Bi2Se3.bader.1 | -20.1524 |10.27;10.27;10.27| -684,-684,-685 | 1,18, 18 \n", + "\n", + "Database has been successfully updated\n", + "\n" + ] + } + ], + "prompt_number": 10 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "header.warnings = 'yY'\n", + "# Calculate Bader charges on cluster \n", + "db['Bi2Se3', 'bader', 1].get_bader_ACF()\n" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "\n", + "Max. F. tot (meV/A) = \n", + "[59]; \n", + "\n", + "-- name | energy(eV)| Vector lenghts (A) | Stresses (MPa) | N MD, N SCF \n", + "-- Bi2Se3.bader.1 | -20.1524 |10.27;10.27;10.27| -684,-684,-685 | 1,18, 18 \n", + "-- /home/aksenov/topologic/Bi2Se3//Bi2Se3.bader/1.CHGCAR_sum does not exist. trying to calculate it \n", + "\n" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "Atoms in file1: 5, Atoms in file2: 5\n", + "Points in file1: 2744000, Points in file2: 2744000\n", + " \n", + "\n" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "-- Warning! File /home/aksenov/topologic/Bi2Se3//Bi2Se3.bader/1.CHGCAR does not exist. Checking .gz .. \n", + "\n" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + " \n", + "\n" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "ACF_text = " + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + " X Y Z CHARGE MIN DIST ATOMIC VOL\n", + " --------------------------------------------------------------------------------\n", + " 1 2.416678 1.435730 11.588585 20.170149 0.923287 27.967000\n", + " 2 3.648748 2.167694 17.496674 20.170148 0.923287 27.966944\n", + " 3 0.000000 0.000000 0.000000 6.694249 0.990643 29.794916\n", + " 4 1.308403 0.777313 6.274127 6.465561 0.934850 32.843083\n", + " 5 4.757023 2.826111 22.811132 6.468233 0.934850 32.894469\n", + " --------------------------------------------------------------------------------\n", + " VACUUM CHARGE: 0.0317\n", + " VACUUM VOLUME: 0.3114\n", + " NUMBER OF ELECTRONS: 60.0000\n" + ] + }, + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 2, + "text": [ + "[20.17, 20.17, 6.694, 6.466, 6.468]" + ] + } + ], + "prompt_number": 2 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "print(db['Bi2Se3', 'bader', 1].charges) # print calculated Bader charges" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "[20.17, 20.17, 6.694, 6.466, 6.468]\n" + ] + } + ], + "prompt_number": 3 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "#Calculate oxidation states\n", + "from analysis import calc_oxidation_states\n", + "\n", + "calc_oxidation_states( db['Bi2Se3', 'bader', 1] )\n" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "Bi 0.8\n", + "Bi 0.8\n", + "Se -0.7\n", + "Se -0.5\n", + "Se -0.5\n" + ] + } + ], + "prompt_number": 4 + } + ], + "metadata": {} + } + ] +} \ No newline at end of file diff --git a/tutorials/calc.gdbm3 b/tutorials/calc.gdbm3 index fafb1a6970aedea2f0d4ea64b980387aada1edfa..3fa254b521854c99283794d2cc0498ea0cc01628 100644 GIT binary patch literal 24433 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 WuaG+y0arU0gsbbHaISV)(H{aW{tfm3 literal 19494 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 NuzK~SV|CU}{S(?4T5tdW diff --git a/tutorials/only_calc.gdbm3 b/tutorials/only_calc.gdbm3 index ab304a1071524fa0e13ecf5c233372211081b30c..84ea37fb7fc9a47bfaa71f99e7fb2b45f0a91ff9 100644 GIT binary patch delta 6219 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