pw 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ require_relative "./lib/atom.rb"
2
+ require_relative "../helper/numeric"
3
+ require_relative "./lib/write"
4
+ require_relative "./lib/boundary"
5
+ require_relative "./lib/private"
6
+ require_relative "./lib/redef"
7
+ class Cell < Array
8
+ attr_reader :min, :max, :celldm, :units
9
+ def initialize params = {}
10
+ add_to_atoms params[:atoms] unless params[:atoms].nil?
11
+ params[:units].lowercase! if params[:units].is_a? String
12
+ @units = params[:units] || :crystal
13
+ @celldm = (@units == :crystal ? [1,1,1] : params[:celldm].dup) rescue @celldm = []
14
+ @realcelldm = (@units == :bohr ? params[:celldm].map{|v| v*0.52918} : params[:celldm]) rescue @realcelldm = []
15
+ @min = []
16
+ @max = []
17
+ end
18
+ def celldm= *args
19
+ arr = args.flatten
20
+ @celldm = (@units == :crystal ? [1,1,1] : arr)
21
+ @realcelldm = (@units == :bohr ? arr.map{|v| v*0.52918} : arr)
22
+ update_atoms_celldm
23
+ end
24
+ def units= unit
25
+ unit.lowercase! if unit.is_a? String
26
+ unit = unit.to_sym
27
+ return self if unit == @units
28
+ change_units unit
29
+ @units = unit
30
+ end
31
+ end
@@ -0,0 +1,54 @@
1
+ class Atom
2
+ attr_accessor :uid, :fixed, :celldm
3
+ attr_reader :coor
4
+ def initialize params = {}
5
+ @name = params[:name].to_sym rescue @name = :X
6
+ @coor = params[:coor].dup rescue @coor = []
7
+ @uid = params[:uid] || nil
8
+ @fixed = params[:fixed]||false
9
+ @celldm = params[:celldm] || nil
10
+ # element = params[:element] || #TODO element constants. dont forget fixing dup
11
+ end
12
+ def coor= *c; @coor = c.flatten;end
13
+ def name= nm; @name = nm.to_sym; end
14
+ def name; @name.to_s; end
15
+ def x; @coor[0]; end
16
+ def y; @coor[1]; end
17
+ def z; @coor[2]; end
18
+ def x= num; @coor[0] = num; end
19
+ def y= num; @coor[1] = num; end
20
+ def z= num; @coor[2] = num; end
21
+ def move! *args
22
+ args.flatten!
23
+ args = args * 3 if args.length == 1
24
+ for i in 0..2;coor[i]+=args[i];end
25
+ return self
26
+ end
27
+ def move *args
28
+ a = self.dup
29
+ return a.move!(*args)
30
+ end
31
+ def to_s
32
+ l = (@fixed ? " 0 0 0" : "")
33
+ output = "%-4s%14.9f%14.9f%14.9f%s" % [@name, coor[0], coor[1], coor[2], l]
34
+ return output
35
+ end
36
+ def dup
37
+ Atom.new(:name => @name, :coor => @coor, :uid => @uid, :fixed => @fixed, :celldm => @celldm)
38
+ end
39
+ def dist other
40
+ if other.is_a? Atom
41
+ arr = other.coor
42
+ elsif other.is_a? Array and other.length = 3
43
+ arr = other
44
+ else
45
+ return nil
46
+ end
47
+ d = []
48
+ for i in 0..2
49
+ d.push (@coor[i] - arr[i]).abs
50
+ d[i] = @celldm[i] - d[i] if (!@celldm.nil? and d[i] > @celldm[i]/2)
51
+ end
52
+ return (d[0]**2+d[1]**2+d[2]**2).sqrt
53
+ end
54
+ end
@@ -0,0 +1,40 @@
1
+ class Cell < Array
2
+ def dist x, y
3
+ $stderr.puts "Distance in crystal units is usually not meaningful!" if @units == :crystal
4
+ arr = wrap(0)
5
+ return arr[x].dist arr[y]
6
+ end
7
+ def wrap! tol = 0.5
8
+ self.each do |atom|
9
+ (0..2).each {|i| atom.coor[i] -= @celldm[i] while atom.coor[i] - @celldm[i] > tol}
10
+ (0..2).each {|i| atom.coor[i] += @celldm[i] while atom.coor[i] < -tol}
11
+ end
12
+ scan_mins_maxes
13
+ return self
14
+ end
15
+ def wrap tol = 0.5
16
+ arr = self.dup
17
+ return arr.wrap!(tol)
18
+ end
19
+ def move! *args
20
+ args.flatten!
21
+ args*=3 if args.length == 1
22
+ self.each do |atom|
23
+ atom.move! args
24
+ end
25
+ for i in 0..2;@max[i]+=args[i];@min[i]+=args[i];end
26
+ return self
27
+ end
28
+ def move *args
29
+ arr = self.dup
30
+ return arr.move! *args
31
+ end
32
+ def reset_order!
33
+ self.old_sort!{|x,y| x.uid <=> y.uid}
34
+ return self
35
+ end
36
+ def reset_order
37
+ arr = self.dup
38
+ return arr.reset_order!
39
+ end
40
+ end
@@ -0,0 +1,80 @@
1
+ class Cell < Array
2
+ private
3
+ def cell_bindings arg, i = self.length
4
+ arg.uid = i
5
+ arg.celldm = @celldm
6
+ return arg
7
+ end
8
+ def add_to_atoms args
9
+ args.each do |atom|
10
+ unless self << atom.dup
11
+ $stderr.puts "#{atom} is not an Atom"
12
+ end
13
+ end
14
+ end
15
+ def update_mins_maxes arg
16
+ for i in 0..2
17
+ (@min[i] = arg[i] if @min[i] > arg[i]) rescue @min[i] = arg[i]
18
+ (@max[i] = arg[i] if @max[i] < arg[i]) rescue @max[i] = arg[i]
19
+ end
20
+ end
21
+ def update_atoms_celldm
22
+ self.each do |atom|
23
+ atom.celldm = @celldm
24
+ end
25
+ end
26
+ def scan_mins_maxes
27
+ @min = self[0].coor.dup
28
+ @max = self[0].coor.dup
29
+ self.each do |atom|
30
+ for i in 0..2
31
+ (@min[i] = atom.coor[i] if @min[i] > atom.coor[i]) rescue @min[i] = atom.coor[i]
32
+ (@max[i] = atom.coor[i] if @max[i] < atom.coor[i]) rescue @max[i] = atom.coor[i]
33
+ end
34
+ end
35
+ end
36
+ def change_units unit
37
+ if unit == :crystal
38
+ self.map!{|atom| atom.coor = toCry(atom.coor);atom}
39
+ @max = toCry @max
40
+ @min = toCry @min
41
+ @celldm = [1,1,1]
42
+ elsif unit == :angstrom
43
+ @celldm = @realcelldm
44
+ if @units == :crystal
45
+ self.map!{|atom| atom.coor = fromCry(atom.coor);atom}
46
+ @max = fromCry @max
47
+ @min = fromCry @min
48
+ elsif @units == :bohr
49
+ self.map!{|atom| atom.coor = bhr2ang(atom.coor);atom}
50
+ @max = bhr2ang @max
51
+ @min = bhr2ang @min
52
+ end
53
+ elsif unit == :bohr
54
+ @celldm = @realcelldm.map{|v| v/0.52918}
55
+ if @units == :crystal
56
+ self.map!{|atom| atom.coor = fromCry(atom.coor);atom}
57
+ @max = fromCry @max
58
+ @min = fromCry @min
59
+ elsif @units == :angstrom
60
+ self.map!{|atom| atom.coor = ang2bhr(atom.coor);atom}
61
+ @max = ang2bhr @max
62
+ @min = ang2bhr @min
63
+ end
64
+ end
65
+ end
66
+ def toCry args
67
+ for i in 0..2; args[i]/=@celldm[i]; end rescue nil
68
+ return args
69
+ end
70
+ def fromCry args
71
+ for i in 0..2; args[i]*=@celldm[i]; end rescue nil
72
+ return args
73
+ end
74
+ def ang2bhr args
75
+ return args.map{|v| v / 0.52918}
76
+ end
77
+ def bhr2ang args
78
+ return args.map{|v| v * 0.52918}
79
+ end
80
+ end
@@ -0,0 +1,83 @@
1
+ class Cell < Array
2
+ alias :old_sort! :sort!
3
+ def sort! fields, tol = 0.5
4
+ tol = [tol, tol, tol] unless tol.is_a? Array
5
+ self.old_sort! do |a, b|
6
+ g = fields.to_s.split(//)
7
+ t = a.name <=> b.name
8
+ x = a.x.approx_sort(b.x, tol[0])
9
+ y = a.y.approx_sort(b.y, tol[1])
10
+ z = a.z.approx_sort(b.z, tol[2])
11
+ result = 0
12
+ while result == 0 and g.length > 0
13
+ result = eval(g.shift)
14
+ end
15
+ result
16
+ end
17
+ return self
18
+ end
19
+ def sort *args
20
+ arr = self.dup
21
+ return arr.sort!(*args)
22
+ end
23
+ alias :old_p :<<
24
+ def << arg
25
+ if arg.is_a?(Atom)
26
+ cell_bindings arg
27
+ update_mins_maxes arg.coor
28
+ self.old_p(arg.dup)
29
+ else false
30
+ end
31
+ end
32
+ alias :old_unshift :unshift
33
+ def unshift arg
34
+ if arg.is_a?(Atom)
35
+ cell_bindings arg, 0
36
+ self.each{|atom| atom.uid+=1}
37
+ update_mins_maxes arg.coor
38
+ self.old_unshift(arg.dup)
39
+ else false
40
+ end
41
+ end
42
+ alias :old_push :push
43
+ def push arg
44
+ if arg.is_a?(Atom)
45
+ cell_bindings arg
46
+ update_mins_maxes arg.coor
47
+ self.old_push(arg.dup)
48
+ else false
49
+ end
50
+ end
51
+ alias :old_insert :insert
52
+ def insert arg, index
53
+ if arg.is_a?(Atom)
54
+ cell_bindings arg, index
55
+ update_mins_maxes arg.coor
56
+ self.each do |atom|
57
+ atom.uid+=1 if atom uid >= index
58
+ end
59
+ self.old_insert(arg.dup, index)
60
+ else false
61
+ end
62
+ end
63
+ alias :old_plus :+
64
+ def + arg
65
+ if arg.is_a?(Cell)
66
+ update_mins_maxes arg.min
67
+ update_mins_maxes arg.max
68
+ self.old_plus(arg)
69
+ else false
70
+ end
71
+ end
72
+ def dup
73
+ if @units == :bohr
74
+ arr = Cell.new(:units => @units, :celldm => @celldm)
75
+ else
76
+ arr = Cell.new(:units => @units, :celldm => @realcelldm)
77
+ end
78
+ self.each do |atom|
79
+ arr << atom.dup
80
+ end
81
+ return arr
82
+ end
83
+ end
@@ -0,0 +1,31 @@
1
+ class Cell < Array
2
+ def to_s
3
+ output = ""
4
+ self.each do |atom|
5
+ output += "%s\n" % atom.to_s
6
+ end
7
+ return output
8
+ end
9
+ def to_pdb
10
+ arr = (@units == :angstrom ? self : self.dup)
11
+ arr.units = :angstrom
12
+ output = "CRYST1%9.3f%9.3f%9.3f 90.00 90.00 90.00 P 1\n" % arr.celldm
13
+ i = 0
14
+ arr.each do |atom|
15
+ i += 1
16
+ output += "ATOM %5d %-4s X 1 %8.3f%8.3f%8.3f 1.00 1.00 %-2s\n" % ([i, atom.name] + atom.coor + [atom.name])
17
+ end
18
+ return output
19
+ end
20
+ def to_xyz
21
+ arr = (@units == :angstrom ? self : self.dup)
22
+ arr.units = :angstrom
23
+ output = "%d\n" % arr.length
24
+ output += "Cell Dimensions %10.6f %10.6f %10.6f\n" % arr.celldm
25
+ arr.each do |atom|
26
+ output += "%-2s %10.6f %10.6f %10.6f\n" % ([atom.name] + atom.coor)
27
+ end
28
+ return output
29
+ end
30
+ # def to_cif
31
+ end
@@ -0,0 +1,24 @@
1
+ class Array
2
+ def numbers!
3
+ i = length - 1
4
+ self.reverse_each do |elem|
5
+ if elem.is_a? Array
6
+ self[i] = elem.numbers!
7
+ else
8
+ elem.numeric? ? self[i] = Float(elem):self.delete_at(i)
9
+ end
10
+ i -= 1
11
+ end
12
+ return self
13
+ end
14
+ def numerify!
15
+ self.each_index do |i|
16
+ if self[i].is_a? Array
17
+ self[i] = self[i].numerify!
18
+ else
19
+ self[i] = Float(self[i]) if self[i].numeric?
20
+ end
21
+ end
22
+ return self
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ class Numeric
2
+ (Math.methods - Module.methods - ["hypot", "ldexp"]).each do |method|
3
+ define_method method do
4
+ Math.send method, self
5
+ end
6
+ end
7
+ def approx_sort other, tol = self.to_f/10
8
+ d = self - other
9
+ if d > tol
10
+ return 1
11
+ elsif -d > tol
12
+ return -1
13
+ else
14
+ return 0
15
+ end
16
+ end
17
+ def numeric?
18
+ true
19
+ end
20
+ end
21
+ class Object
22
+ def numeric?
23
+ false
24
+ end
25
+ end
26
+ class String
27
+ def numeric?
28
+ Float(self) != nil rescue false
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ class Object
2
+ def deep_clone
3
+ return @deep_cloning_obj if @deep_cloning
4
+ @deep_cloning_obj = clone
5
+ @deep_cloning_obj.instance_variables.each do |var|
6
+ val = @deep_cloning_obj.instance_variable_get(var)
7
+ begin
8
+ @deep_cloning = true
9
+ val = val.deep_clone
10
+ rescue TypeError
11
+ next
12
+ ensure
13
+ @deep_cloning = false
14
+ end
15
+ @deep_cloning_obj.instance_variable_set(var, val)
16
+ end
17
+ deep_cloning_obj = @deep_cloning_obj
18
+ @deep_cloning_obj = nil
19
+ deep_cloning_obj
20
+ end
21
+ def to_sym
22
+ self.to_s.to_sym
23
+ end
24
+ end
data/lib/pw.rb CHANGED
@@ -1,2 +1,50 @@
1
- module QE
1
+ require_relative "./cell/cell"
2
+ require "fileutil"
3
+ require_relative "./helper/array.rb"
4
+
5
+ class PW
6
+ def self.input ifile
7
+ cell = nil
8
+ File.open(ifile, 'r') do |f|
9
+ nat = f.ff(/nat/).readline.split(/[ ,]/).numbers![0]
10
+ celldm = []
11
+ while f.ff(/celldm/)
12
+ celldm.push f.readline.split(/[ ,]/).numbers!
13
+ end
14
+ celldm.map!{|v| v == celldm[0] ? v * 0.52918 : v * celldm[0]}
15
+ f.ff(/ATOMIC_POSITIONS/)
16
+ unit = unit? f.readline
17
+ cell = Cell.new(:celldm => celldm, :units => unit)
18
+ f.head(nat, true).map{|v| v.split.numerify!}.each do |atom|
19
+ cell << Atom.new(:name => atom[0], :coor => atom[1,4], :fixed => !atom[4].nil?)
20
+ end
21
+ end
22
+ return cell
23
+ end
24
+ def self.output ofile
25
+ cell = nil
26
+ File.open(ofile, 'r') do |f|
27
+ nat = f.ff(/number of atoms/).readline.split.numbers![0]
28
+ celldm = f.ff(/celldm/).readline.split.numbers!
29
+ celldm.map!{|v| v == celldm[0] ? v * 0.52918 : v * celldm[0]}
30
+ f.seek f.size
31
+ unit = unit? f.rew(/ATOMIC_POSITIONS/).readline
32
+ cell = Cell.new(:celldm => celldm, :units => unit)
33
+ f.head(nat, true).map{|v| v.split.numerify!}.each do |atom|
34
+ cell << Atom.new(:name => atom[0], :coor => atom[1,3], :fixed => !atom[4].nil?)
35
+ end
36
+ end
37
+ return cell
38
+ end
39
+ private
40
+ def self.unit? h
41
+ if /crystal/i =~ h
42
+ unit = :crystal
43
+ elsif /angstrom/i =~ h
44
+ unit = :angstrom
45
+ elsif /bohr/i =~ h
46
+ unit = :bohr
47
+ end
48
+ return unit
49
+ end
2
50
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
5
4
  prerelease:
5
+ version: 0.0.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Sencer Selcuk
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-12 00:00:00.000000000 Z
12
+ date: 2013-02-04 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Quantum Espresso
15
15
  email: sencerselcuk@twitter
@@ -17,7 +17,16 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - lib/cell/lib/private.rb
21
+ - lib/cell/lib/redef.rb
22
+ - lib/cell/lib/boundary.rb
23
+ - lib/cell/lib/write.rb
24
+ - lib/cell/lib/atom.rb
25
+ - lib/cell/cell.rb
20
26
  - lib/pw.rb
27
+ - lib/helper/object.rb
28
+ - lib/helper/numeric.rb
29
+ - lib/helper/array.rb
21
30
  homepage:
22
31
  licenses: []
23
32
  post_install_message:
@@ -25,17 +34,17 @@ rdoc_options: []
25
34
  require_paths:
26
35
  - lib
27
36
  required_ruby_version: !ruby/object:Gem::Requirement
28
- none: false
29
37
  requirements:
30
38
  - - ! '>='
31
39
  - !ruby/object:Gem::Version
32
40
  version: '0'
33
- required_rubygems_version: !ruby/object:Gem::Requirement
34
41
  none: false
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
43
  requirements:
36
44
  - - ! '>='
37
45
  - !ruby/object:Gem::Version
38
46
  version: '0'
47
+ none: false
39
48
  requirements: []
40
49
  rubyforge_project:
41
50
  rubygems_version: 1.8.23
@@ -43,3 +52,4 @@ signing_key:
43
52
  specification_version: 3
44
53
  summary: will be implemented
45
54
  test_files: []
55
+ has_rdoc: