vasputils 0.0.3 → 0.0.4

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.
Files changed (78) hide show
  1. data/Gemfile +1 -1
  2. data/VERSION +1 -1
  3. data/bin/lsvasp +90 -0
  4. data/bin/qsubvasp +42 -6
  5. data/bin/runvasp +35 -0
  6. data/lib/vasputils/calcinspector.rb +15 -15
  7. data/lib/vasputils/incar.rb +30 -30
  8. data/lib/vasputils/kpoints.rb +34 -34
  9. data/lib/vasputils/outcar.rb +45 -45
  10. data/lib/vasputils/poscar.rb +145 -145
  11. data/lib/vasputils/potcar.rb +12 -12
  12. data/lib/vasputils/vaspdir.rb +52 -77
  13. data/lib/vasputils/vaspgeomopt.rb +114 -0
  14. data/memo.txt +7 -0
  15. data/test/test_vaspdir.rb +24 -6
  16. data/test/test_vaspgeomopt.rb +95 -0
  17. data/test/{vaspdir/finished/lock → vaspgeomopt/ended-Iter1/try00/CONTCAR} +0 -0
  18. data/test/{vaspdir/locked/lock → vaspgeomopt/ended-Iter1/try00/INCAR} +0 -0
  19. data/test/{vaspdir/started/lock → vaspgeomopt/ended-Iter1/try00/KPOINTS} +0 -0
  20. data/test/vaspgeomopt/ended-Iter1/try00/OUTCAR +0 -0
  21. data/test/vaspgeomopt/ended-Iter1/try00/POSCAR +0 -0
  22. data/test/vaspgeomopt/ended-Iter1/try00/POTCAR +0 -0
  23. data/test/vaspgeomopt/ended-Iter1/try01/INCAR +0 -0
  24. data/test/vaspgeomopt/ended-Iter1/try01/KPOINTS +0 -0
  25. data/test/vaspgeomopt/ended-Iter1/try01/OUTCAR +16 -0
  26. data/test/vaspgeomopt/ended-Iter1/try01/POSCAR +0 -0
  27. data/test/vaspgeomopt/ended-Iter1/try01/POTCAR +0 -0
  28. data/test/vaspgeomopt/ended-Iter2/try00/CONTCAR +0 -0
  29. data/test/vaspgeomopt/ended-Iter2/try00/INCAR +0 -0
  30. data/test/vaspgeomopt/ended-Iter2/try00/KPOINTS +0 -0
  31. data/test/vaspgeomopt/ended-Iter2/try00/OUTCAR +0 -0
  32. data/test/vaspgeomopt/ended-Iter2/try00/POSCAR +0 -0
  33. data/test/vaspgeomopt/ended-Iter2/try00/POTCAR +0 -0
  34. data/test/vaspgeomopt/ended-Iter2/try01/INCAR +0 -0
  35. data/test/vaspgeomopt/ended-Iter2/try01/KPOINTS +0 -0
  36. data/test/vaspgeomopt/ended-Iter2/try01/OUTCAR +18 -0
  37. data/test/vaspgeomopt/ended-Iter2/try01/POSCAR +0 -0
  38. data/test/vaspgeomopt/ended-Iter2/try01/POTCAR +0 -0
  39. data/test/vaspgeomopt/not-yet/try00/INCAR +0 -0
  40. data/test/vaspgeomopt/not-yet/try00/KPOINTS +0 -0
  41. data/test/vaspgeomopt/not-yet/try00/POSCAR +0 -0
  42. data/test/vaspgeomopt/not-yet/try00/POTCAR +0 -0
  43. data/test/vaspgeomopt/prepare_next/try00/CHG +0 -0
  44. data/test/vaspgeomopt/prepare_next/try00/CHGCAR +0 -0
  45. data/test/vaspgeomopt/prepare_next/try00/CONTCAR +0 -0
  46. data/test/vaspgeomopt/prepare_next/try00/DOSCAR +0 -0
  47. data/test/vaspgeomopt/prepare_next/try00/EIGENVAL +0 -0
  48. data/test/vaspgeomopt/prepare_next/try00/INCAR +0 -0
  49. data/test/vaspgeomopt/prepare_next/try00/KPOINTS +0 -0
  50. data/test/vaspgeomopt/prepare_next/try00/OSZICAR +0 -0
  51. data/test/vaspgeomopt/prepare_next/try00/OUTCAR +0 -0
  52. data/test/vaspgeomopt/prepare_next/try00/PCDAT +0 -0
  53. data/test/vaspgeomopt/prepare_next/try00/POSCAR +0 -0
  54. data/test/vaspgeomopt/prepare_next/try00/POTCAR +0 -0
  55. data/test/vaspgeomopt/prepare_next/try00/WAVECAR +0 -0
  56. data/test/vaspgeomopt/prepare_next/try00/XDATCAR +0 -0
  57. data/test/vaspgeomopt/prepare_next/try00/vasprun.xml +0 -0
  58. data/test/vaspgeomopt/started/try00/INCAR +0 -0
  59. data/test/vaspgeomopt/started/try00/KPOINTS +0 -0
  60. data/test/vaspgeomopt/started/try00/POSCAR +0 -0
  61. data/test/vaspgeomopt/started/try00/POTCAR +0 -0
  62. data/test/vaspgeomopt/till01/try00/CONTCAR +0 -0
  63. data/test/vaspgeomopt/till01/try00/INCAR +0 -0
  64. data/test/vaspgeomopt/till01/try00/KPOINTS +0 -0
  65. data/test/vaspgeomopt/till01/try00/OUTCAR +0 -0
  66. data/test/vaspgeomopt/till01/try00/POSCAR +0 -0
  67. data/test/vaspgeomopt/till01/try00/POTCAR +0 -0
  68. data/test/vaspgeomopt/till01/try01/INCAR +0 -0
  69. data/test/vaspgeomopt/till01/try01/KPOINTS +0 -0
  70. data/test/vaspgeomopt/till01/try01/POSCAR +0 -0
  71. data/test/vaspgeomopt/till01/try01/POTCAR +0 -0
  72. data/vasputils.gemspec +66 -14
  73. metadata +86 -33
  74. data/bin/repeatvasp +0 -47
  75. data/lib/vasputils/calcrepeater.rb +0 -27
  76. data/lib/vasputils/calcseries.rb +0 -98
  77. data/test/test_calcrepeater.rb +0 -69
  78. data/test/test_calcseries.rb +0 -77
