package LD;
use Exporter;
@ISA = qw(Exporter);
#公開したいサブルーチン
@EXPORT = qw();
use strict;
use File::Basename;
use Deps;
use Utils;
use Sci::Science;
use ProgVars;
#use Crystal::MyUtility;
use Crystal::Crystal;
use Crystal::AtomType;
use Crystal::AtomSite;
use Crystal::CIF;
#===============================================
# スクリプト大域変数
#===============================================
my $LF = "
\n";
my $DirectorySeparator = "\\";
#===============================================
# パス(読み込みDB)
# Web関係変数
# CGI の仮想パス
# プログラム名
#===============================================
my $Program = basename($0);
my $ProgramDir = ProgVars->ProgramDir();
my $LDDir = ProgVars->LDDir();
my $MXDDir = ProgVars->MXDDir();
my $MXDOrtoDir = ProgVars->MXDOrtoDir();
my $MXDExecDir = ProgVars->MXDExecDir();
my $SX1DBPath = ProgVars->SX1DBPath();
BEGIN {
}
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 GetBusingParameter
{
my ($this,$atomname) = @_;
$atomname =~ s/\{.*\}//g;
unless(open(IN, "<$SX1DBPath")) {
print "Error in MXD.pm::GetBusingParameter: "
."Can not read DB [$SX1DBPath].
\n";
return ('');
}
;
while() {
my ($name, $mass, $charge, $ai, $bi, $ci, $rad)
= split(/\s+/, $_);
#print "name: $name, $atomname ($mass, $charge, $ai, $bi)
\n";
if(uc $name eq uc $atomname) {
return ($mass, $charge, $ai, $bi, $ci, $rad);
}
}
close(IN);
return ('');
}
sub MakeLDFiles
{
my ($this, $Crystal, $Function, $fname, $pModifiedParams, $EWALD, $EPS) = @_;
my $LDDATPath = "$fname.dat";
my $LD01Path = "$fname.f01";
my $LD02Path = "$fname.f02";
my $LD07Path = "$fname.f07";
if($pModifiedParams) {
$LDDATPath = "$fname-modified.dat";
$LD02Path = "$fname-modified.f02";
}
# print("($LDDATPath) is deleted.\n") if(unlink($LDDATPath));
# print("($LD01Path) is deleted.\n") if(unlink($LD01Path));
# print("($LD02Path) is deleted.\n") if(unlink($LD02Path));
# print("($LD07Path) is deleted.\n") if(unlink($LD07Path));
if($this->MakeLD01File($Crystal, $Function, $LD01Path) <= 0) {
print("Error in LD::MakeLDFiles: Can not write to [$LD01Path].\n");
return 0;
}
if($this->MakeLD02File($Crystal, $Function, $LD02Path, $pModifiedParams) <= 0) {
print("Error in LD::MakeLDFiles: Can not write to [$LD02Path].\n");
return 0;
}
if($this->MakeLD07File($Crystal, $Function, $LD07Path, $EWALD, $EPS) <= 0) {
print("Error in LD::MakeLDFiles: Can not write to [$LD07Path].\n");
return 0;
}
#ファイル名リストのファイル .DAT をつくる
print("\n");
print("Create [$LDDATPath]\n");
unless(open(OUT,">$LDDATPath")) {
print "Can't write to $LDDATPath.\n\n";
return;
}
print OUT "[Files]\n";
print OUT "$LD01Path\n";
print OUT "$LD02Path\n";
print OUT "$fname.f04\n";
print OUT "$LD07Path\n";
print OUT "$fname.f08\n";
print OUT "$fname.f09\n";
if($Function =~ /Phonon/i) {
print OUT "\n";
print OUT "[General]\n";
print OUT "0.4 EwaldAlpha\n";
print OUT "0.8 MinIonicRadius\n";
print OUT "1.0e-6 ConvergenceEPS\n";
print OUT "\n";
print OUT "[CalRange for Phonon]\n";
print OUT "Execute\n";
print OUT "\n";
print OUT "[CalDistance]\n";
print OUT "6.0 MaxDistance\n";
print OUT "Execute\n";
print OUT "\n";
print OUT "[SaveCrystal]\n";
print OUT "Execute\n";
print OUT "\n";
print OUT "[EnergyTest]\n";
print OUT "NotExecute\n";
print OUT "\n";
print OUT "[CalEnergies]\n";
print OUT "NotExecute\n";
print OUT "\n";
print OUT "[Phonon]\n";
print OUT "0 fPhononDebug\n";
print OUT "1 fUsedu/dx\n";
print OUT "0 iPrintMatrixLevel=0: none 1: Wij 2: Wij/Gij "
."3: Wij/Gij/Normalized Wij\n";
print OUT "0 iEigenSolver=0: ZHEGV(Hermitian) "
."1: ZGGEV(Asymmetric) 2: EigAB(Real)\n";
print OUT "2 iPrintEigenVectorLevel=0: none 1: Complex "
."2: Norm 3: Complex/Norm\n";
print OUT "10 nPrintEigenVectors\n";
print OUT "3.0e-5 500 500 500 CalPhononPrecision "
."nULimitNRange(3)\n";
print OUT "1.0e-14 EigCHEPS (for iEigenSolver=2)\n";
print OUT "3.0 3.0 wWindowFunc, nSigmaUsed\n";
print OUT "2\n";
print OUT "0.0 1.0 0.0 0.0 0.0 0.0 21\n";
print OUT "0.0 0.0 0.0 0.0 0.0 1.0 21\n";
print OUT "Execute\n";
print OUT "0.0 1.0 0.0 1.0 0.0 0.0 21\n";
print OUT "0.0 1.0 0.0 1.0 0.0 1.0 21\n";
}
close(OUT);
return 1;
}
sub MakeLD01File
{
my ($this, $Crystal, $Function, $LD01Path) = @_;
#空間群ファイルを作る FILE01.DAT
return 0 unless(open(OUT,">$LD01Path"));
my $SPG = $Crystal->GetCSpaceGroup();
my $SPGName = $Crystal->SPGName();
$SPGName =~ s/[\s']//g;
print OUT "$SPGName\n";
my @SymmetryOperation = $SPG->ExpandSymmetryOperation();
my $nSymmetryOperation = @SymmetryOperation;
print OUT "0 1 $nSymmetryOperation\n";
print OUT " 0.0000 0.0000 0.0000\n";
for(my $i = 0 ; $i < $nSymmetryOperation ; $i++) {
my $SymOp = $SymmetryOperation[$i];
Utils::DelSpace($SymOp);
my @SymOpXYZ = split(/,\s*/, $SymOp);
my @XMatrix = SpaceGroup::SymOpToMatrix($SymOpXYZ[0]);
my @YMatrix = SpaceGroup::SymOpToMatrix($SymOpXYZ[1]);
my @ZMatrix = SpaceGroup::SymOpToMatrix($SymOpXYZ[2]);
printf OUT "%7.4f %7.4f %7.4f %7.4f %7.4f %7.4f "
."%7.4f %7.4f %7.4f\n",
$XMatrix[0], $XMatrix[1], $XMatrix[2],
$YMatrix[0], $YMatrix[1], $YMatrix[2],
$ZMatrix[0], $ZMatrix[1], $ZMatrix[2];
printf OUT "%7.4f %7.4f %7.4f\n",
eval($XMatrix[3]), eval($YMatrix[3]),
eval($ZMatrix[3]);
}
print OUT "\n";
close(OUT);
return 1;
}
sub MakeLD02File
{
my ($this, $Crystal, $Function, $LD02Path, $pModifiedParams) = @_;
#原子ファイルを作る FILE02.DAT
return 0 unless(open(OUT,">$LD02Path"));
my @AtomTypeList = $Crystal->GetCAtomTypeList();
my $nAtomType = @AtomTypeList;
print OUT "$nAtomType\n";
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $atomname = $atom->AtomNameOnly();
my $charge0 = $atom->Charge();
my ($zc, $sign) = ($charge0 =~ /([\d\.]+)([+\-])/);
if($sign eq '-') {
$charge0 = -$zc;
}
my ($Mass, $charge, $ai, $bi, $ci, $rad)
= $this->GetBusingParameter($atomname);
$Mass = AtomType::GetAtomInformationByKey($atomname, "原子量")
if($Mass eq '');
$Mass =~ s/\(.*?\)//g;
$charge = $charge0 if($charge0 ne '');
$ai = 0.9 if($ai == 0);
$bi = 0.08 if($bi == 0);
$ci = 0.0 if($ci eq '');
my $iMP;
if($pModifiedParams) {
for(my $j = 0 ; $j < @$pModifiedParams ; $j++) {
if($atomname eq $pModifiedParams->[$j]{Name}) {
$iMP = $j;
last;
}
}
#print "$atomname => index of Bader charge atom: $iMP\n";
}
if(defined $iMP) {
my $p = $pModifiedParams->[$iMP];
if(defined $p->{Charge}) {
$charge = $p->{Charge};
}
if(defined $p->{ai}) {
$ai = $p->{ai};
}
if(defined $p->{bi}) {
$bi = $p->{bi};
}
if(defined $p->{ci}) {
$ci = $p->{ci};
}
if(defined $p->{rad}) {
$rad = $p->{rad};
}
}
print "$atomname\n";
print OUT "$atomname\n";
printf "%8.4f %8.4f %9.6f %9.6f %9.6f\n", eval($Mass), $charge, $ai, $bi, $ci;
printf OUT "%8.4f %8.4f %9.6f %9.6f %9.6f\n", eval($Mass), $charge, $ai, $bi, $ci;
}
#Aij, Bij, Cij and Morse, Shell parameters
for(my $i = 1 ; $i <= $nAtomType ; $i++) {
for(my $j = $i ; $j <= $nAtomType ; $j++) {
print OUT " 0.0 0.0 0.000000E+00 0.000000E+00 0.020000E+00 0.000000E+00 0.0e0\n";
}
}
#ai, bi IDs
for(my $i = 0 ; $i < $nAtomType ; $i++) {
print OUT " 1 0\n";
}
#Spring constants
print OUT "2\n";
print OUT " 2.200 3.400 4.200 4.300\n";
for(my $i = 1 ; $i <= $nAtomType ; $i++) {
for(my $j = $i ; $j <= $nAtomType ; $j++) {
print OUT "8.6e-19 1.6e-19 0.0e-19\n";
}
}
print OUT "\n";
close(OUT);
return 1;
}
sub MakeLD07File
{
my ($this, $Crystal, $Function, $LD07Path, $EWALD, $EPS) = @_;
#結晶構造ファイルを作る FILE07.DAT
unless(open(OUT,">$LD07Path")) {
print "Can't write to $LD07Path.$LF$LF";
return;
}
print OUT "1\n";
my $SampleName = $this->SampleName();
print OUT "$SampleName\n";
my ($a,$b,$c,$alpha,$beta,$gamma)
= $Crystal->LatticeParametersByOutputMode(0);
printf OUT " %9.4f %9.4f %9.4f %9.4f %9.4f %9.4f\n",
$a, $b, $c, $alpha, $beta, $gamma;
my $SPG = $Crystal->GetCSpaceGroup();
my $SPGName = $SPG->SPGName();
$SPGName =~ s/\s//g;
print OUT "$SPGName\n";
my @AsymmetricAtomSiteList = $Crystal->GetCAsymmetricAtomSiteList();
my $nAsymmetricAtomSite = @AsymmetricAtomSiteList;
print OUT "$nAsymmetricAtomSite\n";
# my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode();
# my $nExpandedAtomSite = @ExpandedAtomSiteList;
# print OUT "$nExpandedAtomSite\n";
for(my $i = 0 ; $i < $nAsymmetricAtomSite ; $i++) {
# for(my $i = 0 ; $i < $nExpandedAtomSite ; $i++) {
# my $atom = $ExpandedAtomSiteList[$i];
my $atom = $AsymmetricAtomSiteList[$i];
my $atomname = $atom->AtomNameOnly();
my $iAtom = $Crystal->FindiAtomType($atomname);
# my $charge = $atom->Charge();
my ($x,$y,$z) = $atom->Position(1);
my $occupancy = $atom->Occupancy();
# my $mult = $atom->Multiplicity();
# $mult = 1 if($IsExpandCoordinate or $IsChooseRandomly);
printf OUT "%5i %7.4f %7.4f %7.4f %7.4f\n",
$iAtom, $occupancy, $x, $y, $z;
}
# LIDs
print OUT " 1 1 1 0 0 0\n";
#XIDs
for(my $i = 0 ; $i < $nAsymmetricAtomSite ; $i++) {
# for(my $i = 0 ; $i < $nExpandedAtomSite ; $i++) {
print OUT " 1 1 1\n";
}
$EWALD = 0.4 if($EWALD eq '');
$EPS = 1.0e-5 if($EPS eq '');
print OUT "$EWALD\n";
print OUT "0.8 $EPS 1.0E-5\n";
print OUT "1 3.0 1\n";
print OUT " 10 0.100000E-05 1 0\n";
print OUT "\n";
close(OUT);
return 1;
}
1;