vasputils 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/bin/checkvasp +79 -0
- data/bin/runvasp +23 -5
- data/lib/vasputils/vaspdir.rb +6 -0
- data/lib/vasputils/vaspgeomopt.rb +19 -19
- data/lib/vasputils/vaspkpointsfinder.rb +72 -0
- data/memo.txt +5 -0
- data/test/test_calcinspector.rb +29 -29
- data/test/test_incar.rb +109 -109
- data/test/test_kpoints.rb +92 -92
- data/test/test_outcar.rb +154 -154
- data/test/test_poscar.rb +184 -184
- data/test/test_potcar.rb +52 -52
- data/test/test_vaspdir.rb +10 -0
- data/test/test_vaspkpointsfinder.rb +25 -0
- data/test/vaspkpointsfinder/01-01-01/try00/INCAR +17 -0
- data/test/vaspkpointsfinder/01-01-01/try00/KPOINTS +6 -0
- data/test/vaspkpointsfinder/01-01-01/try00/POSCAR +8 -0
- data/test/vaspkpointsfinder/01-01-01/try00/POTCAR +0 -0
- data/vasputils.gemspec +10 -6
- metadata +31 -29
- data/bin/lsvasp +0 -95
- data/bin/lsvaspdir +0 -63
- data/bin/lsvaspseries +0 -95
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.9
|
data/bin/checkvasp
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
# Show state of vasp geometry optimization calculations.
|
5
|
+
|
6
|
+
#require "vasputils/calcseries.rb"
|
7
|
+
require "rubygems"
|
8
|
+
gem "vasputils"
|
9
|
+
|
10
|
+
require "vasputils/vaspgeomopt.rb"
|
11
|
+
require "vasputils/vaspdir.rb"
|
12
|
+
require "pp"
|
13
|
+
#require "optparse"
|
14
|
+
|
15
|
+
LONGEST_STATE = :terminated.size
|
16
|
+
KLASSES = [VaspDir, VaspGeomOpt]
|
17
|
+
|
18
|
+
dirs = ARGV
|
19
|
+
dirs = Dir.glob("*").sort if ARGV.empty?
|
20
|
+
|
21
|
+
def guess(dir)
|
22
|
+
KLASSES.each do |klass|
|
23
|
+
begin
|
24
|
+
vd = klass.new(dir)
|
25
|
+
return klass
|
26
|
+
rescue klass::InitializeError
|
27
|
+
end
|
28
|
+
end
|
29
|
+
raise "Cannot identify class for directory #{dir}."
|
30
|
+
end
|
31
|
+
|
32
|
+
dirs.each do |dir|
|
33
|
+
next unless File.directory? dir
|
34
|
+
|
35
|
+
begin
|
36
|
+
klass = guess(dir)
|
37
|
+
klass_name = klass.to_s
|
38
|
+
rescue
|
39
|
+
klass_name = "UnknownDir"
|
40
|
+
end
|
41
|
+
|
42
|
+
printf "%-11s ", klass_name
|
43
|
+
|
44
|
+
case klass_name
|
45
|
+
when "VaspDir"
|
46
|
+
calc = klass.new(dir)
|
47
|
+
printf "%-10s ", calc.state
|
48
|
+
#pp calc.outcar
|
49
|
+
printf "%5s ", ""
|
50
|
+
begin
|
51
|
+
outcar = calc.outcar
|
52
|
+
printf "%8.3f %3d (%3d) ",
|
53
|
+
outcar[:totens][-1], outcar[:ionic_steps], outcar[:electronic_steps]
|
54
|
+
rescue
|
55
|
+
printf "%8s %3s (%3s) ", " "*8, " "*3, " "*3
|
56
|
+
end
|
57
|
+
|
58
|
+
when "VaspGeomOpt"
|
59
|
+
calc = klass.new(dir)
|
60
|
+
printf "%-10s ", calc.state
|
61
|
+
|
62
|
+
ld = calc.latest_dir
|
63
|
+
printf "%5s ", ld.dir.sub(/.*try/, "try")
|
64
|
+
begin
|
65
|
+
outcar = ld.outcar
|
66
|
+
printf "%8.3f %3d (%3d) ",
|
67
|
+
outcar[:totens][-1], outcar[:ionic_steps], outcar[:electronic_steps]
|
68
|
+
rescue
|
69
|
+
printf "%8s %3s (%3s) ", " "*8, " "*3, " "*3
|
70
|
+
end
|
71
|
+
|
72
|
+
when "UnknownDir"
|
73
|
+
printf "-" * 35
|
74
|
+
printf " "
|
75
|
+
|
76
|
+
end
|
77
|
+
puts dir
|
78
|
+
|
79
|
+
end
|
data/bin/runvasp
CHANGED
@@ -12,17 +12,35 @@ require "vasputils/vaspgeomopt.rb"
|
|
12
12
|
require "optparse"
|
13
13
|
|
14
14
|
## option analysis
|
15
|
-
|
15
|
+
opts = {}
|
16
16
|
op = OptionParser.new
|
17
|
-
op.on("-g" , "--geom-opt",
|
17
|
+
op.on("-g" , "--geom-opt", "Geometry optimization"){opts[:geom] = true}
|
18
|
+
op.on("-c" , "--cond-find", "Condition finding" ){opts[:cond] = true}
|
18
19
|
op.parse!(ARGV)
|
19
20
|
|
20
21
|
dir = ARGV[0] || "."
|
21
22
|
|
22
|
-
if
|
23
|
-
|
23
|
+
if opts[:geom] && opts[:cond]
|
24
|
+
puts "-g and -c must not be duplicated."
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
|
28
|
+
if opts[:geom]
|
29
|
+
begin
|
30
|
+
calc_dir = VaspGeomOpt.new(dir)
|
31
|
+
rescue VaspGeomOpt::NoVaspDirError
|
32
|
+
puts "Not suitable for VaspGeomOpt: #{dir}"
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
elsif opts[:cond]
|
36
|
+
TODO
|
24
37
|
else
|
25
|
-
|
38
|
+
begin
|
39
|
+
calc_dir = VaspDir.new(dir)
|
40
|
+
rescue VaspDir::InitializeError
|
41
|
+
puts "Not VaspDir: #{dir}"
|
42
|
+
exit
|
43
|
+
end
|
26
44
|
end
|
27
45
|
|
28
46
|
#pp calc_dir.class.ancestors
|
data/lib/vasputils/vaspdir.rb
CHANGED
@@ -40,6 +40,12 @@ class VaspDir < ComputationManager
|
|
40
40
|
Outcar.load_file("#{@dir}/OUTCAR")
|
41
41
|
end
|
42
42
|
|
43
|
+
# 配下の POSCAR を Cell2 インスタンスにして返す。
|
44
|
+
# 存在しなければ例外 Errno::ENOENT を返す。
|
45
|
+
def poscar
|
46
|
+
Poscar.load_file("#{@dir}/POSCAR")
|
47
|
+
end
|
48
|
+
|
43
49
|
# 配下の CONTCAR を Cell2 インスタンスにして返す。
|
44
50
|
# 存在しなければ例外 Errno::ENOENT を返す。
|
45
51
|
def contcar
|
@@ -70,6 +70,25 @@ class VaspGeomOpt < ComputationManager
|
|
70
70
|
return true
|
71
71
|
end
|
72
72
|
|
73
|
+
# Find latest VaspDir.
|
74
|
+
# Return a last VaspDir which has the name by name sort
|
75
|
+
# and which can be made as a VaspDir instance.
|
76
|
+
# Note: in a series of geometry optimization,
|
77
|
+
# the directory names should have a rule of naming
|
78
|
+
# which can define a method <=>.
|
79
|
+
# Usually, it is simple sort of String.
|
80
|
+
def latest_dir
|
81
|
+
Dir.glob("#{@dir}/*").sort.reverse.find do |dir|
|
82
|
+
begin
|
83
|
+
vd = VaspDir.new(dir)
|
84
|
+
return vd
|
85
|
+
rescue VaspDir::InitializeError
|
86
|
+
next
|
87
|
+
end
|
88
|
+
end
|
89
|
+
raise NoVaspDirError, @dir
|
90
|
+
end
|
91
|
+
|
73
92
|
private
|
74
93
|
|
75
94
|
# Generate next directory of latest_dir.
|
@@ -92,24 +111,5 @@ class VaspGeomOpt < ComputationManager
|
|
92
111
|
VaspDir.new(new_dir)
|
93
112
|
end
|
94
113
|
|
95
|
-
# Find latest VaspDir.
|
96
|
-
# Return a last VaspDir which has the name by name sort
|
97
|
-
# and which can be made as a VaspDir instance.
|
98
|
-
# Note: in a series of geometry optimization,
|
99
|
-
# the directory names should have a rule of naming
|
100
|
-
# which can define a method <=>.
|
101
|
-
# Usually, it is simple sort of String.
|
102
|
-
def latest_dir
|
103
|
-
Dir.glob("#{@dir}/*").sort.reverse.find do |dir|
|
104
|
-
begin
|
105
|
-
vd = VaspDir.new(dir)
|
106
|
-
return vd
|
107
|
-
rescue VaspDir::InitializeError
|
108
|
-
next
|
109
|
-
end
|
110
|
-
end
|
111
|
-
raise NoVaspDirError, @dir
|
112
|
-
end
|
113
|
-
|
114
114
|
end
|
115
115
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require "vasputils/vaspdir.rb"
|
5
|
+
|
6
|
+
#
|
7
|
+
#
|
8
|
+
#
|
9
|
+
class VaspKpointsFinder
|
10
|
+
|
11
|
+
|
12
|
+
def initialize(dir)
|
13
|
+
@dir = dir # redefine in subclass.
|
14
|
+
@lockdir = "lock_vaspkfind"
|
15
|
+
@alive_time = 3600
|
16
|
+
|
17
|
+
@previous_kpoints = nil
|
18
|
+
@kpoints = [ 0, 0, 0 ] #indicate ka, kb, kc
|
19
|
+
|
20
|
+
@kpoint_candidates = list_kpoints
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def calculate
|
26
|
+
@previous_kpoints = Marshal.load(Marshal.dump(@kpoints))
|
27
|
+
|
28
|
+
#@kpoints を起点として、
|
29
|
+
#ka の最適化し、精度以下となる最低の条件を @kpoints に登録。
|
30
|
+
#kb の最適化し、精度以下となる最低の条件を @kpoints に登録。
|
31
|
+
#kc の最適化し、精度以下となる最低の条件を @kpoints に登録。
|
32
|
+
3.times do |i| # each three k axis.
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
#k の gamma center / hexagonal
|
37
|
+
#k の shift
|
38
|
+
#spin の有無。当面は有りを前提。INCAR で ISPIN をチェックする。
|
39
|
+
end
|
40
|
+
|
41
|
+
# Do nothing.
|
42
|
+
def prepare_next
|
43
|
+
end
|
44
|
+
|
45
|
+
def finished?
|
46
|
+
@previous_kpoints == @kpoints
|
47
|
+
end
|
48
|
+
|
49
|
+
# Using lattice constants of POSCAR, which is an initial value.
|
50
|
+
#
|
51
|
+
def list_kpoints
|
52
|
+
#vd = VaspDir.new(Dir.glob(@dir + "/*/try00")[0])
|
53
|
+
#results = []
|
54
|
+
#vd.poscar.axes.get_lattice_constants[0..2].map do |length|
|
55
|
+
#end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
#def lowest_encut
|
61
|
+
# min_dir = Dir.glob(@dir + "/*/*").min_by { |dir| VaspDir.new(dir).incar["ENCUT"] }
|
62
|
+
# VaspDir.new(min_dir).incar["ENCUT"].to_i
|
63
|
+
#end
|
64
|
+
|
65
|
+
#def list_encuts
|
66
|
+
# results = []
|
67
|
+
# (lowest_encut/100).upto 10 do |i|
|
68
|
+
# results << i * 100
|
69
|
+
# end
|
70
|
+
# results
|
71
|
+
#end
|
72
|
+
|
data/memo.txt
CHANGED
data/test/test_calcinspector.rb
CHANGED
@@ -5,47 +5,47 @@ require "test/unit"
|
|
5
5
|
require "vasputils/calcinspector.rb"
|
6
6
|
|
7
7
|
class YetCalc
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
def started? ; return false; end
|
9
|
+
def normal_ended? ; return false; end
|
10
|
+
def to_be_continued?; return false; end
|
11
|
+
def finished? ; return false; end
|
12
12
|
end
|
13
13
|
|
14
14
|
class StartedCalc
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
def started? ; return true ; end
|
16
|
+
def normal_ended? ; return false; end
|
17
|
+
def to_be_continued?; return false; end
|
18
|
+
def finished? ; return false; end
|
19
19
|
end
|
20
20
|
|
21
21
|
class NextCalc
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
def started? ; return true ; end
|
23
|
+
def normal_ended? ; return true ; end
|
24
|
+
def to_be_continued?; return true ; end
|
25
|
+
def finished? ; return false; end
|
26
26
|
end
|
27
27
|
|
28
28
|
class FinishedCalc
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
def started? ; return true ; end
|
30
|
+
def normal_ended? ; return true ; end
|
31
|
+
def to_be_continued?; return false; end
|
32
|
+
def finished? ; return true ; end
|
33
33
|
end
|
34
34
|
|
35
35
|
class TC_ListCalculation < Test::Unit::TestCase
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
36
|
+
def setup
|
37
|
+
@dc00 = YetCalc.new
|
38
|
+
@dc01 = StartedCalc.new
|
39
|
+
@dc02 = NextCalc.new
|
40
|
+
@dc03 = FinishedCalc.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_self_inspect
|
44
|
+
assert_equal("YET", CalcInspector.inspect(@dc00))
|
45
|
+
assert_equal("STARTED", CalcInspector.inspect(@dc01))
|
46
|
+
assert_equal("NEXT", CalcInspector.inspect(@dc02))
|
47
|
+
assert_equal("FINISHED", CalcInspector.inspect(@dc03))
|
48
|
+
end
|
49
49
|
|
50
50
|
|
51
51
|
|
data/test/test_incar.rb
CHANGED
@@ -5,122 +5,122 @@ require "test/unit"
|
|
5
5
|
require "vasputils/incar.rb"
|
6
6
|
require "stringio"
|
7
7
|
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
8
|
+
# assert_equal( cor, data)
|
9
|
+
# assert_in_delta( cor, data, $tolerance )
|
10
|
+
# assert_raise( RuntimeError ){}
|
11
11
|
|
12
12
|
class TC_Incar < Test::Unit::TestCase
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
13
|
+
#def setup
|
14
|
+
# @k = Incar.new
|
15
|
+
#end
|
16
|
+
|
17
|
+
SAMPLE_PAIRS = {
|
18
|
+
"SYSTEM" => "Untitled",
|
19
|
+
"PREC" => "High",
|
20
|
+
"IBRION" => "2",
|
21
|
+
"NSW" => "100",
|
22
|
+
"ISIF" => "2",
|
23
|
+
"ENCUT" => "400",
|
24
|
+
"NELM" => "60",
|
25
|
+
"NELMIN" => "2",
|
26
|
+
"EDIFF" => "1.0e-05",
|
27
|
+
"EDIFFG" => "-0.02",
|
28
|
+
"VOSKOWN" => "1",
|
29
|
+
"NBLOCK" => "1",
|
30
|
+
"ISPIN" => "1",
|
31
|
+
"INIWAV" => "1",
|
32
|
+
"ISTART" => "1",
|
33
|
+
"ICHARG" => "1",
|
34
|
+
"LWAVE" => ".TRUE.",
|
35
|
+
"LCHARG" => ".TRUE.",
|
36
|
+
"ISMEAR" => "0",
|
37
|
+
"SIGMA" => "0.1",
|
38
|
+
"IALGO" => "38",
|
39
|
+
"LREAL" => "Auto",
|
40
|
+
"NGX" => "36",
|
41
|
+
"NGY" => "36",
|
42
|
+
"NGZ" => "42",
|
43
|
+
}
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
45
|
+
def test_self_parse
|
46
|
+
io = StringIO.new
|
47
|
+
io.puts "# SCF input for VASP"
|
48
|
+
io.puts "# Note that VASP uses the FIRST occurence of a keyword"
|
49
|
+
io.puts "# if single point calc, IBRION = -1, NSW = 0, and comment out ISIF"
|
50
|
+
io.puts ""
|
51
|
+
io.puts "SYSTEM = Untitled (VASP)"
|
52
|
+
io.puts " PREC = High"
|
53
|
+
io.puts " IBRION = 2 #-1:atoms not moved, 1:quasi-Newton, 2:conjugate-gradient"
|
54
|
+
io.puts " NSW = 100 #maximum number of ionic steps"
|
55
|
+
io.puts " ISIF = 2"
|
56
|
+
io.puts " ENCUT = 400"
|
57
|
+
io.puts " NELM = 60 #maximum number of electronic steps"
|
58
|
+
io.puts " NELMIN = 2 #minimum number of electronic steps"
|
59
|
+
io.puts " EDIFF = 1.0e-05"
|
60
|
+
io.puts " EDIFFG = -0.02"
|
61
|
+
io.puts " VOSKOWN = 1"
|
62
|
+
io.puts " NBLOCK = 1"
|
63
|
+
io.puts " ISPIN = 1 #1:non spin polarized, 2:spin polarized"
|
64
|
+
io.puts " INIWAV = 1"
|
65
|
+
io.puts " ISTART = 1"
|
66
|
+
io.puts " ICHARG = 1"
|
67
|
+
io.puts " LWAVE = .TRUE."
|
68
|
+
io.puts " LCHARG = .TRUE."
|
69
|
+
io.puts " ISMEAR = 0"
|
70
|
+
io.puts " SIGMA = 0.1"
|
71
|
+
io.puts " IALGO = 38 #38:KosugiAlgorithm, 48:RMM-DIIS"
|
72
|
+
io.puts " LREAL = Auto #fast & not accurate"
|
73
|
+
io.puts " NGX = 36"
|
74
|
+
io.puts " NGY = 36"
|
75
|
+
io.puts " NGZ = 42"
|
76
|
+
io.rewind
|
77
|
+
pairs = Incar.parse(io)
|
78
|
+
assert_equal(SAMPLE_PAIRS, pairs)
|
79
|
+
end
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
def test_self_load_file
|
82
|
+
pairs = Incar.load_file "test/incar/INCAR.00"
|
83
|
+
assert_equal(SAMPLE_PAIRS, pairs)
|
84
84
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
85
|
+
corrects = {
|
86
|
+
"SYSTEM" => "Untitled",
|
87
|
+
"PREC" => "High",
|
88
|
+
"IBRION" => "2",
|
89
|
+
"NSW" => "0",
|
90
|
+
"ISIF" => "2",
|
91
|
+
"ENCUT" => "400",
|
92
|
+
"NELM" => "60",
|
93
|
+
"NELMIN" => "2",
|
94
|
+
"EDIFF" => "1.0e-05",
|
95
|
+
"EDIFFG" => "-0.02",
|
96
|
+
"VOSKOWN" => "1",
|
97
|
+
"NBLOCK" => "1",
|
98
|
+
"ISPIN" => "1",
|
99
|
+
"INIWAV" => "1",
|
100
|
+
"ISTART" => "1",
|
101
|
+
"ICHARG" => "1",
|
102
|
+
"LWAVE" => ".TRUE.",
|
103
|
+
"LCHARG" => ".TRUE.",
|
104
|
+
"ISMEAR" => "0",
|
105
|
+
"SIGMA" => "0.1",
|
106
|
+
"IALGO" => "38",
|
107
|
+
"LREAL" => "Auto",
|
108
|
+
"NGX" => "36",
|
109
|
+
"NGY" => "36",
|
110
|
+
"NGZ" => "42",
|
111
|
+
}
|
112
|
+
pairs = Incar.load_file "test/incar/INCAR.01"
|
113
|
+
assert_equal(corrects, pairs)
|
114
114
|
|
115
|
-
|
116
|
-
|
117
|
-
|
115
|
+
# not exist
|
116
|
+
assert_raise(Errno::ENOENT){Incar.load_file("")}
|
117
|
+
end
|
118
118
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
119
|
+
#def test_dump
|
120
|
+
#
|
121
|
+
#
|
122
|
+
# TODO
|
123
|
+
#end
|
124
124
|
|
125
125
|
end
|
126
126
|
|