@@ -18,151 +18,151 @@ require "crystalcell/cell.rb"
18
18
  # VASP 5 系を使うようになれば事情が変わるだろう。
19
19
  class Poscar
20
20
 
21
- class ElementMismatchError < Exception; end
22
- class ParseError < Exception; end
23
-
24
- # io を読み込んで Cell クラスインスタンスを返す。
25
- # 構文解析できなければ例外 Poscar::ParseError を投げる。
26
- def self.parse(io)
27
- # analyze POSCAR.
28
-
29
- begin
30
- #line 1: comment (string)
31
- comment = io.readline.chomp
32
-
33
- #line 2: universal scaling factor (float)
34
- scale = io.readline.to_f
35
- raise "Poscar.load_file cannot use negative scaling factor.\n" if scale < 0
36
-
37
- #line 3-5: axes (3x3 Array of float)
38
- axes = []
39
- 3.times do |i| #each axis of a, b, c.
40
- vec = io.readline.strip.split(/\s+/) #in x,y,z directions
41
- axes << vec.collect! { |i| i.to_f * scale } #multiply scaling factor
42
- end
43
-
44
- #line 6: numbers of elements. e.g.,[1, 1, 2]
45
- nums_elements = io.readline.strip.split( /\s+/ ).map{|i| i.to_i}
46
-
47
- #line 7-(8): 'Selective dynamics' or not (bool)
48
- line = io.readline
49
- if line =~ /^\s*s/i
50
- selective_dynamics = true
51
- line = io.readline # when this situation, reading one more line is nessesarry
52
- end
53
-
54
- if (line =~ /^\s*d/i ) # allow only 'Direct' now
55
- direct = true
56
- else
57
- raise "Not 'direct' indication."
58
- end
59
-
60
- #line 9(8): position
61
- #e.g., positions_of_elements
62
- #e.g., movable_flags_of_elements
63
-
64
- atoms = []
65
- nums_elements.size.times do |elem_index|
66
- nums_elements[elem_index].times do |index|
67
- items = io.readline.strip.split( /\s+/ )
68
- pos = items[0..2].map {|coord| coord.to_f}
69
- #pp pos
70
-
71
- mov_flags = []
72
- if items.size >= 6 then
73
- items[3..5].each do |i|
74
- ( i =~ /^t/i ) ? mov_flags << true : mov_flags << false
75
- end
76
- atoms << Atom.new(elem_index, pos, mov_flags)
77
- else
78
- atoms << Atom.new(elem_index, pos)
79
- end
80
- end
81
- end
82
- rescue EOFError
83
- raise ParseError, "end of file reached"
84
- end
85
-
86
- cell = Cell.new(axes, atoms )
87
- cell.comment = comment
88
- cell
89
- end
90
-
91
- # file で与えられた名前のファイルを読み込んで Cell クラスインスタンスを返す。
92
- # 構文解析できなければ例外 Poscar::ParseError を投げる。
93
- def self.load_file(file)
94
- io = File.open(file, "r")
95
- self.parse(io)
96
- end
97
-
98
- # POSCAR 形式で書き出す。
99
- # cell は Cell クラスインスタンスと同等のメソッドを持つもの。
100
- # elems は書き出す元素の順番。
101
- # elems が cell の持つ元素リストとマッチしなければ
102
- # 例外 Poscar::ElementMismatchError を投げる。
103
- # io は書き出すファイルハンドル。
104
- def self.dump(cell, elems, io)
105
- unless (Mapping::map?(cell.elements.uniq, elems){ |i, j| i == j })
106
- raise ElementMismatchError,
107
- "elems [#{elems.join(",")}] mismatches to cell.elements [#{cell.elements.join(",")}."
108
- end
109
-
110
- io.puts cell.comment
111
- io.puts "1.0" #scale
112
- 3.times do |i|
113
- io.printf( " % 18.15f % 18.15f % 18.15f\n", cell.axes[i][0], cell.axes[i][1], cell.axes[i][2]
114
- )
115
- end
116
-
117
- # collect information
118
- elem_list = Hash.new
119
- elems.each do |elem|
120
- elem_list[ elem ] = cell.atoms.select{ |atom| atom.element == elem }
121
- end
122
- io.puts(elems.map { |elem| elem_list[elem].size }.join(" "))
123
-
124
- # Selective dynamics
125
- # どれか1つでも getMovableFlag が真であれば Selective dynamics をオンにする
126
- selective_dynamics = false
127
- cell.atoms.each do |atom|
128
- if atom.movable_flags
129
- selective_dynamics = true
130
- io.puts "Selective dynamics"
131
- break
132
- end
133
- end
134
-
135
- elems.each do |elem|
136
- elem_list[ elem ].each do |atom|
137
- if atom.movable_flags
138
- selective_dynamics = true
139
- break
140
- end
141
- end
142
- break if selective_dynamics
143
- end
144
-
145
- io.puts "Direct"
146
-
147
- # positions of atoms
148
- elems.each do |elem|
149
- elem_list[ elem ].each do |atom|
150
- tmp = sprintf(
151
- " % 18.15f % 18.15f % 18.15f",
152
- * atom.position )
153
- if selective_dynamics
154
- if atom.movable_flags == nil
155
- tmp += " T T T"
156
- else
157
- atom.movable_flags.each do |mov|
158
- ( mov == true ) ? tmp += " T" : tmp += " F"
159
- end
160
- end
161
- end
162
- io.puts tmp
163
- end
164
- end
165
- end
21
+ class ElementMismatchError < Exception; end
22
+ class ParseError < Exception; end
23
+
24
+ # io を読み込んで Cell クラスインスタンスを返す。
25
+ # 構文解析できなければ例外 Poscar::ParseError を投げる。
26
+ def self.parse(io)
27
+ # analyze POSCAR.
28
+
29
+ begin
30
+ #line 1: comment (string)
31
+ comment = io.readline.chomp
32
+
33
+ #line 2: universal scaling factor (float)
34
+ scale = io.readline.to_f
35
+ raise "Poscar.load_file cannot use negative scaling factor.\n" if scale < 0
36
+
37
+ #line 3-5: axes (3x3 Array of float)
38
+ axes = []
39
+ 3.times do |i| #each axis of a, b, c.
40
+ vec = io.readline.strip.split(/\s+/) #in x,y,z directions
41
+ axes << vec.collect! { |i| i.to_f * scale } #multiply scaling factor
42
+ end
43
+
44
+ #line 6: numbers of elements. e.g.,[1, 1, 2]
45
+ nums_elements = io.readline.strip.split( /\s+/ ).map{|i| i.to_i}
46
+
47
+ #line 7-(8): 'Selective dynamics' or not (bool)
48
+ line = io.readline
49
+ if line =~ /^\s*s/i
50
+ selective_dynamics = true
51
+ line = io.readline # when this situation, reading one more line is nessesarry
52
+ end
53
+
54
+ if (line =~ /^\s*d/i ) # allow only 'Direct' now
55
+ direct = true
56
+ else
57
+ raise "Not 'direct' indication."
58
+ end
59
+
60
+ #line 9(8): position
61
+ #e.g., positions_of_elements
62
+ #e.g., movable_flags_of_elements
63
+
64
+ atoms = []
65
+ nums_elements.size.times do |elem_index|
66
+ nums_elements[elem_index].times do |index|
67
+ items = io.readline.strip.split( /\s+/ )
68
+ pos = items[0..2].map {|coord| coord.to_f}
69
+ #pp pos
70
+
71
+ mov_flags = []
72
+ if items.size >= 6 then
73
+ items[3..5].each do |i|
74
+ ( i =~ /^t/i ) ? mov_flags << true : mov_flags << false
75
+ end
76
+ atoms << Atom.new(elem_index, pos, mov_flags)
77
+ else
78
+ atoms << Atom.new(elem_index, pos)
79
+ end
80
+ end
81
+ end
82
+ rescue EOFError
83
+ raise ParseError, "end of file reached"
84
+ end
85
+
86
+ cell = Cell.new(axes, atoms )
87
+ cell.comment = comment
88
+ cell
89
+ end
90
+
91
+ # file で与えられた名前のファイルを読み込んで Cell クラスインスタンスを返す。
92
+ # 構文解析できなければ例外 Poscar::ParseError を投げる。
93
+ def self.load_file(file)
94
+ io = File.open(file, "r")
95
+ self.parse(io)
96
+ end
97
+
98
+ # POSCAR 形式で書き出す。
99
+ # cell は Cell クラスインスタンスと同等のメソッドを持つもの。
100
+ # elems は書き出す元素の順番。
101
+ # elems が cell の持つ元素リストとマッチしなければ
102
+ # 例外 Poscar::ElementMismatchError を投げる。
103
+ # io は書き出すファイルハンドル。
104
+ def self.dump(cell, elems, io)
105
+ unless (Mapping::map?(cell.elements.uniq, elems){ |i, j| i == j })
106
+ raise ElementMismatchError,
107
+ "elems [#{elems.join(",")}] mismatches to cell.elements [#{cell.elements.join(",")}."
108
+ end
109
+
110
+ io.puts cell.comment
111
+ io.puts "1.0" #scale
112
+ 3.times do |i|
113
+ io.printf( " % 18.15f % 18.15f % 18.15f\n", cell.axes[i][0], cell.axes[i][1], cell.axes[i][2]
114
+ )
115
+ end
116
+
117
+ # collect information
118
+ elem_list = Hash.new
119
+ elems.each do |elem|
120
+ elem_list[ elem ] = cell.atoms.select{ |atom| atom.element == elem }
121
+ end
122
+ io.puts(elems.map { |elem| elem_list[elem].size }.join(" "))
123
+
124
+ # Selective dynamics
125
+ # どれか1つでも getMovableFlag が真であれば Selective dynamics をオンにする
126
+ selective_dynamics = false
127
+ cell.atoms.each do |atom|
128
+ if atom.movable_flags
129
+ selective_dynamics = true
130
+ io.puts "Selective dynamics"
131
+ break
132
+ end
133
+ end
134
+
135
+ elems.each do |elem|
136
+ elem_list[ elem ].each do |atom|
137
+ if atom.movable_flags
138
+ selective_dynamics = true
139
+ break
140
+ end
141
+ end
142
+ break if selective_dynamics
143
+ end
144
+
145
+ io.puts "Direct"
146
+
147
+ # positions of atoms
148
+ elems.each do |elem|
149
+ elem_list[ elem ].each do |atom|
150
+ tmp = sprintf(
151
+ " % 18.15f % 18.15f % 18.15f",
152
+ * atom.position )
153
+ if selective_dynamics
154
+ if atom.movable_flags == nil
155
+ tmp += " T T T"
156
+ else
157
+ atom.movable_flags.each do |mov|
158
+ ( mov == true ) ? tmp += " T" : tmp += " F"
159
+ end
160
+ end
161
+ end
162
+ io.puts tmp
163
+ end
164
+ end
165
+ end
166
166
 
