#===============================================
# DVXa
#===============================================
package DVXa;
use Exporter;
@ISA = qw(Exporter);
#公開したいサブルーチン
@EXPORT = qw();
use strict;
use JFile;
use Deps;
#===============================================
# パス(読み込みDB)
# Web関係変数
# CGI の仮想パス
# プログラム名
#===============================================
my $WebRootDir = "d:\\MyWebs";
my $CGIPath = Deps::MakePath($WebRootDir, "cgi-bin", 1);
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);
#===============================================
# 静的メンバー関数
#===============================================
sub ModifyIonOccupancy
{
my ($pOrbitals, $charge) = @_;
return $pOrbitals if($charge == 0);
my $nOrbitals = @$pOrbitals;
if($charge < 0) {
for(my $j = 0 ; $j < $nOrbitals ; $j++) {
my $pOrb = $pOrbitals->[$j];
my $n = $pOrb->{'n'};
my $l = $pOrb->{'l'};
my $Ne = $pOrb->{'Ne'};
#print "charge=$charge n=$n l=$l Ne=$Ne
\n";
my $dNe = 0;
if($l == 0 and $Ne < 2) {
$dNe = 2 - $Ne;
}
elsif($l == 1 and $Ne < 6) {
$dNe = 6 - $Ne;
}
elsif($l == 2 and $Ne < 10) {
$dNe = 10 - $Ne;
}
elsif($l == 3 and $Ne < 14) {
$dNe = 14 - $Ne;
}
if(abs($charge) >= $dNe) {
$pOrb->{'Ne'} += $dNe;
$charge += $dNe;
}
else {
$pOrb->{'Ne'} += $charge;
$charge = 0.0;
}
return $pOrb if($charge == 0);
}
}
else {
for(my $j = $nOrbitals-1 ; $j >= 0 ; $j--) {
my $pOrb = $pOrbitals->[$j];
my $n = $pOrb->{'n'};
my $l = $pOrb->{'l'};
my $Ne = $pOrb->{'Ne'};
#print "charge=$charge n=$n l=$l Ne=$Ne
\n";
next if($Ne == 0.0);
if($charge >= $Ne) {
$charge -= $Ne;
$pOrb->{'Ne'} = 0.0;
}
else {
$pOrb->{'Ne'} -= $charge;
$charge = 0.0;
}
return $pOrb if($charge == 0);
}
}
}
#===============================================
# 変数取得関数
#===============================================
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);
return $this->{'NonRelPath'};
}
sub NonRelPath
{
my ($this) = @_;
return $this->{'NonRelPath'};
}
sub FileType { return shift->{'FileType'}; }
sub FileName { return shift->{'FileName'}; }
sub SetFileName { my ($this,$f)=@_; return $this->{'FileName'} = $f; }
sub SetSampleName
{
my ($this, $name) = @_;
return $this->{'SampleName'} = $name;
}
sub SampleName
{
my ($this) = @_;
return $this->{'SampleName'};
}
sub ClearAll { my $this=shift; undef $this->{'DataArray'}; }
sub DataArray { return shift->{'DataArray'}; }
sub SetDataArray
{
my ($this, $DataArray) = @_;
return $this->{'DataArray'} = $DataArray;
}
#===============================================
# コンストラクタ、デストラクタ
#===============================================
BEGIN {
}
sub new
{
my ($module) = @_;
my $this = {};
bless $this;
return $this;
}
sub DESTROY
{
my $this = shift;
}
#===============================================
# 一般関数
#===============================================
sub CheckFileType
{
my ($path) = @_;
my ($drive, $dir, $filename, $ext, $lastdir, $filebody)
= Deps::SplitFilePath($path);
#print "Path: $path\n";
if($filename =~ /^[a-zA-Z]07$/) {
my $infile = new JFile;
my $ret = $infile->Open($path, "r");
return undef unless($ret);
my $IsGPGL = 1;
for(my $i = 0 ; $i < 10 ; $i++) {
my $line = $infile->ReadLine();
last unless(defined $line);
Utils::DelSpace($line);
next if($line =~ /^[DHMQSPJLBIX]/);
$IsGPGL = 0;
last;
}
$infile->Close();
return "DVXa GPGL File" if($IsGPGL);
}
if($ext =~ /^F05$/i) {
return "DVXa Input File";
}
elsif($ext =~ /^F01$/i) {
return "DVXa raw Input File";
}
elsif($ext =~ /^F03$/i) {
return "DVXa Madelung potential File";
}
return undef;
}
sub Read
{
my ($this, $filename) = @_;
$this->ClearAll();
my $FileType = $this->{'FileType'} = DVXa::CheckFileType($filename);
$this->SetFileName($filename);
if($FileType eq "DVXa GPGL File") {
return 1;
}
return undef
}
sub ReadOrbitals
{
my ($this, $atomname) = @_;
my $HartreeToeV = Sci::HartreeToeV();
print "HartreeToeV: $HartreeToeV
\n";
my $NonRelPath = $this->NonRelPath();
#print "NonRelPath: $NonRelPath
\n";
my $in = new JFile($NonRelPath, "r");
if(!$in) {
#print "Can not read [$NonRelPath]
\n";
return undef;
}
my $nOrbitals = 0;
my $AtomicNumber = 0;
my @Orbitals;
while(!$in->eof()) {
my $line = $in->ReadLine();
#print "line: $line
\n";
my ($head) = ($line =~ /^\s*(\w+)\W/);
#print "head: $head
\n";
if(uc $head eq uc $atomname) {
#print "head: $head
\n";
$line = $in->ReadLine();
my ($nn, $nMesh, $no)
= ($line =~ /^\s*(\d+)\s+(\d+)\s+(\d+)/);
$nOrbitals = $no;
#print "nOrbitals: $nOrbitals
\n";
$line = $in->ReadLine();
#print "line: $line
\n";
($AtomicNumber) = ($line =~ /^\s*(\w+)\W/);
#print "AtomicNumber: $AtomicNumber
\n";
for(my $i = 0 ; $i < $nOrbitals ; $i++) {
$line = $in->ReadLine();
my ($n, $l, $m, $energy, $Ne)
= Utils::Split("\\s+", $line);
#print "nlm e ne=$n $l $m, $energy, $Ne
\n";
my %o;
$o{'n'} = $n;
$o{'l'} = $l;
$o{'Energy'} = $energy * $HartreeToeV; #eV
$o{'Ne'} = $Ne;
push(@Orbitals, \%o);
}
last;
}
}
$in->Close();
return ($nOrbitals, $AtomicNumber, @Orbitals);
}
1;