class Crysna::Cell
常にソートされたものを返す。
Public Class Methods
# File lib/crysna/cell.rb, line 34 def self.load_file(file) self.new(YAML.load_file(file)) end
sites は element を鍵、サイト名リストを値としたハッシュ。 e.g., sites = { 0 => ["S00", "S01"], 1 => ["S02", "S03"], }
def initialize(sites, energy = nil)
# File lib/crysna/cell.rb, line 25 def initialize(sites) @atoms = [] sites.each do |elem, names| names.each do |name| @atoms << Crysna::Atom.new(elem, name, [0,0,0]) end end end
Generate new instance by POCAR style indication. elems is like {‘Ag’=>2, ‘I’=>2}$ sitenames is like [‘2A’, ‘2B’, ‘IA’, ‘IA’]
# File lib/crysna/cell.rb, line 41 def self.new_elems_sitenames(elems, sitenames) sites = {} elems.each do |elem, num| site_elem = [] num.times { site_elem << sitenames.shift} sites[elem] = site_elem end sites self.new(sites) end
Public Instance Methods
compare configuration_string
で比較する。
old 元素名ソートで若いものから優先して比較する。 Enumerable の min もしくは max メソッドで一意のものが導き出さ れさえすれば良いので、大小の物理的な意味はあまり深く考えない。 当面の基準は、以下: - 含まれる元素リストをソートした配列で比較し、 違えばこれを返す。 このチェックを通過したら含まれる元素は 同じということになる。 - 元素名でソートして番号の若いものから優先的に サイト名の配列で比較。 違えばこれを返す。 全ての元素について行う。 - これらのチェックを通過すれば等しい。
# File lib/crysna/cell.rb, line 202 def <=>(other) self.configuration_string <=> other.configuration_string ###self_tmp = self.centering ###other_tmp = other.centering ###raise TypeError unless other_tmp.is_a? Crysna::Cell ### ####pp self_tmp.configuration_string_full ####pp other_tmp.configuration_string_full ### ###elems = (self_tmp.elements + other_tmp.elements).sort.uniq ### ###elems.each do |element| ### self_tmp_atoms = atoms_of_element(element) ### other_tmp_atoms = other_tmp.atoms_of_element(element) ### ### flag = self_tmp_atoms.size <=> other_tmp_atoms.size ### #pp self_tmp_atoms.size ### #pp other_tmp_atoms.size ### return flag unless flag == 0 ### ### flag = self_tmp_atoms <=> other_tmp_atoms ### ### return flag unless flag == 0 ### self_tmp_atoms.size.times do |i| ### #pp self_tmp_atoms[i] ### #pp other_tmp_atoms[i] ### flag = self_tmp_atoms[i] <=> other_tmp_atoms[i] ### return flag unless flag == 0 ### end ###end ### ###return 0 end
# File lib/crysna/cell.rb, line 123 def ==(other) return false unless atoms.sort == other.atoms.sort return true end
# File lib/crysna/cell.rb, line 283 def [](index) atoms[index] end
element が占有するサイト site_name を追加する。 dup_check を true にすると、 サイト名が重複したときに例外 Crysna::Cell::DuplicateSiteError
を生じる。 dup_check を false にすると、このチェックが行われない。
# File lib/crysna/cell.rb, line 77 def add_atom(element, site_name, global_vector, dup_check = false) if dup_check @atoms.each do |atom| if atom.site.name == site_name raise DuplicateSiteError, "#{site_name} is already occupied in #{@sites.inspect}" end end end @atoms << Crysna::Atom.new(element, site_name, global_vector) @atoms.sort! end
self に対して1つ原子を追加したときにありうる 全ての Crysna::Cell
を配列にして返す。 site_candidates は元素名を鍵、サイトリストを値としたハッシュ。
dup_check は重複サイトチェック。 重複サイトに複数の原子が入る場合を判定する。 dup_check が true だと返される結果に該当項目が含まれない。 dup_check が false だと返される結果に該当項目が含まれる。
site_candidates に含まれていないサイトが self に含まれていても エラーにはせず含まれたまま処理する。
# File lib/crysna/cell.rb, line 139 def added_sites(site_candidates, dup_check = false) results = [] site_candidates.each do |element, added_sites| added_sites.each do |added_site| site_config = Marshal.load(Marshal.dump(self)) begin site_config.add_atom(element, added_site, [0, 0, 0], dup_check) rescue DuplicateSiteError next end results << site_config end end return results end
Return sorted @atoms
# File lib/crysna/cell.rb, line 53 def atoms @atoms.sort! @atoms end
# File lib/crysna/cell.rb, line 160 def atoms_of_element(element) results = [] atoms.each do |atom| results << atom if atom.element == element end results.sort end
Return center-migrateed cell with all atoms. Therefore, global_vector becomes [0,0,0]
# File lib/crysna/cell.rb, line 179 def centering result = Marshal.load(Marshal.dump(self)) result.centering! result end
Destructive migrate all atoms to center cell. Therefore, global_vector becomes [0,0,0]
# File lib/crysna/cell.rb, line 170 def centering! @atoms.map! do |atom| atom.centering end return self end
Return string to which sitenames of atoms are joined. Ignoreing their elements. For example, “ABCD”
# File lib/crysna/cell.rb, line 290 def configuration_string #atoms.map do |atom| # atom.sitename #end . join("") result = elements.map do |elem| "#{elem}:" + atoms_of_element(elem).map {|atom| atom.sitename}.join("-") end .join(",") result end
Return string to which configuration_string_full
of atoms are joined. Ignoreing their elements. For example, “A555-B455-C556-D555” Note: suffix of arabic number is the same manner of CIF indices.
# File lib/crysna/cell.rb, line 305 def configuration_string_full result = elements.map do |elem| "#{elem}:" + atoms_of_element(elem).map {|atom| atom.full_sitename}.join("-") end .join(",") result end
Return element list, which is unique and sorted.
# File lib/crysna/cell.rb, line 156 def elements @atoms.map{|atom| atom.element}.sort.uniq end
Return the cell which is the first in sort.
# File lib/crysna/cell.rb, line 238 def minimize(operations, io = File.open(File::NULL, "w")) min = self io.puts "in Cell::minimize()" operations.each do |ope| id = ope['operation_id'] operation = ope['operation'] io.puts "operation_id: " + id.to_s new = self.operate(operation) new.atoms.each do |atom| io.puts "#{atom.site.name}#{atom.site.global_vector.to_a}" end if new < min min = new io.puts "min is updated" end io.puts end return min end
Execute symmetry operation. site_operation is a hash;
the key is old name, and the value is an array of [new_name, global_vector, rotation]
matrix indicates operation to global vector.
# File lib/crysna/cell.rb, line 98 def operate(site_operation) #pp site_operation @atoms.each do |atom| #pp site_operation;exit unless site_operation.keys.include?(atom.site.name) raise NoEntryError, "#{atom.site.name} is not in #{site_operation.inspect}" end end #result = Crysna::Cell.new({}) result = self.class.new({}) atoms.each do |atom| op = site_operation[atom.site.name] new_name, shift_vector, rotation = *op pos = Matrix[* rotation] * atom.site.global_vector + Mageo::Vector3DInternal[* shift_vector] new_vector = Mageo::Vector3DInternal[* pos] result.add_atom(atom.element, new_name, new_vector) end return result end
Return internal data with format at initialize
e.g., { 0 => ["S00", "S01"], 1 => ["S02", "S03"]}
# File lib/crysna/cell.rb, line 60 def sites results = {} @atoms.each do |atom| elem = atom.element sitename = atom.site.name results[elem] = [] unless results.has_key? elem results[elem] << sitename end results end
CrystalCell::Cell
クラスインスタンスを返す。 引数 axes は格子ベクトルを絶対座標で表したもの。 引数 sites_coordinates はサイト名を鍵、内部座標を値とするハッシュ。
# File lib/crysna/cell.rb, line 274 def to_cell(axes, sites_coordinates) la = CrystalCell::LatticeAxes.new(axes) cc_atoms = [] atoms.each do |atom| cc_atoms << CrystalCell::Atom.new(atom.element, sites_coordinates[atom.site.name]) end CrystalCell::Cell.new(la, cc_atoms) end
Output yaml format. Note that global_vector is discarded.
# File lib/crysna/cell.rb, line 262 def to_yaml results = {} atoms.each do |atom| results[atom.element] ||= [] results[atom.element] << atom.site.name end YAML.dump(results) end