167
167
  end
168
168
 
@@ -2,17 +2,17 @@
2
2
  # Class for dealing with POTCAR.
3
3
  #
4
4
  module Potcar
5
- def self.load_file(file)
6
- results = {}
7
- results[:name] = file
5
+ def self.load_file(file)
6
+ results = {}
7
+ results[:name] = file
8
8
 
9
- elements = Array.new
10
- File.open( file, "r" ).each do |line|
11
- if line =~ /VRHFIN\s*=\s*([A-Za-z]*)/
12
- elements << $1
13
- end
14
- end
15
- results[:elements] = elements
16
- results
17
- end
9
+ elements = Array.new
10
+ File.open( file, "r" ).each do |line|
11
+ if line =~ /VRHFIN\s*=\s*([A-Za-z]*)/
12
+ elements << $1
13
+ end
14
+ end
15
+ results[:elements] = elements
16
+ results
17
+ end
18
18
  end
@@ -4,10 +4,12 @@
4
4
  require "fileutils"
5
5
  require "pp"
6
6
  require "date"
7
+ require "yaml"
7
8
 
8
9
  require "rubygems"
9
10
  gem "comana"
10
- require "comana.rb"
11
+ require "comana/computationmanager.rb"
12
+ require "comana/machineinfo.rb"
11
13
 
