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

Parameters:

  • x (Float) (defaults to: nil)

    The x coordinate of the atom in angstrom

  • y (Float) (defaults to: nil)

    The y coordinate of the atom in angstrom

  • z (Float) (defaults to: nil)

    The z coordinate of the atom in angstrom

  • s (String, nil) (defaults to: nil)

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

  • c (Boolean, String, Array<String>) (defaults to: Array.new)

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



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

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



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

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)



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

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

#cloneObject

An exact clone of the atom. Same ID and everything



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

def clone
  a = Atom.new(self.x, self.y, self.z, self.species, self.constrain)
  a.id = self.id
  return a
end

#constrained?Boolean

A boolean value, True if the atom has relaxation constraints

Returns:

  • (Boolean)


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

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, but with a unique id



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

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



112
113
114
# File 'lib/aims/atom.rb', line 112

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



117
118
119
120
121
# File 'lib/aims/atom.rb', line 117

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



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

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)



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

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



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/aims/atom.rb', line 189

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



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

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.



176
177
178
179
180
# File 'lib/aims/atom.rb', line 176

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)



143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/aims/atom.rb', line 143

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)



160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/aims/atom.rb', line 160

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)



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/aims/atom.rb', line 125

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



183
184
185
# File 'lib/aims/atom.rb', line 183

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