#=============================================== # MolecularOrbital #=============================================== package MolecularOrbital; #use Exporter; #@ISA = qw(Exporter); use strict; sub SetSourcePath { my ($this,$p)=@_; return $this->{SourcePath} = $p; } sub SourcePath { return shift->{SourcePath}; } sub SetTitle { my ($this,$t)=@_; return $this->{Title} = $t; } sub Title { return shift->{Title}; } sub SetCrystal { my ($this,$crystal) = @_; return $this->{'Crystal'} = $crystal; } sub Crystal { return shift->{'Crystal'}; } sub SetUHF { my ($this,$f)=@_; return $this->{IsUHF} = $f; } sub UHF { return shift->{IsUHF}; } sub SetnAlphaElectrons { my ($this,$n)=@_; return $this->{nAlphaElectrons} = $n; } sub nAlphaElectrons { return shift->{nAlphaElectrons}; } sub SetnBetaElectrons { my ($this,$n)=@_; return $this->{nBetaElectrons} = $n; } sub nBetaElectrons { return shift->{nBetaElectrons}; } sub SetBase { my ($this,$iOrb,$base)=@_; return $this->{Base}->[$iOrb] = $base; } sub SetWFCoeff { my ($this, $iMO, $ibase, $coeff) = @_; $this->{WFCoeff}->[$iMO] = [] if(!defined $this->{WFCoeff}->[$iMO]); return $this->{WFCoeff}->[$iMO][$ibase] = $coeff; } sub nData { my ($this)=@_; my $a=$this->{Ne}; return scalar @$a; } sub nWF { return shift->nData(); } sub nBase { my $p = shift->{WFCoeff}->[0]; return 0 if(!$p); return scalar @$p; } sub RootNumber { my ($this,$i)=@_; return $this->{RootNumber}->[$i]; } sub Symmetry { my ($this,$i)=@_; return $this->{Symmetry}->[$i]; } sub Energy { my ($this,$i)=@_; return $this->{Energy}->[$i]; } sub Spin { my ($this,$i)=@_; return $this->{Spin}->[$i]; } sub Ne { my ($this,$i)=@_; return $this->{Ne}->[$i]; } sub Base { my ($this,$i)=@_; return $this->{Base}->[$i]; } sub WFCoeff { my ($this,$iMO,$ibase)=@_; return $this->{WFCoeff}->[$iMO][$ibase]; } sub pRootNumber() { return shift->{RootNumber}; } sub pSymmetry { return shift->{Symmetry}; } sub pEnergy { return shift->{Energy}; } sub pNe { return shift->{Ne}; } sub pSpin { return shift->{Spin}; } sub pBase { return shift->{Base}; } sub pWFCoeff { return shift->{WFCoeff}; } sub Unit { return shift->{Unit}; } sub SetUnit { my ($this,$u)=@_; return $this->{Unit} = $u; } sub SetYName { my ($this,$name)=@_; return $this->{YName} = $name; } sub YName { return shift->{YName}; } sub GetYName { return shift->{YName}; } sub GetYMinMax { my $this = shift; return ($this->{YMin}, $this->{YMax}); } sub GetMinMax { my $this = shift; return ($this->{YMin}, $this->{YMax}); } sub nRedMOs { my ($this, $spin) = @_; return $this->nData() if(!defined $spin); my $n = 0; for(my $i = 0 ; $i < $this->nData() ; $i++) { $n++ if($this->Spin($i) == $spin); } return $n; } #============================================================ # コンストラクタ、デストラクタ #============================================================ sub new { my ($module) = @_; my $this = {}; bless $this; $this->{Energy} = []; $this->{RootNumber}= []; $this->{Symmetry} = []; $this->{Spin} = []; $this->{Ne} = []; $this->{Base} = []; $this->{WFCoeff} = []; my $nData = $this->nData(); return $this; } sub DESTROY { my $this = shift; } sub NormalizeWFCoeff { my ($this) = @_; for(my $i = 0 ; $i < $this->nData() ; $i++) { my $C2 = 0.0; for(my $j = 0 ; $j < $this->nBase() ; $j++) { my $c = $this->WFCoeff($i, $j); $C2 += $c * $c; } next if($C2 == 0.0); my $C = sqrt($C2); for(my $j = 0 ; $j < $this->nBase() ; $j++) { my $c = $this->WFCoeff($i, $j); $this->SetWFCoeff($i, $j, $c / $C); } } } sub Add { my ($this, $index, $RootNumber, $symmetry, $e, $ne, $spin) = @_; my $prn = $this->pRootNumber(); my $psym = $this->pSymmetry(); my $pe = $this->pEnergy(); my $pne = $this->pNe(); my $pspin = $this->pSpin(); $prn->[$index] = $RootNumber; $psym->[$index] = $symmetry; $pe->[$index] = $e; $pne->[$index] = $ne; $pspin->[$index] = $spin; #print "[$RootNumber][$symmetry][$e][$ne][$spin]\n"; return $this->nData(); } sub CalYMinMax { my ($this) = @_; my $pe = $this->pEnergy(); return unless($pe); my $nData = $this->nData(); return if($nData <= 0); my $min = $pe->[0]; my $max = $min; for(my $i = 1 ; $i < $nData ; $i++) { $min = $pe->[$i] if($min > $pe->[$i]); $max = $pe->[$i] if($max < $pe->[$i]); } $this->{YMin} = $min; $this->{YMax} = $max; return ($min, $max); } sub CalMinMax { my ($this) = @_; $this->CalYMinMax(); return 1; } 1;