vasputils 0.0.1 → 0.0.2
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/Gemfile +1 -1
- data/VERSION +1 -1
- data/bin/qsubvasp +30 -0
- data/lib/vasputils/vaspdir.rb +176 -218
- data/test/test_vaspdir.rb +59 -189
- data/test/vaspdir/finished/CONTCAR +17 -0
- data/test/vaspdir/finished/INCAR +27 -0
- data/test/vaspdir/finished/KPOINTS +6 -0
- data/test/vaspdir/finished/OUTCAR +1436 -0
- data/test/vaspdir/finished/POSCAR +12 -0
- data/test/vaspdir/finished/POTCAR +16 -0
- data/test/vaspdir/finished/lock +0 -0
- data/test/vaspdir/lack-INCAR/KPOINTS +5 -4
- data/test/vaspdir/lack-INCAR/POSCAR +11 -56
- data/test/vaspdir/lack-INCAR/POTCAR +13 -695
- data/test/vaspdir/lack-KPOINTS/INCAR +2 -3
- data/test/vaspdir/lack-KPOINTS/POSCAR +11 -56
- data/test/vaspdir/lack-KPOINTS/POTCAR +13 -695
- data/test/vaspdir/lack-POSCAR/INCAR +2 -3
- data/test/vaspdir/lack-POSCAR/KPOINTS +5 -4
- data/test/vaspdir/lack-POSCAR/POTCAR +13 -695
- data/test/vaspdir/lack-POTCAR/INCAR +2 -3
- data/test/vaspdir/lack-POTCAR/KPOINTS +5 -4
- data/test/vaspdir/lack-POTCAR/POSCAR +11 -56
- data/test/vaspdir/locked/INCAR +28 -0
- data/test/vaspdir/locked/KPOINTS +6 -0
- data/test/vaspdir/locked/POSCAR +12 -0
- data/test/vaspdir/locked/POTCAR +16 -0
- data/test/vaspdir/locked/lock +0 -0
- data/test/vaspdir/not-yet/INCAR +28 -0
- data/test/vaspdir/not-yet/KPOINTS +6 -0
- data/test/vaspdir/not-yet/POSCAR +12 -0
- data/test/vaspdir/not-yet/POTCAR +16 -0
- data/test/vaspdir/started/CONTCAR +17 -0
- data/test/vaspdir/started/INCAR +27 -0
- data/test/vaspdir/started/KPOINTS +6 -0
- data/test/vaspdir/started/OUTCAR +1028 -0
- data/test/vaspdir/started/POSCAR +12 -0
- data/test/vaspdir/started/POTCAR +16 -0
- data/test/vaspdir/started/lock +0 -0
- data/vasputils.gemspec +27 -3
- metadata +48 -23
data/Gemfile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/bin/qsubvasp
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
require "optparse"
|
5
|
+
|
6
|
+
## option analysis
|
7
|
+
OPTS = {}
|
8
|
+
op = OptionParser.new
|
9
|
+
op.on("-e", "--economy" , "Prior efficiency."){OPTS[:e] = true}
|
10
|
+
op.on("-s", "--speed" , "Prior speed.") {OPTS[:s] = true}
|
11
|
+
|
12
|
+
op.on("-g", "--geom-opt" , "Geometry optimization.") {OPTS[:g] = true}
|
13
|
+
op.on("-n", "--nebm" , "Nudged Elastic Band method."){OPTS[:n] = true}
|
14
|
+
op.on("-c", "--cond-find", "Condition Finding.") {OPTS[:c] = true}
|
15
|
+
|
16
|
+
op.parse!(ARGV)
|
17
|
+
|
18
|
+
cluster = ARGV[0]
|
19
|
+
#cluster = ARGV
|
20
|
+
#qsub で複数のクラスターを候補に入れることができるか?e.g., Ga, Ge
|
21
|
+
#それによって、ここがかきかわる。
|
22
|
+
|
23
|
+
puts "Options -e and -s cannot be duplicated." if OPTS[:e] && OPTS[:s]
|
24
|
+
if [OPTS[:g], OPTS[:n], OPTS[:c]].select_all(true).size ==
|
25
|
+
puts "Options -g, -n, and -c cannot be duplicated."
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
|
data/lib/vasputils/vaspdir.rb
CHANGED
@@ -26,115 +26,35 @@ require "vasputils/kpoints.rb"
|
|
26
26
|
# try00 形式の postfix がついていることを前提とする。
|
27
27
|
# 00 の部分には CONTCAR を POSCAR にする手続きで連続して行う計算の番号を示す。
|
28
28
|
#
|
29
|
-
class VaspDir
|
30
|
-
|
29
|
+
class VaspDir < Comana
|
31
30
|
class InitializeError < Exception; end
|
32
|
-
class ConvergedError < Exception; end
|
33
|
-
class NotEndedError < Exception; end
|
34
|
-
class LockedError < Exception; end
|
35
|
-
class PostfixMismatchError < Exception; end
|
36
|
-
|
37
|
-
|
38
|
-
LOCK_FILE = "lock"
|
39
|
-
POSTFIX = /try(\d+)$/
|
40
|
-
|
41
|
-
YET = 0# - 未計算。
|
42
|
-
STARTED = 1# - 開始した。
|
43
|
-
INTERRUPTED = 2# - 中断された。
|
44
|
-
CONTINUED = 3# - 終了し、次の計算を生成した。
|
45
|
-
COMPLETED = 4# - 終了し、収束した。
|
46
|
-
|
47
|
-
attr_reader :mode
|
48
|
-
#attr_reader :dir
|
49
|
-
|
50
|
-
#INCAR 解析とかして、モードを調べる。
|
51
|
-
#- 格子定数の構造最適化モード(ISIF = 3)
|
52
|
-
#- 格子定数を固定した構造最適化モード(ISIF = 2)
|
53
|
-
##- k 点探索モードは無理だろう。
|
54
|
-
def initialize(dir_name)
|
55
|
-
@dir = dir_name
|
56
|
-
|
57
|
-
%w(INCAR KPOINTS POSCAR POTCAR).each do |file|
|
58
|
-
infile = "#{@dir}/#{file}"
|
59
|
-
raise InitializeError, infile unless FileTest.exist? infile
|
60
|
-
end
|
61
31
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
#when "1"
|
67
|
-
# @mode = :molecular_dynamics
|
68
|
-
when "2"
|
69
|
-
if (@incar["ISIF"] == "2")
|
70
|
-
@mode = :geom_opt_atoms
|
71
|
-
elsif (@incar["ISIF"] == "3")
|
72
|
-
@mode = :geom_opt_lattice
|
73
|
-
else
|
74
|
-
@mode = :geom_opt
|
75
|
-
end
|
76
|
-
else
|
77
|
-
@mode = nil
|
78
|
-
end
|
32
|
+
# 配下の OUTCAR を Outcar インスタンスにして返す。
|
33
|
+
# 存在しなければ例外 Errno::ENOENT を返す。
|
34
|
+
def outcar
|
35
|
+
Outcar.load_file("#{@dir}/OUTCAR")
|
79
36
|
end
|
80
37
|
|
81
|
-
#
|
82
|
-
|
83
|
-
|
38
|
+
# 配下の CONTCAR を Cell2 インスタンスにして返す。
|
39
|
+
# 存在しなければ例外 Errno::ENOENT を返す。
|
40
|
+
def contcar
|
41
|
+
Poscar.load_file("#{@dir}/CONTCAR")
|
84
42
|
end
|
85
43
|
|
86
|
-
#
|
87
|
-
# 終わっているかは判定しない。
|
88
|
-
# 具体的には lock ファイルが存在すれば true を返す。
|
44
|
+
# 配下の KPOINTS を読み込んだ結果をハッシュにして返す。
|
89
45
|
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
|
93
|
-
|
94
|
-
def started?
|
95
|
-
return File.exist? lock_file
|
46
|
+
# 存在しなければ例外 Errno::ENOENT を返す筈だが、
|
47
|
+
# vasp dir の判定を incar でやっているので置こる筈がない。
|
48
|
+
def incar
|
49
|
+
Incar.load_file("#{@dir}/INCAR")
|
96
50
|
end
|
97
51
|
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
# MEMO
|
102
|
-
# PI12345 ファイルは実行中のみ存在し、終了後 vasp (mpi?) に自動的に削除される。
|
103
|
-
def normal_ended?
|
104
|
-
begin
|
105
|
-
return Outcar.load_file("#{@dir}/OUTCAR")[:normal_ended]
|
106
|
-
rescue Errno::ENOENT
|
107
|
-
return false
|
108
|
-
end
|
52
|
+
# 配下の KPOINTS を読み込んだ結果をハッシュにして返す。
|
53
|
+
def kpoints
|
54
|
+
Kpoints.load_file("#{@dir}/KPOINTS")
|
109
55
|
end
|
110
56
|
|
111
|
-
|
112
|
-
# normal_ended? が true のうち、
|
113
|
-
# 結果を使って次に計算すべきなら true を、そうでなければ false を返す。
|
114
|
-
#
|
115
|
-
# 計算すべき、の条件はモードによって異なる。
|
116
|
-
# NSW = 0 もしくは NSW = 1 のとき、必ず false。
|
117
|
-
# - :single_point モードならば、常に false。
|
118
|
-
# - :geom_opt_lattice モードならば、ionic step が 2 以上なら true。
|
119
|
-
# - :geom_opt_atoms モードならば、ionic step が NSW と同じなら true。
|
120
|
-
#
|
121
|
-
def to_be_continued?
|
122
|
-
begin
|
123
|
-
outcar = Outcar.load_file("#{@dir}/OUTCAR")
|
124
|
-
rescue Errno::ENOENT
|
125
|
-
return false
|
126
|
-
end
|
127
|
-
ionic_steps = outcar[:ionic_steps]
|
128
|
-
return false unless outcar[:normal_ended]
|
129
|
-
return false if @incar["NSW"].to_i <= 1
|
130
|
-
if @mode == :geom_opt_lattice
|
131
|
-
return ionic_steps != 1
|
132
|
-
elsif @mode == :geom_opt_atoms
|
133
|
-
return ionic_steps == @incar["NSW"].to_i
|
134
|
-
else
|
135
|
-
return false
|
136
|
-
end
|
137
|
-
end
|
57
|
+
private
|
138
58
|
|
139
59
|
# vasp を投げる。
|
140
60
|
# 計算実行時に lock を生成する。
|
@@ -148,135 +68,173 @@ class VaspDir
|
|
148
68
|
# machinefile を生成しないとどのホストで計算するか、安定しない。
|
149
69
|
# そのうち mpiexec from torque に対応するが、
|
150
70
|
# まずは mpirun で動くように作る。
|
151
|
-
def
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
command = "touch #{generated_files.join(" ")}"
|
196
|
-
end
|
197
|
-
|
198
|
-
status = system command
|
199
|
-
if status
|
200
|
-
lock_io.puts "STATUS: normal ended."
|
201
|
-
else
|
202
|
-
lock_io.puts "STATUS: irregular ended, status #{$?}."
|
203
|
-
end
|
71
|
+
def send_command
|
72
|
+
#File.open(lock_file, "w") do |lock_io|
|
73
|
+
# lock_io.puts "HOST: #{ENV["HOST"]}"
|
74
|
+
# lock_io.puts "START: #{Time.now.to_s}"
|
75
|
+
# lock_io.flush
|
76
|
+
|
77
|
+
# num_cores = 4 if /^Se\d\d/ =~ ENV["HOST"]
|
78
|
+
# num_cores = 4 if /^Ge\d\d/ =~ ENV["HOST"]
|
79
|
+
# num_cores = 4 if /^Ga\d\d/ =~ ENV["HOST"]
|
80
|
+
# num_cores = 4 if /^At$/ =~ ENV["HOST"]
|
81
|
+
# num_cores = 2 if /^yggdrasil$/ =~ ENV["HOST"]
|
82
|
+
|
83
|
+
# # machines を生成
|
84
|
+
# File.open("#{@dir}/machines", "w") do |io|
|
85
|
+
# io.puts "localhost:#{num_cores}"
|
86
|
+
# end
|
87
|
+
#end
|
88
|
+
num_cores = 4
|
89
|
+
command = "cd #{@dir};" +
|
90
|
+
"/usr/local/calc/mpich-1.2.7-ifc7/bin/mpirun " +
|
91
|
+
"-np #{num_cores} " +
|
92
|
+
"-machinefile machines " +
|
93
|
+
"/usr/local/calc/vasp/vasp4631mpi" +
|
94
|
+
"> stdout"
|
95
|
+
|
96
|
+
if $TEST
|
97
|
+
generated_files = [
|
98
|
+
"CHG",
|
99
|
+
"CHGCAR",
|
100
|
+
"CONTCAR",
|
101
|
+
"DOSCAR",
|
102
|
+
"EIGENVAL",
|
103
|
+
"IBZKPT",
|
104
|
+
"OSZICAR",
|
105
|
+
"OUTCAR",
|
106
|
+
"PCDAT",
|
107
|
+
"WAVECAR",
|
108
|
+
"XDATCAR",
|
109
|
+
"machines",
|
110
|
+
"vasprun.xml",
|
111
|
+
"lock",
|
112
|
+
]
|
113
|
+
generated_files.map!{|i| "#{@dir}/#{i}"}
|
114
|
+
command = "touch #{generated_files.join(" ")}"
|
204
115
|
end
|
205
|
-
end
|
206
|
-
|
207
|
-
# 次の計算ディレクトリを作成し、
|
208
|
-
# その VaspDir クラスで self を置き換える。
|
209
|
-
# 計算が正常終了していなければ、例外 VaspDirNotEndedError を生じる。
|
210
|
-
# 次の計算ディレクトリが既に存在していれば例外 Errno::EEXIST が投げられる。
|
211
|
-
def next
|
212
|
-
raise NotEndedError unless normal_ended?
|
213
|
-
raise ConvergedError unless to_be_continued?
|
214
|
-
#postfix = /try(\d+)$/
|
215
|
-
POSTFIX =~ @dir
|
216
|
-
try_num = $1.to_i
|
217
|
-
next_dir = @dir.sub(POSTFIX, sprintf("try%02d", try_num + 1))
|
218
|
-
Dir.mkdir next_dir
|
219
|
-
FileUtils.cp( "#{@dir}/INCAR" , "#{next_dir}/INCAR")
|
220
|
-
FileUtils.cp( "#{@dir}/KPOINTS", "#{next_dir}/KPOINTS")
|
221
|
-
FileUtils.cp( "#{@dir}/POTCAR" , "#{next_dir}/POTCAR")
|
222
|
-
FileUtils.cp( "#{@dir}/CONTCAR", "#{next_dir}/POSCAR")
|
223
|
-
initialize(next_dir)
|
224
|
-
end
|
225
|
-
|
226
|
-
# Postprocess.
|
227
|
-
def teardown
|
228
|
-
# Do nothing.
|
229
|
-
end
|
230
116
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
117
|
+
system command
|
118
|
+
#status = system command
|
119
|
+
#if status
|
120
|
+
# lock_io.puts "STATUS: normal ended."
|
121
|
+
#else
|
122
|
+
# lock_io.puts "STATUS: irregular ended, status #{$?}."
|
123
|
+
#end
|
235
124
|
end
|
236
125
|
|
237
|
-
#
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
end
|
248
|
-
|
249
|
-
# 配下の OUTCAR を Outcar インスタンスにして返す。
|
250
|
-
# 存在しなければ例外 Errno::ENOENT を返す。
|
251
|
-
def outcar
|
252
|
-
Outcar.load_file("#{@dir}/OUTCAR")
|
253
|
-
end
|
126
|
+
#INCAR 解析とかして、モードを調べる。
|
127
|
+
#- 格子定数の構造最適化モード(ISIF = 3)
|
128
|
+
#- 格子定数を固定した構造最適化モード(ISIF = 2)
|
129
|
+
##- k 点探索モードは無理だろう。
|
130
|
+
def set_parameters
|
131
|
+
#pp @dir; exit;
|
132
|
+
%w(INCAR KPOINTS POSCAR POTCAR).each do |file|
|
133
|
+
infile = "#{@dir}/#{file}"
|
134
|
+
raise InitializeError, infile unless FileTest.exist? infile
|
135
|
+
end
|
254
136
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
137
|
+
#@incar = Incar.load_file("#{@dir}/INCAR")
|
138
|
+
#case @incar["IBRION"]
|
139
|
+
#when "-1"
|
140
|
+
# @mode = :single_point
|
141
|
+
##when "1"
|
142
|
+
## @mode = :molecular_dynamics
|
143
|
+
#when "2"
|
144
|
+
# if (@incar["ISIF"] == "2")
|
145
|
+
# @mode = :geom_opt_atoms
|
146
|
+
# elsif (@incar["ISIF"] == "3")
|
147
|
+
# @mode = :geom_opt_lattice
|
148
|
+
# else
|
149
|
+
# @mode = :geom_opt
|
150
|
+
# end
|
151
|
+
#else
|
152
|
+
# @mode = nil
|
153
|
+
#end
|
154
|
+
|
155
|
+
@lockdir = "lock"
|
156
|
+
@alive_time = 3600
|
157
|
+
@outfiles = ["OUTCAR"] # Files only to output should be indicated.
|
259
158
|
end
|
260
159
|
|
261
|
-
#
|
160
|
+
# 正常に終了していれば true を返す。
|
161
|
+
# 実行する前や実行中、OUTCAR が完遂していなければ false。
|
262
162
|
#
|
263
|
-
#
|
264
|
-
#
|
265
|
-
def
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
Kpoints.load_file("#{@dir}/KPOINTS")
|
272
|
-
end
|
273
|
-
|
274
|
-
private
|
275
|
-
|
276
|
-
# Return lock file name.
|
277
|
-
def lock_file
|
278
|
-
return "#{@dir}/#{LOCK_FILE}"
|
163
|
+
# MEMO
|
164
|
+
# PI12345 ファイルは実行中のみ存在し、終了後 vasp (mpi?) に自動的に削除される。
|
165
|
+
def finished?
|
166
|
+
begin
|
167
|
+
return Outcar.load_file("#{@dir}/OUTCAR")[:normal_ended]
|
168
|
+
rescue Errno::ENOENT
|
169
|
+
return false
|
170
|
+
end
|
279
171
|
end
|
280
172
|
|
281
173
|
end
|
282
174
|
|
175
|
+
#class VaspGeometryOptimization < Comana
|
176
|
+
# # 次の計算ディレクトリを作成し、
|
177
|
+
# # その VaspDir クラスで self を置き換える。
|
178
|
+
# # 計算が正常終了していなければ、例外 VaspDirNotEndedError を生じる。
|
179
|
+
# # 次の計算ディレクトリが既に存在していれば例外 Errno::EEXIST が投げられる。
|
180
|
+
# def next
|
181
|
+
# raise NotEndedError unless normal_ended?
|
182
|
+
# raise ConvergedError unless to_be_continued?
|
183
|
+
# #postfix = /try(\d+)$/
|
184
|
+
# POSTFIX =~ @dir
|
185
|
+
# try_num = $1.to_i
|
186
|
+
# next_dir = @dir.sub(POSTFIX, sprintf("try%02d", try_num + 1))
|
187
|
+
# Dir.mkdir next_dir
|
188
|
+
# FileUtils.cp( "#{@dir}/INCAR" , "#{next_dir}/INCAR")
|
189
|
+
# FileUtils.cp( "#{@dir}/KPOINTS", "#{next_dir}/KPOINTS")
|
190
|
+
# FileUtils.cp( "#{@dir}/POTCAR" , "#{next_dir}/POTCAR")
|
191
|
+
# FileUtils.cp( "#{@dir}/CONTCAR", "#{next_dir}/POSCAR")
|
192
|
+
# initialize(next_dir)
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# # Return number of electronic steps.
|
196
|
+
# def internal_steps
|
197
|
+
# return outcar[:electronic_steps] if outcar
|
198
|
+
# return 0
|
199
|
+
# end
|
200
|
+
#
|
201
|
+
# # Return number of ionic steps.
|
202
|
+
# def external_steps
|
203
|
+
# return outcar[:ionic_steps] if outcar
|
204
|
+
# return 0
|
205
|
+
# end
|
206
|
+
#
|
207
|
+
# # Return elapsed time.
|
208
|
+
# def elapsed_time
|
209
|
+
# return outcar[:elapsed_time] if outcar
|
210
|
+
# return 0.0
|
211
|
+
# end
|
212
|
+
#
|
213
|
+
# # normal_ended? が false なら false。
|
214
|
+
# # normal_ended? が true のうち、
|
215
|
+
# # 結果を使って次に計算すべきなら true を、そうでなければ false を返す。
|
216
|
+
# #
|
217
|
+
# # 計算すべき、の条件はモードによって異なる。
|
218
|
+
# # NSW = 0 もしくは NSW = 1 のとき、必ず false。
|
219
|
+
# # - :single_point モードならば、常に false。
|
220
|
+
# # - :geom_opt_lattice モードならば、ionic step が 2 以上なら true。
|
221
|
+
# # - :geom_opt_atoms モードならば、ionic step が NSW と同じなら true。
|
222
|
+
# #
|
223
|
+
# def to_be_continued?
|
224
|
+
# begin
|
225
|
+
# outcar = Outcar.load_file("#{@dir}/OUTCAR")
|
226
|
+
# rescue Errno::ENOENT
|
227
|
+
# return false
|
228
|
+
# end
|
229
|
+
# ionic_steps = outcar[:ionic_steps]
|
230
|
+
# return false unless outcar[:normal_ended]
|
231
|
+
# return false if @incar["NSW"].to_i <= 1
|
232
|
+
# if @mode == :geom_opt_lattice
|
233
|
+
# return ionic_steps != 1
|
234
|
+
# elsif @mode == :geom_opt_atoms
|
235
|
+
# return ionic_steps == @incar["NSW"].to_i
|
236
|
+
# else
|
237
|
+
# return false
|
238
|
+
# end
|
239
|
+
# end
|
240
|
+
#
|