lib/vasputils/poscar.rb in vasputils-0.0.10 vs lib/vasputils/poscar.rb in vasputils-0.0.11
- old
+ new
@@ -41,53 +41,61 @@
3.times do |i| #each axis of a, b, c.
vec = io.readline.strip.split(/\s+/) #in x,y,z directions
axes << vec.collect! { |i| i.to_f * scale } #multiply scaling factor
end
- #line 6: numbers of elements. e.g.,[1, 1, 2]
- nums_elements = io.readline.strip.split( /\s+/ ).map{|i| i.to_i}
+ # Element symbol (vasp 5). Nothing in vasp 4.
+ #elements = io.readline.strip.split(/\s+/).map{|i| i.to_i}
+ vals = io.readline.strip.split(/\s+/)
+ if vals[0].to_i == 0
+ elements = vals
+ nums_elements = io.readline.strip.split(/\s+/).map{|i| i.to_i}
+ else
+ elements = []
+ vals.size.times { |i| elements << i }
+ nums_elements = vals.map{|i| i.to_i}
+ end
- #line 7-(8): 'Selective dynamics' or not (bool)
+ # 'Selective dynamics' or not (bool)
line = io.readline
if line =~ /^\s*s/i
selective_dynamics = true
line = io.readline # when this situation, reading one more line is nessesarry
end
- if (line =~ /^\s*d/i ) # allow only 'Direct' now
+ if (line =~ /^\s*d/i) # allow only 'Direct' now
direct = true
else
raise "Not 'direct' indication."
end
- #line 9(8): position
- #e.g., positions_of_elements
- #e.g., movable_flags_of_elements
+ # atom positions
+ # e.g., positions_of_elements
+ # e.g., movable_flags_of_elements
atoms = []
nums_elements.size.times do |elem_index|
nums_elements[elem_index].times do |index|
- items = io.readline.strip.split( /\s+/ )
+ items = io.readline.strip.split(/\s+/)
pos = items[0..2].map {|coord| coord.to_f}
- #pp pos
mov_flags = []
if items.size >= 6 then
items[3..5].each do |i|
- ( i =~ /^t/i ) ? mov_flags << true : mov_flags << false
+ (i =~ /^t/i) ? mov_flags << true : mov_flags << false
end
- atoms << Atom.new(elem_index, pos, mov_flags)
+ atoms << Atom.new(elements[elem_index], pos, mov_flags)
else
- atoms << Atom.new(elem_index, pos)
+ atoms << Atom.new(elements[elem_index], pos)
end
end
end
rescue EOFError
raise ParseError, "end of file reached"
end
- cell = Cell.new(axes, atoms )
+ cell = Cell.new(axes, atoms)
cell.comment = comment
cell
end
# file で与えられた名前のファイルを読み込んで Cell クラスインスタンスを返す。
@@ -101,24 +109,30 @@
# cell は Cell クラスインスタンスと同等のメソッドを持つもの。
# elems は書き出す元素の順番。
# elems が cell の持つ元素リストとマッチしなければ
# 例外 Poscar::ElementMismatchError を投げる。
# io は書き出すファイルハンドル。
- def self.dump(cell, elems, io)
+ # 'version' indicates a poscar style for vasp 4 or 5.
+ def self.dump(cell, elems, io, version = 5)
unless (Mapping::map?(cell.elements.uniq, elems){ |i, j| i == j })
raise ElementMismatchError,
"elems [#{elems.join(",")}] mismatches to cell.elements [#{cell.elements.join(",")}."
end
io.puts cell.comment
io.puts "1.0" #scale
3.times do |i|
- io.printf( " % 18.15f % 18.15f % 18.15f\n", cell.axes[i][0], cell.axes[i][1], cell.axes[i][2]
+ io.printf(" % 18.15f % 18.15f % 18.15f\n", cell.axes[i][0], cell.axes[i][1], cell.axes[i][2]
)
end
- # collect information
+ # Element symbols for vasp 5.
+ if version >= 5
+ io.puts cell.atoms.map {|atom| atom.element}.uniq.join(" ")
+ end
+
+ # Atom numbers.
elem_list = Hash.new
elems.each do |elem|
elem_list[ elem ] = cell.atoms.select{ |atom| atom.element == elem }
end
io.puts(elems.map { |elem| elem_list[elem].size }.join(" "))
@@ -149,16 +163,16 @@
# positions of atoms
elems.each do |elem|
elem_list[ elem ].each do |atom|
tmp = sprintf(
" % 18.15f % 18.15f % 18.15f",
- * atom.position )
+ * atom.position)
if selective_dynamics
if atom.movable_flags == nil
tmp += " T T T"
else
atom.movable_flags.each do |mov|
- ( mov == true ) ? tmp += " T" : tmp += " F"
+ (mov == true) ? tmp += " T" : tmp += " F"
end
end
end
io.puts tmp
end