Class: Aims::Atom

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/aims/atom.rb

Constant Summary collapse

@@lastid =

The last id assigned to an atom

0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x = nil, y = nil, z = nil, s = nil, c = Array.new) ⇒ Atom

Create an atom of the specified species at the given coordinates

  • x The x coordinate of the atom in angstrom

  • y The y coordinate of the atom in angstrom

  • z The z coordinate of the atom in angstrom

  • s The atomic species ex. “C”, “Si”, “S”, etc. (can be nil)

  • c The relaxation constraints. valid values are TRUE, FALSE, “.true.”, “.false.”, “x”, “y”, “z” or %w(x y z)



30
31
32
33
34
35
36
37
38
# File 'lib/aims/atom.rb', line 30

def initialize(x=nil, y=nil, z=nil, s=nil, c=Array.new)
  self.x = x
  self.y = y
  self.z = z
  self.species = s
  self.precision = 0.0001
  self.id = (@@lastid +=1)
  self.constrain = c
end

Instance Attribute Details

#constrainObject

The relaxation constraints of this atom



18
19
20
# File 'lib/aims/atom.rb', line 18

def constrain
  @constrain
end

#idObject

The id of this atom. Every atom has a unique id



14
15
16
# File 'lib/aims/atom.rb', line 14

def id
  @id
end

#precisionObject

Two atoms are equal if their coordinates are the same to this precision



20
21
22
# File 'lib/aims/atom.rb', line 20

def precision
  @precision
end

#speciesObject

The species of this atom



16
17
18
# File 'lib/aims/atom.rb', line 16

def species
  @species
end

#xObject

The x coordinate of the atom in angstrom



8
9
10
# File 'lib/aims/atom.rb', line 8

def x
  @x
end

#yObject

The y coordinate of the atom in angstrom



10
11
12
# File 'lib/aims/atom.rb', line 10

def y
  @y
end

#zObject

The z coordinate of the atom in angstrom



12
13
14
# File 'lib/aims/atom.rb', line 12

def z
  @z
end

Instance Method Details

#==(atom) ⇒ Object Also known as: eql?

Two atoms are equal if their coordinates are equal and they are the same species



59
60
61
62
63
64
# File 'lib/aims/atom.rb', line 59

def ==(atom)
	((self.x-atom.x).abs < self.precision) & 
	((self.y-atom.y).abs < self.precision) & 
	((self.z-atom.z).abs < self.precision) & 
	(self.species == atom.species)
end

#[](i) ⇒ Object

Index into the Atom’s coordinates (x,y,z)



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/aims/atom.rb', line 78

def [](i)
  case i
  when 0
    self.x
  when 1
    self.y
  when 2
    self.z
  else
    raise "Index Out of Bounds"
  end
end

#constrained?Boolean

A boolean value, True if the atom has relaxation constraints

Returns:

  • (Boolean)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/aims/atom.rb', line 42

def constrained?
  if self.constrain
    if self.constrain == true
      true
    elsif self.constrain.is_a? String
      true
    elsif self.constrain.is_a? Array and not self.constrain.empty?
      true
    else
      false
    end
  else
    false
  end
end

#copyObject

A deep copy of the atom



97
98
99
# File 'lib/aims/atom.rb', line 97

def copy
  Atom.new(self.x, self.y, self.z, self.species, self.constrain)
end

#displace(x, y, z) ⇒ Object

Return a new atom with the same species and relaxation constraints but with coordinates displaced by x, y, z



103
104
105
# File 'lib/aims/atom.rb', line 103

def displace(x,y,z)
  Atom.new(self.x+x, self.y+y, self.z+z, self.species, self.constrain)
end

#displace!(x, y, z) ⇒ Object

Displace this atom in place



108
109
110
111
112
# File 'lib/aims/atom.rb', line 108

def displace!(x,y,z)
  self.x += x
  self.y += y
  self.z += z
end

#distance_to(atom) ⇒ Object