12
14
  require "vasputils/incar.rb"
13
15
  require "vasputils/outcar.rb"
@@ -29,6 +31,18 @@ require "vasputils/kpoints.rb"
29
31
  class VaspDir < Comana
30
32
  class InitializeError < Exception; end
31
33
 
34
+ #INCAR 解析とかして、モードを調べる。
35
+ #- 格子定数の構造最適化モード(ISIF = 3)
36
+ #- 格子定数を固定した構造最適化モード(ISIF = 2)
37
+ ##- k 点探索モードは無理だろう。
38
+ def initialize(dir)
39
+ super(dir)
40
+ %w(INCAR KPOINTS POSCAR POTCAR).each do |file|
41
+ infile = "#{@dir}/#{file}"
42
+ raise InitializeError, infile unless FileTest.exist? infile
43
+ end
44
+ end
45
+
32
46
  # 配下の OUTCAR を Outcar インスタンスにして返す。
33
47
  # 存在しなければ例外 Errno::ENOENT を返す。
34
48
  def outcar
@@ -54,6 +68,19 @@ class VaspDir < Comana
54
68
  Kpoints.load_file("#{@dir}/KPOINTS")
55
69
  end
56
70
 
71
+ # 正常に終了していれば true を返す。
72
+ # 実行する前や実行中、OUTCAR が完遂していなければ false。
73
+ #
74
+ # MEMO
75
+ # PI12345 ファイルは実行中のみ存在し、終了後 vasp (mpi?) に自動的に削除される。
76
+ def finished?
77
+ begin
78
+ return Outcar.load_file("#{@dir}/OUTCAR")[:normal_ended]
79
+ rescue Errno::ENOENT
80
+ return false
81
+ end
82
+ end
83
+
57
84
  private
