pw 0.0.0 → 0.0.1
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/lib/cell/cell.rb +31 -0
- data/lib/cell/lib/atom.rb +54 -0
- data/lib/cell/lib/boundary.rb +40 -0
- data/lib/cell/lib/private.rb +80 -0
- data/lib/cell/lib/redef.rb +83 -0
- data/lib/cell/lib/write.rb +31 -0
- data/lib/helper/array.rb +24 -0
- data/lib/helper/numeric.rb +30 -0
- data/lib/helper/object.rb +24 -0
- data/lib/pw.rb +49 -1
- metadata +14 -4
data/lib/cell/cell.rb
ADDED
@@ -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
|
data/lib/helper/array.rb
ADDED
@@ -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
|
-
|
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:
|
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:
|