Return the distance to another atom



92
93
94
# File 'lib/aims/atom.rb', line 92

def distance_to(atom)
	Math.sqrt((self.x - atom.x)**2 + (self.y - atom.y)**2 + (self.z - atom.z)**2)
end

#eachObject

Enumerate over each coordinate (x,y,z)



73
74
75
# File 'lib/aims/atom.rb', line 73

def each
  [self.x, self.y, self.z].each{|i| yield i}
end

#format_geometry_inObject

Print a string representation of this atom formatted in the geometry.in format used by Aims



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/aims/atom.rb', line 180

def format_geometry_in
  line = "atom %16.6f %16.6f %16.6f %s" % [self.x, self.y, self.z, self.species]
  if self.constrain
    if self.constrain == true
      line << "\nconstrain_relaxation .true."
    elsif self.constrain.is_a? String
      line << "\nconstrain_relaxation #{self.constrain}"
    elsif self.constrain.is_a? Array and not self.constrain.empty?
      self.constrain.each{|c|
        line << "\nconstrain_relaxation #{c}"            
      }
      line << "\n"
    end
  end
  line
end

#hashObject

Implementation for Hash equality testing



68
69
70
# File 'lib/aims/atom.rb', line 68

def hash
  (self.x*self.y + self.z).abs.ceil
end

#rotate(mat) ⇒ Object

Return a new rotated atom about the origin using the given 3x3 Math::Matrix.



167
168
169
170
171
# File 'lib/aims/atom.rb', line 167

def rotate(mat)
  v = Vector[self.x, self.y, self.z]
  newv = mat*v
  Atom.new(newv[0], newv[1], newv[2], self.species, self.constrain)
end

#rotate_X(angle) ⇒ Object

Return an atom rotated about the x-axis using the origin as the center-point.

  • angle Is the amount to rotate in degrees (or it can respond to :sin and :cos)



134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/aims/atom.rb', line 134

def rotate_X(angle)
  sinA = if angle.respond_to? :sin
    angle.sine
  else
    Math.sin(angle*Math::PI/180)
  end
  cosA = if angle.respond_to? :cos
    angle.cos
  else
    Math.cos(angle*Math::PI/180)
  end
  mat = Matrix[[1, 0, 0], [0, cosA, -1*sinA],[0, sinA, cosA]]
  rotate(mat)       
end

#rotate_Y(angle) ⇒ Object

Return an atom rotated about the y-axis using the origin as the center-point.

  • angle Is the amount to rotate in degrees (or it can respond to :sin and :cos)



151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/aims/atom.rb', line 151

def rotate_Y(angle)
  sinA = if angle.respond_to? :sin
    angle.sine
  else
    Math.sin(angle*Math::PI/180)
  end
  cosA = if angle.respond_to? :cos
    angle.cos
  else
    Math.cos(angle*Math::PI/180)
  end
  mat = Matrix[[cosA, 0, -1*sinA],[0, 1, 0], [sinA, 0, cosA]]
  rotate(mat)             
end

#rotate_Z(angle) ⇒ Object

Return an atom rotated about the z-axis using the origin as the center-point.

  • angle Is the amount to rotate in degrees (or it can respond to :sin and :cos)



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/aims/atom.rb', line 116

def rotate_Z(angle)
  sinA = if angle.respond_to? :sin
    angle.sine
  else
    Math.sin(angle*Math::PI/180)
  end
  cosA = if angle.respond_to? :cos
    angle.cos
  else
    Math.cos(angle*Math::PI/180)
  end
  
  mat = Matrix[[cosA, -1*sinA, 0],[sinA, cosA, 0], [0,0,1]]
  rotate(mat) 
end

#to_sObject

Print a string representation of this atom



174
175
176
# File 'lib/aims/atom.rb', line 174

def to_s
  "%s %16.6f %16.6f %16.6f" % [self.species, self.x, self.y, self.z]
end