# modified at 2008.7.21 require 'matrix' class RotationGroup Element={ "1z" => Matrix[[1,0,0],[0,1,0],[0,0,1]], "2x" => Matrix[[1,0,0],[0,-1,0],[0,0,-1]], "2y" => Matrix[[-1,0,0],[0,1,0],[0,0,-1]], "2z" => Matrix[[-1,0,0],[0,-1,0],[0,0,1]], "2d" => Matrix[[0,1,0],[1,0,0],[0,0,-1]], "2e" => Matrix[[0,-1,0],[-1,0,0],[0,0,-1]], "3z" => Matrix[[0,1,0],[-1,-1,0],[0,0,1]], "3r" => Matrix[[0,1,0],[0,0,1],[1,0,0]], "4z" => Matrix[[0,1,0],[-1,0,0],[0,0,1]], "6z" => Matrix[[1,1,0],[-1,0,0],[0,0,1]], } System={ "1" => "triclinic", "2" => "monoclinic", "222" => "orthorhombic", "4" => "tetragonal", "422" => "tetragonal", "3" => "trigonal", "32" => "trigonal", "6" => "hexagonal", "622" => "hexagonal", "23" => "cubic", "432" => "cubic", } Axis={ "1" => ["z"], "2" => ["y"], "222" => ["x","y","z"], "4" => ["z"], "422" => ["z","x","d"], "3" => ["z"], "32" => ["z","d","e"], "6" => ["z"], "622" => ["z","d","e"], "23" => ["z","r"], "432" => ["z","r","d"], } def initialize(s) @string=s.gsub(/\s/){""} end attr_reader :string def rotation() return self end def system() System[rotation.string] end def axis() Axis[rotation.string] end def generator() g=@string.gsub(/m/){"-2"} ax=axis() a=[] i=0 while g.size>0 break unless m=/(-?\d'?)(\/(-2'?))?/.match(g) a.push(m[1]+ax[i]) a.push(m[3]+ax[i]) if m[2] g=m.post_match i+=1 end return a end def gen_matrix() g=generator() return g.collect{|e| Element[e]} end def position(pstn) a=[pstn] b=[""] while b.size>0 b=[] for e1 in gen_matrix for e2 in a p=e1*e2 b.push(p) unless a.include?(p) end a=(a+b).uniq end end return a end def element() return position(Element["1z"]) end end # class class Matrix Direction={ #100 [1,0,0] => 'x', [0,1,0] => 'y', [0,0,1] => 'z', #110 [0,1,1] => 'yz', [1,0,1] => 'zx', [1,1,0] => 'xy', [0,1,-1] => 'y-z', [1,0,-1] => 'z-x', [1,-1,0] => 'x-y', #111 [1,1,1] => 'xyz', [-1,1,1] => '-xyz', [1,-1,1] => 'x-yz', [1,1,-1] => 'xy-z', #hexa 100,010,110 [2,1,0] => '2xy', [1,2,0] => 'x2y', } def operation rt=rotation.to_s.sub(/^\-2/){"m"} rt+=eigen unless rt=~/\-?1/ return rt end def rotation # trace=2cos(t)+1 h={3=>1, -1=>2, 0=>3, 1=>4, 2=>6} t=self.tr d=self.det return h[t*d]*d end def eigen sign=self.det str="" for ve in Direction.keys v=Vector[*ve] if sign*self*v==v str=Direction[ve] end end return str end def to_xyz char=["x","y","z"] a=[] for i in 0..2 s="" for j in 0..2 s+="+#{self[i,j]}#{char[j]}" unless self[i,j]==0 end s="0" if s=="" s.gsub!(/\+\-/){"-"} s.gsub!(/^\+/){""} s.gsub!(/1([x-z])/){"#{$1}"} a.push(s) end return a end end #class