) {
my ($name, $mass, $charge, $ai, $bi, $ci, $rad)
= split(/\s+/, $_);
if(uc $name eq uc $atomname) {
return ($mass, $charge, $ai, $bi, $ci, $rad);
}
}
close(IN);
return ('');
}
sub SetnExpandCells
{
my ($this, $nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC) = @_;
$this->{'nExpandLatticeA'} = $nExpandLatticeA;
$this->{'nExpandLatticeB'} = $nExpandLatticeB;
$this->{'nExpandLatticeC'} = $nExpandLatticeC;
return ($this->{'nExpandLatticeA'}, $this->{'nExpandLatticeB'},
$this->{'nExpandLatticeC'});
}
sub nExpandCells
{
my ($this) = @_;
return ($this->{'nExpandLatticeA'}, $this->{'nExpandLatticeB'},
$this->{'nExpandLatticeC'});
}
sub MakeMXDFiles
{
my ($this, $Crystal, $MXDFunction,
$fname05, $fname07, $fname10, $Version, $IsChooseRandomly) = @_;
if(!defined $IsChooseRandomly) {
$IsChooseRandomly = $Version;
$Version = 1.0;
}
$Version = 2.0 if(!defined $Version);
my $LF = "
\n";
my $ret = $this->MakeFILE05($Crystal, $MXDFunction, $fname05, $IsChooseRandomly);
return $ret if($ret <= 0);
$ret = $this->MakeFILE07($Crystal, $MXDFunction, $fname07, $Version, $IsChooseRandomly);
return $ret if($ret <= 0);
if($MXDFunction =~ /^XD/i) {
$ret = $this->MakeFILE10($Crystal, $MXDFunction, $fname10, $IsChooseRandomly);
return $ret if($ret <= 0);
}
return 1;
}
sub MakeFILE05
{
my ($this, $Crystal, $MXDFunction, $fname05, $IsChooseRandomly) = @_;
my $LF = "
\n";
unless(open(OUT,">$fname05")) {
print "Can not write to $fname05.$LF$LF";
return -1;
}
my $SampleName = $this->SampleName();
my $mode = "XD";
$mode = "MD" if($MXDFunction =~ /^MD/i);
printf OUT "%2s.......I....:....I....:....I....:....I....:....I....:....I....:....I:\n",
$mode;
print OUT "START $SampleName\n";
print OUT "NORMAL 01000. 0100. 50. 5. 5. :\n";
print OUT "NOACCUM 2.0 1.0 0.0 :\n";
print OUT "T SCALING 300.00 1.0 10. :\n";
print OUT "P SCALING 0.0001 0.0001 0.0001 :\n";
print OUT "V :\n";
print OUT "BUSING 3. 0.0 :\n";
my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode();
my $nExpandedAtomSite = @ExpandedAtomSiteList;
my @atomlist = $Crystal->GetCAtomTypeList();
my %AtomCount;
for(my $i = 0 ; $i < $nExpandedAtomSite ; $i++) {
my $atom = $ExpandedAtomSiteList[$i];
my $atomname = $atom->AtomNameOnly();
$AtomCount{$atomname}++;
}
my $count =0;
for(my $i = 0 ; $i < @atomlist ; $i++) {
my $atom = $atomlist[$i];
my $atomname = $atom->AtomNameOnly();
# my $charge = $atom->Charge();
$count++;
my ($Mass, $charge, $ai, $bi, $ci, $rad)
= $this->GetBusingParameter($atomname);
$Mass = AtomType::GetAtomInformationByKey($atomname, "原子量")
if($Mass eq '');
printf OUT "%1d %-2s%5d. %6.3f %7.2f %9.4f %9.4f %9.4f :\n",
$count, $atomname, $AtomCount{$atomname}, $charge, $Mass, $ai, $bi, $ci;
}
print OUT " :\n";
print OUT " :\n";
printf OUT "%2s.......I....:....I....:....I....:....I....:....I....:....I....:....I:\n",
$mode;
print OUT "STOP :\n";
print OUT "\n";
close(OUT);
return 1;
}
sub MakeFILE07
{
my ($this, $Crystal, $MXDFunction,
$fname07, $Version, $IsChooseRandomly) = @_;
if(!defined $IsChooseRandomly) {
$IsChooseRandomly = $Version;
$Version = 1.0;
}
$Version = 2.0 if(!defined $Version);
my $LF = "
\n";
my $SampleName = $this->SampleName();
my ($a,$b,$c,$alpha,$beta,$gamma)
= $Crystal->LatticeParametersByOutputMode(0);
my @AtomTypeList = $Crystal->GetCAtomTypeList();
my $nAtomType = @AtomTypeList;
my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode();
my $nExpandedAtomSite = @ExpandedAtomSiteList;
unless(open(OUT,">$fname07")) {
print "Can not write to $fname07.$LF$LF";
return -1;
}
printf OUT "%-60s%5d%5d\n", $SampleName, 0, 0;
printf OUT " %6d%3d 0 0 0 0 0 1 0 0 0\n",
$nExpandedAtomSite, $nAtomType;
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $atomname = $atom->AtomNameOnly();
printf OUT " %-4s", $atomname;
}
print OUT "\n";
my %AtomCount;
for(my $i = 0 ; $i < $nExpandedAtomSite ; $i++) {
my $atom = $ExpandedAtomSiteList[$i];
my $atomname = $atom->AtomNameOnly();
$AtomCount{$atomname}++;
}
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $atomname = $atom->AtomNameOnly();
printf OUT "%6d", $AtomCount{$atomname};
}
print OUT "\n";
my $CurPos = 1;
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $atomname = $atom->AtomNameOnly();
printf OUT "%6d", $CurPos;
$CurPos += $AtomCount{$atomname};
}
print OUT "\n";
my $EndPos = 0;
my %iAtom;
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $atomname = $atom->AtomNameOnly();
$iAtom{$atomname} = $i+1;
$EndPos += $AtomCount{$atomname};
printf OUT "%6d", $EndPos;
}
print OUT "\n";
printf OUT " 300.00 1.0000 300.00 0.00010 0.00010 0.00010\n";
printf OUT " 0.200E-14 %10.6f%10.6f%10.6f 0.000000 0.000000 0.000000\n",
$a, $b, $c;
printf OUT "%10.6f 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000\n",
$Crystal->Density();
for(my $it = 0 ; $it < $nAtomType ; $it++) {
my $atomtype = $AtomTypeList[$it];
my $atomtypename = $atomtype->AtomNameOnly();
for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) {
my $atom = $ExpandedAtomSiteList[$i];
my $atomname = $atom->AtomNameOnly();
next if(uc $atomname ne uc $atomtypename);
my ($x,$y,$z) = $atom->Position(1);
if($Version >= 2.0) {
printf OUT "%10.8f%10.8f%10.8f %9.7f%9.7f%9.7f %8.6f %8.6f %8.6f%3d\n",
$x, $y, $z, 0, 0, 0, $x, $y, $z, $iAtom{$atomname};
}
else {
printf OUT "%9.7f%9.7f%9.7f %8.6f%8.6f%8.6f %9.6f%9.6f%9.6f\n",
$x, $y, $z, 0, 0, 0, $x, $y, $z;
}
}
}
print OUT " 800 300 0 940608\n";
close(OUT);
return 1;
}
sub MakeFILE10
{
my ($this, $Crystal, $MXDFunction,
$fname10, $IsChooseRandomly) = @_;
my $LF = "
\n";
#print "Error: MD is not supported.
\n";
#return -1;
my ($nx, $ny, $nz ) = $this->nExpandCells();
my ($a,$b,$c,$alpha,$beta,$gamma)
= $Crystal->LatticeParametersByOutputMode(0);
my @AtomTypeList = $Crystal->GetCAtomTypeList();
my $nAtomType = @AtomTypeList;
my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode();
my $nExpandedAtomSite = @ExpandedAtomSiteList;
my $SPG = $Crystal->GetCSpaceGroup();
my $nSymmetry = 1; #$SPG->nSymmetryOperation();
unless(open(OUT,">$fname10")) {
print "Can not write to $fname10.$LF$LF";
return -1;
}
printf OUT "%10.7f%10.7f%10.7f%10.8f%10.8f%10.8f\n",
$a, $b, $c, $alpha, $beta, $gamma;
printf OUT "%5d%5d%5d%5d%5d%5d%4s %6d\n",
$nx, $ny, $nz, $nExpandedAtomSite, $nExpandedAtomSite,
$nSymmetry, ' ', $nAtomType;
my %AtomCount;
for(my $i = 0 ; $i < $nExpandedAtomSite ; $i++) {
my $atom = $ExpandedAtomSiteList[$i];
my $atomname = $atom->AtomNameOnly();
$AtomCount{$atomname}++;
}
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $atomname = $atom->AtomNameOnly();
printf OUT "%-4s", $atomname;
print OUT "\n" if(($i+1) % 18 == 0);
}
print OUT "\n" if($nAtomType % 18 != 0);
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $atomname = $atom->AtomNameOnly();
printf OUT "%4d", $AtomCount{$atomname};
print OUT "\n" if(($i+1) % 18 == 0);
}
print OUT "\n" if($nAtomType % 18 != 0);
for(my $it = 0 ; $it < $nAtomType ; $it++) {
my $atomtype = $AtomTypeList[$it];
my $atomtypename = $atomtype->AtomNameOnly();
for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) {
my $atom = $ExpandedAtomSiteList[$i];
my $atomname = $atom->AtomNameOnly();
next if(uc $atomname ne uc $atomtypename);
my ($x,$y,$z) = $atom->Position(1);
printf OUT "%5d%10.7f%10.7f%10.7f\n",
1, $x, $y, $z, 0, 0, 0, $x, $y, $z;
# $it+1, $x, $y, $z, 0, 0, 0, $x, $y, $z;
}
}
print OUT " 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0\n";
for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) {
printf OUT "%6d", $i*200 + 1;
print OUT "\n" if(($i+1) % 12 == 0);
}
print OUT "\n" if($nExpandedAtomSite % 12 != 0);
print OUT " \n";
close(OUT);
return 1;
}
sub MakeXTALDATA
{
my ($this, $Crystal, $Function, $WorkingDirectory, $FilePrefix) = @_;
my $LF = "
\n";
my $SampleName = $this->SampleName();
my ($a,$b,$c,$alpha,$beta,$gamma)
= $Crystal->LatticeParameters();
my @AtomTypeList = $Crystal->GetCAtomTypeList();
my $nAtomType = @AtomTypeList;
my @AsymmetricAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode();
my $nAsymmetricAtomSite = @AsymmetricAtomSiteList;
# my $SPG = "P 1"; #$Crystal->GetCSpaceGroup();
# my $nSymmetry = 1; #$SPG->nSymmetryOperation();
my $FileXTALDATA = Deps::MakePath($WorkingDirectory, "XTALDATA.DAT", 0);
my $MXDInputFile = Deps::MakePath($WorkingDirectory, "MXDInput.in", 0);
my $MXDInputOutFile = Deps::MakePath($WorkingDirectory, "MXDInput.out", 0);
my $MXDFile05File = Deps::MakePath($WorkingDirectory, "FILE05.dat", 0);
my $MXDFile06File = Deps::MakePath($WorkingDirectory, "FILE06.dat", 0);
my $MXDFile07File = Deps::MakePath($WorkingDirectory, "FILE07.dat", 0);
my $MXDFile10File = Deps::MakePath($WorkingDirectory, "FILE10.dat", 0);
my $MXDf05File = Deps::MakePath($WorkingDirectory, "$FilePrefix.f05", 0);
my $MXDf07File = Deps::MakePath($WorkingDirectory, "$FilePrefix.f07", 0);
my $MXDf10File = Deps::MakePath($WorkingDirectory, "$FilePrefix.f10", 0);
print "[$FileXTALDATA] was deleted.$LF" if(unlink($FileXTALDATA));
print "[$MXDInputFile] was deleted.$LF" if(unlink($MXDInputFile));
print "[$MXDInputOutFile] was deleted.$LF" if(unlink($MXDInputOutFile));
print "[$MXDFile05File] was deleted.$LF" if(unlink($MXDFile05File));
print "[$MXDFile06File] was deleted.$LF" if(unlink($MXDFile06File));
print "[$MXDFile07File] was deleted.$LF" if(unlink($MXDFile07File));
print "[$MXDFile10File] was deleted.$LF" if(unlink($MXDFile10File));
print "[$MXDf05File] was deleted.$LF" if(unlink($MXDf05File));
print "[$MXDf07File] was deleted.$LF" if(unlink($MXDf07File));
print "[$MXDf10File] was deleted.$LF" if(unlink($MXDf10File));
print "$LF";
print "Create XTALDATA.DATA [$FileXTALDATA]$LF";
unless(open(OUT,">$FileXTALDATA")) {
print "Can not write to $FileXTALDATA.$LF$LF";
return (-1);
}
print OUT ':"""""""""""""""""""""""""""""""""""""""""""""""""""""""""":', "\n";
print OUT ": CRYSTAL DATA BASE CREATED BY MXD.pm (C) T. Kamiya :\n";
print OUT ":..........................................................:\n";
print OUT ": :\n";
print OUT "----:----I----:----I----:----I----:----I----:----I----:----I\n";
print OUT "...................I \n";
my $ShortSampleName = $SampleName;
$ShortSampleName =~ s/^\s+//;
$ShortSampleName =~ s/\s.*$//;
$ShortSampleName = substr($ShortSampleName, 0, 18);
printf OUT "%-19sI----:----I----:----I----:----I----:----I\n", $ShortSampleName;
print OUT "$SampleName\n";
printf OUT "%8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n",
$a, $b, $c, $alpha, $beta, $gamma;
my $nCation = 0;
my $nAnion = 0;
for(my $i = 0 ; $i < $nAsymmetricAtomSite ; $i++) {
my $atom = $AsymmetricAtomSiteList[$i];
my $charge = $atom->Charge();
if($charge =~ /-/) {
$nAnion++;
}
else {
$nCation++;
}
}
# my $SPGName = $SPG->SPGName();
# $SPGName =~ s/\s//g;
# my @SymmetryOperation = ('x,y,z'); #$SPG->ExpandSymmetryOperation();
# my $nSymmetryOperation = 1; #@SymmetryOperation;
# printf OUT "%-10s %4d %d %4d %4d\n", $SPGName, $nSymmetry, 0, $nCation, $nAnion;
printf OUT "%-10s %4d %d %4d %4d\n", "P1", 1, 0, $nCation, $nAnion;
printf OUT "%02d%02d%02d%2d%2d%2d%2d%2d%2d%2d%2d%2d\n",
0, 0, 0,
1, 0, 0,
0, 1, 0,
0, 0, 1;
my %AtomCount;
for(my $i = 0 ; $i < $nAsymmetricAtomSite ; $i++) {
my $atom = $AsymmetricAtomSiteList[$i];
my $name = uc $atom->AtomNameOnly();
# $name = sprintf "%2s", $name;
my $charge = $atom->Charge();
$charge = - ($charge + 0) if($charge =~ /-/);
my ($x,$y,$z) = $atom->Position();
my $iAtomType = $Crystal->FindiAtomType($name);
$AtomCount{$name}++;
# 1020 FORMAT (A4,1X, I5, F10.5,3F10.5, 3I5)
printf OUT "%-4s %5d%10.5f%10.5f%10.5f%10.5f\n",
"$name" . $AtomCount{$name}, $iAtomType, abs($charge), $x, $y, $z;
}
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $name = uc $atom->AtomNameOnly();
$name = sprintf "%2s", $name;
printf OUT "%-5s", $name;
}
print OUT "\n";
print OUT "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n";
close(OUT);
print "Change working directory to [$WorkingDirectory]$LF";
unless(chdir($WorkingDirectory)) {
print "Error in MXD.pm::MakeXTALDATA: "
."Could not change to [$WorkingDirectory]$LF";
my $dir = cwd();
print "+++ Current working directory is [$dir].$LF";
return (-1);
}
print "Create MXDInput.in [$MXDInputFile]$LF";
unless(open(OUTI,">$MXDInputFile")) {
print "Can not write to $MXDInputFile.$LF$LF";
return (-1);
}
print "Execute MXDInput [$MXDInputPath]$LF";
print "\n";
no strict;
my $pid = open2(IN, OUT, $MXDInputPath);
use strict;
unless(open(OUT2,">$MXDInputOutFile")) {
print "Can not write to $MXDInputOutFile.$LF$LF";
close(IN);
close(OUT);
return (-1);
}
# print "lat: ", $Crystal->LatticeSystem(), "
";
# print "lat: $a $b $c $alpha $beta $gamma
";
print OUTI "$ShortSampleName\n";
print OUT "$ShortSampleName\n";
if($Crystal->LatticeSystem() eq 'hexagonal' or
($Crystal->LatticeSystem() eq 'rhombohedral' and
abs($alpha-90.0) < 0.1 and abs($beta-90.0) < 0.1 and
abs($gamma-120.0) <0.1) ) {
print "This crystal has a hexagonal cell.\n";
print "The hexagonal cell was converted to the orthorhombic cell.\n";
print OUTI "y\n";
print OUT "y\n";
}
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $name = uc $atom->AtomNameOnly();
$name = sprintf "%2s", $name;
printf OUT "%-5s", $name;
printf OUTI "%-5s", $name;
#CA O TI
#123451234512345
}
print OUT "\n";
print OUTI "\n";
my ($nx,$ny,$nz) = $this->nExpandCells();
printf OUT "%5d%5d%5d\n", $nx, $ny, $nz;
printf OUTI "%5d%5d%5d\n", $nx, $ny, $nz;
print OUT "\n";
print OUTI "\n";
printf OUT " %7.2f\n", 300.0;
printf OUTI " %7.2f\n", 300.0;
print OUT "y\n";
print OUTI "y\n";
print OUT "\n\n";
print OUTI "\n\n";
close(OUTI);
close(OUT);
while() {
# print "$_$LF";
print OUT2 "$_\n";
}
close(IN);
close(OUT2);
#Convert FILE05 to .f05
unless(open(IN2,"<$MXDFile05File")) {
print "Can not read [$MXDFile05File].$LF$LF";
return (-1);
}
unless(open(OUT2,">$MXDf05File")) {
print "Can not write to [$MXDf05File].$LF$LF";
return (-1);
}
#XD.......I....:....I....:....I....:....I....:....I....:....I....:....I:
my $line = ;
$line =~ s/^XD/MD/ if($Function =~ /^MD/i);
print OUT2 $line;
#START IGZOm1 (1 x 1 x 1) :
$line = ;
print OUT2 $line;
#ECONOMY 00500. 0500. 50. 5. 5. :
$line = ;
$line =~ s/^ECONOMY/NORMAL /;
$line =~ s/00500/05000/;
print OUT2 $line;
#NOACCUM 2.00 1.0 0.0 :
$line = ;
print OUT2 $line;
#T SCALING 300.00 -0.1 1. :
$line = ;
print OUT2 $line;
#P NO-CNTL 0.0001 0.0001 0.0001 :
$line = ;
$line =~ s/^P NO-CNTL/P SCALING/;
print OUT2 $line;
#V CONST. :
$line = ;
$line =~ s/^V CONST. /V /;
print OUT2 $line;
#BUSING 3. 0.0 :
$line = ;
print OUT2 $line;
for(my $i = 0 ; $i < $nAtomType ; $i++) {
#1 GA 12. 3.000 69.72 0.000 0.000 0.000 :
$line = ;
my ($sn, $name, $count) = ($line =~ /^\s*(\d+)\s+(\S+)\s+(\S+)/);
#print "line: $line
";
#print "sn: $sn, $name, $count
";
my $iAtom = $Crystal->FindiAtomType($name);
my $atom = $AtomTypeList[$iAtom-1];
my ($Mass, $charge, $ai, $bi, $ci, $rad)
= $this->GetBusingParameter($name);
$charge = $atom->Charge() if($charge eq '');
$Mass = AtomType::GetAtomInformationByKey($name, "原子量")
if($Mass eq '');
printf OUT2 "%1d %-2s%5d. %6.3f %7.2f %9.4f %9.4f %9.4f :\n",
$sn, $name, $count, $charge, $Mass, $ai, $bi, $ci;
}
# :
$line = ;
print OUT2 $line;
$line = ;
print OUT2 $line;
#XD.......I....:....I....:....I....:....I....:....I....:....I....:....I:
$line = ;
$line =~ s/^XD/MD/ if($Function =~ /^MD/i);
print OUT2 $line;
#STOP :
$line = ;
print OUT2 $line;
close(IN2);
close(OUT2);
use strict;
print "
\n";
$MXDFile07File = $MXDf07File if(rename($MXDFile07File, $MXDf07File));
$MXDFile10File = $MXDf10File if(rename($MXDFile10File, $MXDf10File));
return ($FileXTALDATA, $MXDInputFile, $MXDInputOutFile,
$MXDf05File, $MXDFile06File, $MXDFile07File, $MXDFile10File);
}
sub UijWithParams
{
my ($this, $r, $Zi, $ai, $bi, $ci, $Zj, $aj, $bj, $cj) = @_;
my $KZ = $K0 * $Zi * $Zj;
my $Aij = $ai + $aj;
my $Bij = $bi + $bj;
my $KA = $F0 * $Bij * exp($Aij / $Bij);
my $Uij = $KZ / $r + $KA * exp(-$r / $Bij);
return $Uij;
}
sub dUijdrWithParams
{
my ($this, $r, $Zi, $ai, $bi, $ci, $Zj, $aj, $bj, $cj) = @_;
my $KZ = $K0 * $Zi * $Zj;
my $Aij = $ai + $aj;
my $Bij = $bi + $bj;
my $KA = $F0 * $Bij * exp($Aij / $Bij);
my $dUijdr = -$KZ / ($r*$r) - $KA / $Bij * exp(-$r / $Bij);
return $dUijdr;
}
1;