package TB;
use Exporter;
@ISA = qw(Exporter);
#公開したいサブルーチン
@EXPORT = qw();
use strict;
use File::Basename;
use Crystal::SpaceGroup;
use Crystal::DVXa;
use Crystal::XCrySDen;
#my $DirectorySeparator = "\\";
my $WebRootDir = "d:\\MyWebs";
my $ProgramDir = "d:\\Programs";
my $DVXaDir = Deps::MakePath($ProgramDir, "DVXa97", 1);
my $NonRelDir = Deps::MakePath($DVXaDir, "exec", 1);
my $NonRelPath = Deps::MakePath($NonRelDir, "nonrel", 0);
my $KListDBDir = Deps::MakePath($WebRootDir, "Research", 1);
$KListDBDir = Deps::MakePath($KListDBDir, "klist", 1);
#===============================================
# 変数取得関数
#===============================================
sub KListDBDir {
my $this = shift;
return $this->{'KListDBDir'} if($this->{'KListDBDir'});
return $this->{'KListDBDir'} = $KListDBDir;
}
sub SetKListDBDir {
my($this, $d) = @_;
$this->{'KListDBDir'} = $d;
return $d;
}
sub NonRelDir {
my $this = shift;
return $this->{'NonRelDir'} if($this->{'NonRelDir'});
return $this->{'NonRelDir'} = $NonRelDir;
}
sub SetNonRelDir {
my($this, $d) = @_;
$this->{'NonRelDir'} = $d;
$this->SetNonRelFile();
return $d;
}
sub SetNonRelFile {
my ($this) = @_;
my $file = "nonrel";
$this->{'NonRelFile'} = $file;
$NonRelDir = $this->NonRelDir();
$this->{'NonRelPath'}
= $NonRelPath = Deps::MakePath($NonRelDir, $file, 0);
#print "dd: ", $this->NonRelDir(), "
\n";
#print "ff: ", $this->{'NonRelPath'}, "
\n";
return $this->{'NonRelPath'};
}
sub NonRelPath
{
my ($this) = @_;
return $this->{'NonRelPath'};
}
#===============================================
# コンストラクタ、デストラクタ
#===============================================
sub new
{
my ($module) = @_;
my $this = {};
bless $this;
return $this;
}
sub DESTROY
{
my $this = shift;
}
#===============================================
# 一般関数
#===============================================
sub SetSampleName
{
my ($this, $name) = @_;
return $this->{'SampleName'} = $name;
}
sub SampleName
{
my ($this) = @_;
return $this->{'SampleName'};
}
sub SaveTBInputFile
{
my ($this, $Crystal, $filename) = @_;
my $LF = "
\n";
my $DVXa = new DVXa;
my $NonRelDir = $DVXa->SetNonRelDir($this->NonRelDir());
my $NonRelPath = $DVXa->NonRelPath();
#print "Nonrel path: $NonRelPath$LF";
my $XC = new XCrySDen;
my $KListDBDir = $XC->SetKListDBDir($this->KListDBDir);
#print "klist DB dir: $KListDBDir$LF";
#ファイル名を(ベース名, ディレクトリ名, 拡張子)に分解
my @filenames = fileparse($filename, "\.[^\.]+");
my @AtomTypeList = $Crystal->GetCAtomTypeList();
#ファイル作製開始
unless(open(OUT,">$filename")) {
print "Can not write to [$filename].$LF$LF";
return;
}
my $SampleName = $this->SampleName();
my ($a,$b,$c,$alpha,$beta,$gamma)
= $Crystal->LatticeParametersByOutputMode(0);
my @AtomTypeList = $Crystal->GetCAtomTypeList();
my $nAtomTypes = @AtomTypeList;
my @ExpandedAtomSiteList
= $Crystal->GetCExpandedAtomSiteListByOutputMode();
my $nAtoms = @ExpandedAtomSiteList;
# my $SPGName = $Crystal->SPGNameByOutputMode();
# my $iSPG = $Crystal->iSPGByOutputMode();
my $SPGName = $Crystal->SPGName();
my $iSPG = $Crystal->iSPG();
my ($KListFilePath, @KList) = $XC->ReadKList($iSPG, $SPGName);
#print "KList DB file: $KListFilePath$LF\n";
print OUT<\n";
print OUT "$nAtomTypes\n";
for(my $i = 0 ; $i < $nAtomTypes ; $i++) {
my $type = $AtomTypeList[$i];
my $name = $type->AtomNameOnly();
my $charge = $type->Charge();
#print "$i: $name ($charge)
\n";
$charge = 0 unless(defined $charge);
#print "'$name'
\n";
print OUT "'$name' '$charge'\n";
my ($nOrbitals, $AtomicNumber, @Orbitals) = $DVXa->ReadOrbitals($name);
DVXa::ModifyIonOccupancy(\@Orbitals, $charge);
print OUT " $nOrbitals\n";
for(my $j = 0 ; $j < $nOrbitals ; $j++) {
my $pOrb = $Orbitals[$j];
my $n = $pOrb->{'n'};
my $l = $pOrb->{'l'};
my $m = 0;
my $Energy = $pOrb->{'Energy'};
my $Ne = $pOrb->{'Ne'};
my $ri = 0.0;
my $rd = 0.0;
if($l == 2.0) {
$rd = 1.10;
}
#n l m n(electrons) energy(eV) ri rd
printf OUT " %d %d %d %8.4f %12.4f %8.4f %8.4f\n",
$n, $l, $m, $Ne, $Energy, $ri, $rd;
}
#'Sr'
# 10
# 1 0 0 2. 1 0 0
# 2 0 0 2. 1 0 0
# 2 1 0 6. 1 0 0
# 3 0 0 2. 1 0 0
# 3 1 0 6. 1 0 0
# 3 2 0 10. 1 0 0
# 4 0 0 2. 1 0 0
# 4 1 0 6. 1 0 0
# 4 2 0 0. 1 0 0
# 5 0 0 0. 5.00 1.10 0
}
print OUT<AtomNameOnly();
my ($x,$y,$z) = $atom->Position(1);
my $occupancy = $atom->Occupancy();
# my $mult = $atom->Multiplicity();
my $id = $atom->Id();
next if($occupancy < 0.9999);
printf OUT "%2d %12.8f %12.8f %12.8f\n",
$id, $x, $y, $z;
}
#Occupancyが1未満のサイト
for(my $i = 0 ; $i < $nAtoms ; $i++) {
my $atom = $ExpandedAtomSiteList[$i];
my $atomname = $atom->AtomNameOnly();
my ($x,$y,$z) = $atom->Position(1);
my $occupancy = $atom->Occupancy();
# my $mult = $atom->Multiplicity();
my $id = $atom->Id();
next if($occupancy > 0.9999);
printf OUT "%2d %12.8f %12.8f %12.8f\n",
$id, $x, $y, $z;
}
print OUT "\n";
print OUT "[Calculation points in Reciprocal Space]\n";
my $nKList = @KList - 1;
print OUT "$nKList\n";
for(my $i = 1 ; $i < $nKList+1 ; $i++) {
my $pk1 = $KList[$i-1];
my $pk2 = $KList[$i];
my $label1 = $pk1->{'Label'};
my $kx1 = $pk1->{'kx'};
my $ky1 = $pk1->{'ky'};
my $kz1 = $pk1->{'kz'};
my $label2 = $pk2->{'Label'};
my $kx2 = $pk2->{'kx'};
my $ky2 = $pk2->{'ky'};
my $kz2 = $pk2->{'kz'};
my $nPoint = $pk2->{'nPoint'};
#0 0 0 0 0 1 10
#0 0 0 0 1 1 10
printf OUT "%10.4f %10.4f %10.4f %10.4f %10.4f %10.4f %3d '%s' '%s'\n",
$kx1, $ky1, $kz1, $kx2, $ky2, $kz2, $nPoint, $label1, $label2;
}
print OUT<