58
85
 
59
86
  # vasp を投げる。
@@ -68,7 +95,7 @@ class VaspDir < Comana
68
95
  # machinefile を生成しないとどのホストで計算するか、安定しない。
69
96
  # そのうち mpiexec from torque に対応するが、
70
97
  # まずは mpirun で動くように作る。
71
- def send_command
98
+ def calculate
72
99
  #File.open(lock_file, "w") do |lock_io|
73
100
  # lock_io.puts "HOST: #{ENV["HOST"]}"
74
101
  # lock_io.puts "START: #{Time.now.to_s}"
@@ -85,89 +112,37 @@ class VaspDir < Comana
85
112
  # io.puts "localhost:#{num_cores}"
86
113
  # end
87
114
  #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(" ")}"
115
- end
116
-
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
124
- end
115
+ #num_cores = 4
125
116
 
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
117
+ #settings = YAML.load_file("#{ENV["HOME"]}/.machineinfo")
118
+ #setting = settings[ENV["HOST"]]
119
+ begin
120
+ hi = MachineInfo.load_file("#{ENV["HOME"]}/.machineinfo").get_host(ENV["HOST"])
121
+ vasp = hi["vasp"]
122
+ rescue
123
+ vasp = "vasp"
135
124
  end
125
+ command = "cd #{@dir};"
126
+ command += vasp
127
+ command += "> stdout"
136
128
 
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
129
+ #if ENV["PBS_JOBID"]
130
+ # command += "/usr/local/calc/mpiexec/bin/mpiexec /usr/local/calc/bin/vasp5212-mpich2"
151
131
  #else
152
- # @mode = nil
132
+ # /usr/local/calc/bin/vasp5212-mpich2"
133
+ ## command = "cd #{@dir};" +
134
+ ## "/usr/local/calc/mpich-1.2.7-ifc7/bin/mpirun " +
135
+ ## "-np #{num_cores} " +
136
+ ## "-machinefile machines " +
137
+ ## "/usr/local/calc/vasp/vasp4631mpi" +
138
+ ## "> stdout"
153
139
  #end
154
140
 
155
- @lockdir = "lock"
156
- @alive_time = 3600
157
- @outfiles = ["OUTCAR"] # Files only to output should be indicated.
141
+ system command
158
142
  end
159
143
 
160
- # 正常に終了していれば true を返す。
161
- # 実行する前や実行中、OUTCAR が完遂していなければ false。
162
- #
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
144
+ def prepare_next
145
+ #do_nothing
171
146
  end
172
147
 
173
148
  end