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