package TSPACE; use Exporter; @ISA = qw(Exporter); #公開したいサブルーチン @EXPORT = qw(); #use lib "d:/Programs/Perl/lib"; use strict; use File::Basename; use ProgVars; use Utils; #=============================================== # スクリプト大域変数 #=============================================== my %TSPACELatticeTypeHash = ( 0 => "Simple hexagonal", 1 => "Other simple lattices", 2 => "Face centered", 3 => "Body centered", 4 => "C centered", -1 => "Trigonal in rhomb lattice", ); my @TSPACELatticeTypeList = ( 0 => "Simple hexagonal", 1 => "Other simple lattices", 2 => "Face centered", 3 => "Body centered", 4 => "C centered", -1 => "Trigonal in rhomb lattice", ); my %PointGroupDB = { Oh => {LatticeSystem => 'cubic', RotationOperation => 'Oh'}, O => {LatticeSystem => 'cubic', RotationOperation => 'Oh'}, Td => {LatticeSystem => 'cubic', RotationOperation => 'Oh'}, Th => {LatticeSystem => 'cubic', RotationOperation => 'Oh'}, T => {LatticeSystem => 'cubic', RotationOperation => 'Oh'}, D4h => {LatticeSystem => 'tetragonal', RotationOperation => 'Oh'}, D4 => {LatticeSystem => 'tetragonal', RotationOperation => 'Oh'}, D2d => {LatticeSystem => 'tetragonal', RotationOperation => 'Oh'}, C4v => {LatticeSystem => 'tetragonal', RotationOperation => 'Oh'}, C4h => {LatticeSystem => 'tetragonal', RotationOperation => 'Oh'}, S4 => {LatticeSystem => 'tetragonal', RotationOperation => 'Oh'}, C4 => {LatticeSystem => 'tetragonal', RotationOperation => 'Oh'}, D2h => {LatticeSystem => 'orthogonal', RotationOperation => 'Oh'}, D2 => {LatticeSystem => 'orthogonal', RotationOperation => 'Oh'}, C2v => {LatticeSystem => 'orthogonal', RotationOperation => 'Oh'}, D6h => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, D6 => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, D3h => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, C6v => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, C6h => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, C3h => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, C6 => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, # D3d => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, # D3 => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, # C3v => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, # S6 => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, # C3 => {LatticeSystem => 'hexagonal', RotationOperation => 'D6h'}, D3d => {LatticeSystem => 'trigonal', RotationOperation => 'D6h'}, D3 => {LatticeSystem => 'trigonal', RotationOperation => 'D6h'}, C3v => {LatticeSystem => 'trigonal', RotationOperation => 'D6h'}, S6 => {LatticeSystem => 'trigonal', RotationOperation => 'D6h'}, C3 => {LatticeSystem => 'trigonal', RotationOperation => 'D6h'}, C2h => {LatticeSystem => 'monoclinic', RotationOperation => 'Oh'}, Cs => {LatticeSystem => 'monoclinic', RotationOperation => 'Oh'}, C2 => {LatticeSystem => 'monoclinic', RotationOperation => 'Oh'}, Ci => {LatticeSystem => 'triclinic', RotationOperation => 'Oh'}, C1 => {LatticeSystem => 'triclinic', RotationOperation => 'Oh'}, }; #=============================================== # パス(読み込みDB) # Web関係変数 # CGI の仮想パス # プログラム名 #=============================================== my $Program = ProgVars::Program(); my $ProgramDir = ProgVars::ProgramDir(); my $ProgramOldDir = ProgVars::ProgramOldDir(); my $BinDir = Deps::MakePath($TSPACEDir, "bin", 0); my $WYCOFFPath = Deps::MakePath($TSPACEDBDir, "WYCOFF", 0); my $GENERATORPath = Deps::MakePath($TSPACEDBDir, "GENERATOR", 0); my $D6hRotationOperationTablePath = Deps::MakePath($TSPACEDBDir, "D6hRotationOperationTable.txt", 0); my $OhRotationOperationTablePath = Deps::MakePath($TSPACEDBDir, "OhRotationOperationTable.txt", 0); #============================================================ # 静的関数 #============================================================ sub GetTSPACELatticeTypeHash { return \%TSPACELatticeTypeHash; } sub GetTSPACELatticeTypeList { return \@TSPACELatticeTypeList; } #============================================================ # 変数等取得、再定義関数 #============================================================ sub GetRotationOperationTable { my ($this, $Sym, $Type) = @_; if($Type eq 'List') { return $this->{"p${Sym}RotationOperationTableList"}; } else { $this->{"p${Sym}RotationOperationTableHash"}; } } sub GetWycoffPositionList { my ($this) = @_; return $this->{pWycoffPositionList}; } sub GetWycoffPositionHash { my ($this, $iSPG, $iSet) = @_; $iSet = 1 if(!defined $iSet); my $p = $this->{pWycoffPositionList}; return $p->[$iSPG][$iSet]; } sub GetGeneratorList { my ($this) = @_; return $this->{pGeneratorList}; } sub GetGeneratorHash { my ($this, $iSPG, $iSet) = @_; $iSet = 1 if(!defined $iSet); my $p = $this->{pGeneratorList}; return $p->[$iSPG][$iSet]; } sub GetSPGName { my ($this, $iSPG, $iSet) = @_; $iSet = 1 if(!defined $iSet); my $p = $this->{pGeneratorList}; return ('', '') if(!defined $p); my $h = $p->[$iSPG][$iSet]; return ($h->{PointGroup}, $h->{SpaceGroup}); } sub GetRotationOperationGroup { my ($this, $PointGroup) = @_; if($PointGroupDB{$PointGroup}) { return $PointGroupDB{$PointGroup}->{RotationOperation}; } if($PointGroup eq 'Cs3') { return 'Oh'; } if($PointGroup =~ /4/) { return 'Oh'; } if($PointGroup =~ /^[A-Z]3/ or $PointGroup =~ /^[A-Z]6/) { return 'D6h'; } return 'Oh'; } #============================================================ # 継承クラスで定義しなおす関数 #============================================================ #============================================================ # コンストラクタ、デストラクタ #============================================================ sub new { my ($module) = @_; my $this = {}; bless $this; $this->ReadDatabases(); return $this; } sub DESTROY { my $this = shift; } #============================================================ # ファイル読み込み関数 #============================================================ sub ReadDatabases { my ($this) = @_; $this->ReadRotationOperationTable('D6h'); $this->ReadRotationOperationTable('Oh'); $this->ReadGeneratorDB(); $this->ReadWycoffPositions(); } sub ReadWycoffPositions { my ($this) = @_; my $in = JFile->new($WYCOFFPath, "r"); if(!$in) { print("Error in TSPACE::ReadWycoffPositions: Can not read [$WYCOFFPath].\n"); return; } my @List; my $iPrevSPG = 1; my $iSet = 1; while(1) { my $line = $in->ReadLine(); Utils::DelSpace($line); last if($line eq ''); my ($iSPG, $nWycoff) = Utils::Split("\\s+", $line); if($iSPG == $iPrevSPG) { $iSet++; } else { $iPrevSPG = $iSPG; $iSet = 1; } #print "SPG=$iSPG [$iSet]: nW = $nWycoff
\n"; my @Pos; for(my $i = 0 ; $i < $nWycoff ; $i++) { $line = $in->ReadLine(); my ($w, $x, $y, $z) = Utils::Split("\\s+", $line); $Pos[$i] = { Name => $w, x => $x, y => $y, z => $z, }; #print " $w: ($x, $y, $z)
\n"; } $List[$iSPG][$iSet] = { iSPG => $iSPG, iSet => $iSet, nWycoffPositions => $nWycoff, pPositions => \@Pos, }; } $in->Close(); $this->{pWycoffPositionList} = \@List; } sub ReadGeneratorDB { my ($this) = @_; my $in = JFile->new($GENERATORPath, "r"); if(!$in) { print("Error in TSPACE::ReadGeneratorDB: Can not read [$GENERATORPath].\n"); return; } my @List; my $iPrevSPG = 0; my $iSet = 1; while(1) { my $line = $in->ReadLine(); Utils::DelSpace($line); last if($line eq ''); my ($iSPG, $idx, $nGen, $PGName, $SPGName) = ($line =~ /(\d+)\s+([-\d]+)\s+(\d+)\s+(\S+)\s+(.*)\s*$/); if($iSPG == $iPrevSPG) { $iSet++; } else { $iPrevSPG = $iSPG; $iSet = 1; } #print "SPG=$iSPG [$iSet]: $idx, nGen=$nGen: $PGName: $SPGName
\n"; my @Gen; for(my $i = 0 ; $i < $nGen ; $i++) { $line = $in->ReadLine(); my ($iRot, $a1, $b1, $a2, $b2, $a3, $b3) = Utils::Split("\\s+", $line); $Gen[$i] = { iRotation => $iRot, a1 => $a1, b1 => $b1, v1 => $a1 / $b1, a2 => $a2, b2 => $b2, v2 => $a2 / $b2, a3 => $a3, b3 => $b3, v3 => $a3 / $b3, }; #print " $iRot, $a1/$b1, $a2/$b2, $a3/$b3
\n"; } $List[$iSPG][$iSet] = { iSPG => $iSPG, iSet => $iSet, nGenerator => $nGen, PointGroup => $PGName, SpaceGroup => $SPGName, pGenerators => \@Gen, }; } $in->Close(); $this->{pGeneratorList} = \@List; } sub ReadRotationOperationTable { my ($this, $Sym) = @_; my $InFile; if($Sym eq 'D6h') { $InFile = $D6hRotationOperationTablePath; } else { $InFile = $OhRotationOperationTablePath; } my $in = JFile->new($InFile, "r"); if(!$in) { print("Error in TSPACE::ReadRotationOperationTable: Can not read [$InFile].\n"); return; } my @Op; my %OpHash; $in->SkipTo("TABLE OF OPERATION CODE"); for(my $i = 0 ; ; $i++) { my $line = $in->ReadLine(); last if(!defined $line); my ($idx, $name, $x, $y, $z) = Utils::Split("\\s+", $line); last if(!defined $z); $x =~ s/-W/-X+Y/; $y =~ s/-W/-X+Y/; $z =~ s/-W/-X+Y/; $x =~ s/W/X-Y/; $y =~ s/W/X-Y/; $z =~ s/W/X-Y/; #$App->print(" $idx: $name: ($x $y $z)\n"); $Op[$idx] = {Name => $name, x => $x, y => $y, z => $z}; $OpHash{$name} = {ID => $idx, x => $x, y => $y, z => $z}; } $this->{"p${Sym}RotationOperationTableList"} = \@Op; $this->{"p${Sym}RotationOperationTableHash"} = \%OpHash; $in->SkipTo("GROUP TABLE FOR"); my $line = $in->ReadLine(); my @idx1 = Utils::Split("\\s+", $line); my $nOp = @idx1; #$App->print("\n"); #$App->H3("# of operation without inversion: $nOp\n"); #$App->BeginTable(1); #$App->BeginRow(); for(my $i = 0 ; $i < $nOp ; $i++) { my $ip1 = $i+1; #$App->TableCell("$Op[$ip1]->{Name}"); } #$App->EndRow(); for(my $i = 0 ; ; $i++) { my $line = $in->ReadLine(); last if(!defined $line); my ($idx, @a) = Utils::Split("\\s+", $line); last if(@a < $nOp-1); #$App->BeginRow(); #$App->TableCell("$Op[$idx]->{Name}"); for(my $j = 0 ; $j < @a ; $j++) { my $idx2 = $a[$j]; #$App->TableCell($Op[$idx2]->{Name}); } #$App->EndRow(); } #$App->EndTable(); $in->SkipTo("INVERS ELEMENTS"); my @InvOp; for(my $i = 0 ; ; $i++) { my $line = $in->ReadLine(); last if(!defined $line); my @a = Utils::Split("\\s+", $line); last if(@a == 0); push(@InvOp, @a); } #$App->print("\n"); #$App->print("Inverse elements\n"); for(my $i = 0 ; $i < @InvOp ; $i++) { my $ip1 = $i+1; #$App->print("$Op[$ip1]->{Name}=>$Op[$InvOp[$i]]->{Name} "); } #$App->print("\n"); $in->Close(); } 1;