package VASP; use Exporter; @ISA = qw(Exporter); #公開したいサブルーチン @EXPORT = qw(); #use lib "d:/Programs/Perl/lib"; use strict; use File::Basename; use Cwd; use ProgVars; use Utils; use GraphData; use Sci::Science; use Sci::EnergyBandArray; #use MyTk::GraphFrameArray; use Crystal::Crystal; use Crystal::AtomType; use Crystal::AtomSite; use Crystal::XCrySDen; use Crystal::CIF; use Crystal::BandStructure; use Sci qw($e $me $pi $kB $h $hbar $KToeV $JToeV erfc); use Sci::ChemicalReaction; #=============================================== # スクリプト大域変数 #=============================================== my $LF = "
\n"; my $DirectorySeparator = Deps::DirectorySeparator(); #"\\"; # 擬ポテンシャル、PAWポテンシャルの優先順位 my %PPPriority; $PPPriority{B} = [qw(B B_h B_s)]; $PPPriority{C} = [qw(C C_h C_s)]; $PPPriority{N} = [qw(N N_h N_s)]; $PPPriority{O} = [qw(O O_h O_s)]; $PPPriority{F} = [qw(F F_h F_s)]; #$PPPriority{Ne} = [qw(Ne)]; $PPPriority{H} = [qw(H H_h)]; $PPPriority{Li} = [qw(Li_sv Li)]; $PPPriority{Be} = [qw(Be Be_sv)]; $PPPriority{Na} = [qw(Na_pv Na Na_sv)]; $PPPriority{K} = [qw(K_sv K_pv)]; $PPPriority{Ca} = [qw(Ca_pv Ca_sv)]; $PPPriority{Rb} = [qw(Rb_sv Rb_pv)]; #$PPPriority{Sr} = [qw(Sr_sv)]; #$PPPriority{Cs} = [qw(Cs_sv)]; #$PPPriority{Ba} = [qw(Ba_sv)]; $PPPriority{Sc} = [qw(Sc_sv Sc)]; $PPPriority{Ti} = [qw(Ti_pv Ti Ti_sv)]; $PPPriority{V} = [qw(V_pv V V_sv)]; $PPPriority{Cr} = [qw(Cr_pv Cr Cr_sv)]; $PPPriority{Mn} = [qw(Mn_pv Mn Mn_sv)]; #$PPPriority{Y} = [qw(Y_sv)]; $PPPriority{Zr} = [qw(Zr_sv Zr)]; #$PPPriority{Nb} = [qw(Nb_pv)]; $PPPriority{Mo} = [qw(Mo_pv Mo)]; $PPPriority{Tc} = [qw(Tc_pv Tc)]; $PPPriority{Hf} = [qw(Hf_pv Hf)]; $PPPriority{Ta} = [qw(Ta_pv Ta)]; $PPPriority{W} = [qw(W_pv W)]; $PPPriority{Re} = [qw(Re Re_pv)]; $PPPriority{Fe} = [qw(Fe Fe_pv Fe_sv)]; $PPPriority{Co} = [qw(Co Co_pv)]; $PPPriority{Ni} = [qw(Ni Ni_pv)]; $PPPriority{Cu} = [qw(Cu Cu_pv)]; #$PPPriority{Zn} = [qw(Zn)]; $PPPriority{Ru} = [qw(Ru Ru_pv)]; $PPPriority{Rh} = [qw(Rh Rh_pv)]; $PPPriority{Pd} = [qw(Pd Pd_pv)]; #$PPPriority{Ag} = [qw(Ag)]; #$PPPriority{Cd} = [qw(Cd)]; $PPPriority{Os} = [qw(Os_pv Os)]; #$PPPriority{Ir} = [qw(Ir)]; $PPPriority{Pt} = [qw(Pt Pt_pv)]; #$PPPriority{Au} = [qw(Au)]; #$PPPriority{Hg} = [qw(Hg)]; #$PPPriority{Al} = [qw(Al)]; #$PPPriority{Si} = [qw(Si)]; $PPPriority{P} = [qw(P P_h)]; $PPPriority{S} = [qw(S S_h)]; $PPPriority{Cl} = [qw(Cl Cl_h)]; #$PPPriority{Ar} = [qw(Ar)]; $PPPriority{Ga} = [qw(Ga_d Ga_h Ga)]; $PPPriority{Ge} = [qw(Ge_d Ge_h Ge)]; #$PPPriority{As} = [qw(As)]; #$PPPriority{Se} = [qw(Se)]; #$PPPriority{Br} = [qw(Br)]; #$PPPriority{Kr} = [qw(Kr)]; $PPPriority{In} = [qw(In_d In)]; $PPPriority{Sn} = [qw(Sn_d Sn)]; #$PPPriority{Sb} = [qw(Sb)]; #$PPPriority{Te} = [qw(Te)]; #$PPPriority{I} = [qw(I)]; #$PPPriority{Xe} = [qw(Xe)]; $PPPriority{Tl} = [qw(Tl_d Tl)]; $PPPriority{Pb} = [qw(Pb_d Pb)]; $PPPriority{Bi} = [qw(Bi_d Bi)]; $PPPriority{Po} = [qw(Po_d Po)]; $PPPriority{At} = [qw(At_d At)]; #$PPPriority{Rn} = [qw(Rn)]; $PPPriority{La} = [qw(La La_s)]; $PPPriority{Ce} = [qw(Ce Ce_3)]; $PPPriority{Pr} = [qw(Pr Pr_3)]; $PPPriority{Nd} = [qw(Nd Nd_3)]; $PPPriority{Pm} = [qw(Pm Pm_3)]; $PPPriority{Sm} = [qw(Sm Sm_3)]; $PPPriority{Eu} = [qw(Eu Eu_2)]; $PPPriority{Gd} = [qw(Gd Gd_3)]; $PPPriority{Tb} = [qw(Tb_3)]; $PPPriority{Dy} = [qw(Dy_3)]; $PPPriority{Ho} = [qw(Ho_3)]; $PPPriority{Tm} = [qw(Tm Tm_3)]; $PPPriority{Yb} = [qw(Yb Yb_2)]; $PPPriority{Lu} = [qw(Lu Lu_3)]; $PPPriority{Ac} = [qw(Ac Ac_s)]; $PPPriority{Th} = [qw(Th Th_s)]; $PPPriority{Pa} = [qw(Pa Pa_s)]; $PPPriority{U} = [qw(U U_s)]; $PPPriority{Np} = [qw(Np Np_s)]; $PPPriority{Pu} = [qw(Pu Pu_s)]; $PPPriority{Pa} = [qw(Pa Pa_s)]; #=============================================== # パス(読み込みDB) # Web関係変数 # CGI の仮想パス # プログラム名 #=============================================== my $Program = ProgVars::Program(); my $ProgramDir = ProgVars::ProgramDir(); #my $ProgramOldDir = ProgVars::ProgramOldDir(); my $VASPDir = ProgVars::VASPDir(); #my $VASPProgOldDir = ProgVars::VASPProgOldDir(); my $VASPDBDir = ProgVars::VASPDBDir(); my $WebRootDir = ProgVars::WebRootDir(); my $KListDBDir = ProgVars::KListDBDir(); #============================================================ # 変数等取得、再定義関数 #============================================================ sub ClearAll { my $this=shift; delete $this->{FileType}; delete $this->{DataArray}; } sub FileType { return shift->{'FileType'}; } sub FileName { return shift->{'FileName'}; } sub SetFileName { my ($this,$f)=@_; return $this->{'FileName'} = $f; } #sub DataArray { return shift->{'DataArray'}; } #sub SetDataArray { my ($this, $da) = @_; return $this->{'DataArray'} = $da; } sub SetSampleName { my ($this,$n)=@_; return $this->{'SampleName'} = $n; } sub SampleName { return shift->{'SampleName'}; } 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 GetFileName { my($this, $path, $fname) = @_; my $s; if(-d $path) { $s = $path; } else { my ($drive, $dir, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($path); #print "[$drive] [$dir] [$filename]\n"; if($drive) { $s = Deps::MakePath($drive, $dir); } elsif($dir) { $s = $dir; } else { $s = ''; } } my $path2 = Deps::MakePath($s, $fname); #print "s=$path2\n"; return $path2; } sub GetINCARFileName { my($this,$f)=@_; return $this->GetFileName($f, "INCAR"); } sub GetOUTCARFileName { my($this,$f)=@_; return $this->GetFileName($f, "OUTCAR"); } sub GetKPOINTSFileName { my($this,$f)=@_; return $this->GetFileName($f, "KPOINTS"); } sub GetPOSCARFileName { my($this,$f)=@_; return $this->GetFileName($f, "POSCAR"); } sub GetCONTCARFileName { my($this,$f)=@_; return $this->GetFileName($f, "CONTCAR"); } sub GetPOTCARFileName { my($this,$f)=@_; return $this->GetFileName($f, "POTCAR"); } sub GetEIGENVALFileName { my($this,$f)=@_; return $this->GetFileName($f, "EIGENVAL"); } sub GetDOSCARFileName { my($this,$f)=@_; return $this->GetFileName($f, "DOSCAR"); } sub GetPROCARFileName { my($this,$f)=@_; return $this->GetFileName($f, "PROCAR"); } sub GetCARDir { my($this, $path)=@_; return $path if(-d $path); my ($drive, $dir, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($path); if($drive) { return Deps::MakePath($drive, $dir); } return $dir; } sub SpinPolarized { my ($this,$s) = @_; return $this->{IsSpinPolarized} = $s; } sub IsSpinPolarized { my ($this) = @_; return $this->{IsSpinPolarized} if(defined $this->{IsSpinPolarized}); return 0; } sub IsNonCollinear { my ($this) = @_; my $this->ReadINCARtoHash(); return $this->{IsNonCollinear} if(defined $this->{IsNonCollinear}); return 0; } sub DataArray { my ($this)=@_; return $this->{DataArray}; } sub SetDataArray { my ($this, $da) = @_; if($this->{Application} and $this->{Application}->{MainWindow}) { return $this->mw()->{DataArray} = $this->{DataArray} = $da; } else { return $this->{DataArray} = $da; } } #============================================================ # 継承クラスで定義しなおす関数 #============================================================ sub CheckFileType { my ($path) = @_; my ($drive, $dir, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($path); #print "f: $filename\n"; if($filename =~ /^OUTCAR$/i) { return "VASP Output file"; } if($filename =~ /^DOSCAR$/i) { my $in = new JFile($path, "r"); return undef unless($in); my $IsBig = 1; for(my $i = 0 ; $i < 6 ; $i++) { my $line1 = $in->ReadLine(); if($in->eof()) { $IsBig = 0; last; } } $in->Close(); return "VASP DOSCAR file" if($IsBig); return undef; } if($filename =~ /^EIGENVAL(\..*)?$/i) { return "VASP EIGENVAL file"; } if($filename =~ /\.csv$/i) { #print "f: $filename [$path]\n"; my $in = new JFile($path, "r"); return undef if(!$in); my $line = $in->ReadLine(); # my @a = split(/\s*,\s*/, $line); my @a = Utils::Split("\\s*,\\s*", $line); $in->Close(); return "CSV Band file" if($a[1] =~ /kx/i); return undef; } return undef; } #============================================================ # コンストラクタ、デストラクタ #============================================================ sub new { my ($module) = @_; my $this = {}; bless $this; return $this; } sub DESTROY { my $this = shift; } #============================================================ # ファイル読み込み関数 #============================================================ sub ReadOUTCAR { my ($this, $path, $target) = @_; my $in = new JFile($path, "rb"); return undef unless($in); $this->SetDataArray(new GraphDataArray); my $Data = new GraphData; my $line = $in->SkipTo("^\\s+POSCAR: "); my ($SampleName) = ($line =~ /^\s+POSCAR:\s*(\w*)\s*$/); $SampleName = Deps::GetLastDirectory($path) unless($SampleName); #print "Sample: $SampleName\n"; $Data->SetTitle($SampleName); $in->SkipTo("Dimension of arrays:"); # k-Points NKPTS = 1 number of bands NBANDS= 383 $line = $in->ReadLine(); my ($nBands) = ($line =~ /NBANDS\s*=\s*(\d+)/); #print "nBands=$nBands\n"; # number of dos NEDOS = 301 number of ions NIONS = 72 $line = $in->ReadLine(); my ($nIons) = ($line =~ /NIONS\s*=\s*(\d+)/); #print "nIons=$nIons\n"; # number of electron 639.0000000 magnetization $line = $in->SkipTo("^\\s*number of electron"); my ($nElectrons) = ($line =~ /number of electron\s+(\S+)/); $nElectrons += 0.0; #print "nElectrons=$nElectrons\n"; if($target eq 'EnergyConvergence') { my @Iteration; my @EnergyWithoutEntropy; my $iter = 0; $in->rewind(); while(!$in->eof()) { $line = $in->SkipTo("--- Iteration "); #print "line: $line\n"; last if($in->eof()); $line = $in->SkipTo(" energy without entropy ="); my ($eng) = ($line =~ /entropy =\s*(\S+)/); $EnergyWithoutEntropy[$iter] = $eng; $Iteration[$iter] = $iter+1; print "i=$iter: E(total)=$eng\n"; $iter++; } $Data->{'x0'} = \@Iteration; $Data->{'x0_Name'} = "Iteration"; $Data->{'y0'} = \@EnergyWithoutEntropy; $Data->{'y0_Name'} = "Energy / Ry"; } if($target =~ /ForceConvergence/i) { my @Iteration; my @RMSForce; my $iter = 0; $in->rewind(); while(!$in->eof()) { $line = $in->SkipTo("POSITION\\s+TOTAL-FORCE"); #print "line: $line\n"; last if($in->eof()); $in->ReadLine(); my $n = 0; my $F2 = 0.0; while(1) { $line = $in->ReadLine(); last if($line =~ /-----/); my ($x,$y,$z,$Fx,$Fy,$Fz) = Utils::Split("\\s+", $line); $F2 += $Fx*$Fx + $Fy*$Fy + $Fz*$Fz; $n++; if($target !~ /RMS/i) { my ($n0,$n1) = ($target =~ /\(AtomRange:\s*(\d+)\s*-\s*(\d+)\s*\)/); $n0 = 0 unless(defined($n0)); $n1 = -1 unless(defined($n1)); #print "AtomRange: $n0 - $n1\n"; next if($n1 > 0 and not ($n0 <= $n and $n <= $n1)); my $ix = 3*($n-1) + 1; my $iy = 3*($n-1) + 2; my $iz = 3*($n-1) + 3; unless(defined $Data->{"x$ix"}) { my (@Fx, @Fy, @Fz); $Data->{"x$ix"} = \@Iteration; $Data->{"x${ix}_Name"} = "Iteration"; $Data->{"y${ix}"} = \@Fx; $Data->{"y${ix}_Name"} = "Atom ${n} Force x / eV/Angstrom"; $Data->{"x$iy"} = \@Iteration; $Data->{"x${iy}_Name"} = "Iteration"; $Data->{"y${iy}"} = \@Fy; $Data->{"y${iy}_Name"} = "Atom ${n} Force y / eV/Angstrom"; $Data->{"x$iz"} = \@Iteration; $Data->{"x${iz}_Name"} = "Iteration"; $Data->{"y${iz}"} = \@Fz; $Data->{"y${iz}_Name"} = "Atom ${n} Force z / eV/Angstrom"; } $Data->{"y${ix}"}->[$iter] = $Fx; $Data->{"y${iy}"}->[$iter] = $Fy; $Data->{"y${iz}"}->[$iter] = $Fz; } } my $F = 0.0; $F = sqrt($F2 / $n) if($n > 0); $RMSForce[$iter] = $F; $Iteration[$iter] = $iter+1; print "i=$iter: F(RMS)=$F\n"; $iter++; } $Data->{'x0'} = \@Iteration; $Data->{'x0_Name'} = "Iteration"; $Data->{'y0'} = \@RMSForce; $Data->{'y0_Name'} = "RMS Force / eV/Angstrom"; } if($target eq 'EnergyLevels') { $in->rewind(); my $iter = 0; while(!$in->eof()) { #print "iter: $iter\n"; $line = $in->SkipTo(" band No. band"); last unless(defined $line); my @XConstant; my @BandEnergy; my @Occupation; for(my $i = 0 ; $i < $nBands ; $i++) { $line = $in->ReadLine(); #print "line: $line"; my @a = split(/\s+/, $line); @a = Utils::RemoveSpaceElement(@a); #print "i=$i: $a[0], $a[1], $a[2]\n"; $XConstant[$i] = 1.0; $BandEnergy[$i] = $a[1]; $Occupation[$i] = $a[2]; } $Data->{'x0'} = \@XConstant; $Data->{'x0_Name'} = "Band No"; $Data->{"y${iter}"} = \@BandEnergy; $Data->{"y${iter}_Name"} = "Energy (Iter# $iter)"; $Data->{"Occupation${iter}"} = \@Occupation; $iter++; } } $in->Close(); $Data->CalMinMax(); $this->{'DataArray'}->AddGraphData($Data); $this->{'DataArray'}->{'TargetData'} = $target; return $path; } sub ReadKeyValue { my ($this, $RegExp, $def, $path) = @_; my $in = new JFile($path, "rb"); return 0.0 if(!defined $in); my $line = $in->SkipTo($RegExp); # my $val = $1; my ($val) = ($line =~ /$RegExp/); $in->Close(); $val = $def unless(defined $val); return $val; } sub ReadFermiEnergy { my ($this, $path) = @_; my $in = new JFile($path, "rb"); return 0.0 if(!defined $in); my $line = $in->SkipTo(" E-fermi :"); #print "p[$path]\n"; #print "l:$line\n"; my $EF; ($EF) = ($line =~ /E-fermi\s*:\s*(\S+)/) if($line); $in->Close(); $EF = 0.0 unless(defined $EF); #print "***EF=$EF eV\n"; #exit; return $EF; } sub ReadOUTCARValues { my ($this, $path) = @_; my $in = new JFile($path, "rb"); return 0.0 if(!defined $in); my $energy; my $pos; while(1) { my $l = $in->SkipTo("\\s*free energy TOTEN ="); last if(!defined $l); $pos = $in->tell(); ($energy) = ($l =~ /free energy TOTEN =\s*(\S+)/); } $in->seek($pos, 0) if(defined $pos); #print "energy: $energy\n"; $this->{FreeEnergy} = $energy; my $l1 = $in->SkipTo("\\s*total charge"); #print "l1=$l1\n"; $in->SkipTo("# of ion s p d tot"); $in->ReadLine(); for(my $i = 1 ; ; $i++) { my $l = $in->ReadLine(); Utils::DelSpace($l); last if($l =~ /^-----/ or !defined $l or $l eq ''); my ($iIon, $s, $p, $d, $tot) = Utils::Split("\\s+", $l); $this->{"Ion${iIon}_s"} = $s; $this->{"Ion${iIon}_p"} = $p; $this->{"Ion${iIon}_d"} = $d; $this->{"Ion${iIon}_tot"} = $tot; $this->{"nIon"} = $iIon; #print "iIon=$iIon, $s, $p, $d, $tot\n"; } $in->Close(); return; } sub GetOrbitalsFromPROCAR { my ($this, $path) = @_; my $in = new JFile($path, 'r'); if(!$in) { print "Error in VASP::GetOrbitalsFromPROCAR: $!: Can not read [$path].\n"; return -1; } if(!$in->SkipTo("band\\s+\\d")) { print "Error in VASP::GetOrbitalsFromPROCAR: Can not find 'band' label in [$path].\n"; return -2; } $in->ReadLine(); my $line = $in->ReadLine(); my ($ion, @a) = Utils::Split("\\s+", $line); my $na = @a; if($a[$na-1] eq 'tot') { delete $a[$na-1]; } $in->Close(); return @a; } sub CalSele { my ($this, $Emin, $Estep, $nE, $pD, $T, $EF) = @_; my $Sele = 0.0; for(my $ie = 0 ; $ie < $nE ; $ie++) { my $Ei = $Emin + $ie * $Estep; my $fe = Sci::FEe($Ei, $EF, $T); my $fh = 1.0 - $fe; next if($fe < 1.0e-10 or $fh < 1.0e-10); $Sele += $pD->[$ie] * ($fe * log($fe) + $fh * log($fh)); } return -$kB * $Sele / $e; } sub CalEele { my ($this, $Emin, $Estep, $nE, $pD, $T, $EF) = @_; my $Eele = 0.0; for(my $ie = 0 ; $ie < $nE ; $ie++) { my $Ei = $Emin + $ie * $Estep; $Eele += $Ei * $pD->[$ie] * Sci::FEe($Ei, $EF, $T); } return $Eele; } sub CalNe { my ($this, $Dunder, $Emin, $Estep, $nE, $pD, $T, $EF) = @_; my $Ne = $Dunder; for(my $ie = 0 ; $ie < $nE ; $ie++) { my $Ei = $Emin + $ie * $Estep; $Ne += $pD->[$ie] * Sci::FEe($Ei, $EF, $T); } return $Ne; } sub CalEF { my ($this, $Dunder, $Emin, $Estep, $nE, $pD, $T, $NELECT, $EFmin, $EFmax, $EFEPS, $NeEPS) = @_; $EFEPS = 1.0e-6 if(!defined $EFEPS); $NeEPS = 1.0e-4 if(!defined $NeEPS); my $dNe0 = $this->CalNe($Dunder, $pD, $T, $EFmin) - $NELECT; my $dNe1 = $this->CalNe($Dunder, $pD, $T, $EFmax) - $NELECT; #print " dNe($EFmin) = $dNe0 dNe($EFmax) = $dNe1\n"; if($dNe0 * $dNe1 > 0.0) { print "Error in VASP::CalEF: dNe($EFmin)=$dNe0 and dNe($EFmax)=$dNe1 has the same signs.\n"; print " Reconsider dEFmin and dEFmax applicable for binary search.\n"; print "\n"; exit; } my ($EFnew, $dNe0, $dNe1, $dNenew); my $EF0 = $EFmin; my $EF1 = $EFmax; my $nMaxIter = 100; for(my $i = 0; $i < $nMaxIter ; $i++) { $dNe0 = $this->CalNe($Dunder, $Emin, $Estep, $nE, $pD, $T, $EF0) - $NELECT; $dNe1 = $this->CalNe($Dunder, $Emin, $Estep, $nE, $pD, $T, $EF1) - $NELECT; #print "T=$T EFrange = ($EF0, $EF1) dNe = ($dNe0, $dNe1)\n"; if(abs($dNe0) < $NeEPS) { return ($EF0, $dNe0); } if(abs($dNe1) < $NeEPS) { return ($EF1, $dNe1); } # if($EF1 - $EF0 < $EFEPS and abs($dNe0) < $NeEPS and abs($dNe1) < $NeEPS) { if($EF1 - $EF0 < $EFEPS) { $EFnew = ($EF0 + $EF1) / 2.0; $dNenew = $this->CalNe($Dunder, $Emin, $Estep, $nE, $pD, $T, $EFnew) - $NELECT; #exit; return ($EFnew, $dNenew); } $EFnew = ($EF0 + $EF1) / 2.0; $dNenew = $this->CalNe($Dunder, $Emin, $Estep, $nE, $pD, $T, $EFnew) - $NELECT; if($dNe0*$dNenew < 0.0) { $EF1 = $EFnew; } else { $EF0 = $EFnew; } } print "Error in VASP::CalEF: Not converged after $nMaxIter iterations\n"; return (undef, undef); } sub CalculateExactDOSFromEIGENVAL { my ($this, $EIGENVALPath, $EF, $Emin, $Emax, $Estep, $nE) = @_; my (@D, @Ne); my ($Dunder, $Dover) = (0.0, 0.0); my $in = JFile->new($EIGENVALPath, 'r') or die "Can not read [$EIGENVALPath].\n"; my $line; for(my $i = 0 ; $i < 5 ; $i++) { $in->ReadLine(); } #print "line: $line\n"; my $SampleName = $line; $SampleName =~ s/^\s*//; $SampleName =~ s/\s*$//; $line = $in->ReadLine(); my ($nn, $nK, $nLevels) = Utils::Split("\\s+", $line); print " nn,nK,nLevels=$nn, $nK, $nLevels\n"; for(my $ie = 0 ; $ie < $nLevels ; $ie++) { $D[$ie] = 0.0; } for(my $i = 0 ; $i < $nK ; $i++) { $in->ReadLine(); $line = $in->ReadLine(); my ($kx, $ky, $kz, $w) = Utils::Split("\\s+", $line); for(my $ie = 0 ; $ie < $nLevels ; $ie++) { $line = $in->ReadLine(); my ($idx, $Ei, $occ) = Utils::Split("\\s+", $line); $Ei -= $EF; my $iE = int(($Ei - $Emin) / $Estep); #print "i=$i ie=$ie Ei = $Ei ($Emin - $Emax) iE=$iE (< $nE)\n"; if($iE < 0.0) { $Dunder += 2.0 * $w; } elsif($nE <= $iE) { $Dover += 2.0 * $w; } else { $D[$iE] += 2.0 * $w; #print " D[$iE] = $D[$iE]\n"; } } } $in->Close(); $Ne[0] = $Dunder; for(my $ie = 0 ; $ie < $nE ; $ie++) { $Ne[$ie+1] += $Ne[$ie] + $D[$ie]; } return ($Dunder, $Dover, \@D, \@Ne); } sub ReadDOSCARwithPROCAR { my ($this, $path) = @_; my $DOSCARPath = $this->GetDOSCARFileName($path); print "VASP::ReadDOSCAR: Read [$DOSCARPath].\n"; my $PROCARPath = $this->GetPROCARFileName($path); print "VASP::ReadDOSCAR: Read [$PROCARPath].\n"; my $POSCAR = $this->GetPOSCARFileName($path); print "VASP::ReadPROCAR: Read [$POSCAR].\n"; my $Crystal = $this->ReadStructureFromCARFiles($POSCAR, 1); my @AtomTypeList = $Crystal->GetCAtomTypeList(); my $nAtomType = @AtomTypeList; my %AtomNum; for(my $i = 0 ; $i < $nAtomType ; $i++) { my $name = $AtomTypeList[$i]->AtomNameOnly();; $AtomNum{$name} = 0 if(!defined $AtomNum{$name}); my $n = ++$AtomNum{$name}; $AtomTypeList[$i]->SetAtomName("$name$n"); #print "$i: $name$n\n"; } my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode(); # my @M = $Crystal->GetCnMultiplicityExpandedAtomSiteList(); my $nTotalExpandedAtomSite = @ExpandedAtomSiteList; my @AtomNames; for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) { my $atomsite = $ExpandedAtomSiteList[$i]; $AtomNames[$i] = $atomsite->AtomName(); #AtomNameOnly(); #print "Site[$i]: $AtomNames[$i] ($M[$i])\n"; print "Site[$i]: $AtomNames[$i]\n"; } my $OUTCAR = $this->GetOUTCARFileName($path); my $EF = $this->ReadFermiEnergy($OUTCAR); print "EF: $EF eV\n"; print "VASP::ReadPROCAR: Read [$PROCARPath].\n"; my @Orbitals = $this->GetOrbitalsFromPROCAR($PROCARPath); if(@Orbitals == 0) { return -1; } my $in = new JFile($DOSCARPath, "rb"); return undef unless($in); my $line; for(my $i = 0 ; $i < 5 ; $i++) { $line = $in->ReadLine(); } # BaZn2As2-I4mmm [PAW_PBE] (dos) my $SampleName = $line; $SampleName =~ s/^\s*//; $SampleName =~ s/\s*$//; print "Sample [$SampleName]\n"; # 15.00000000 -35.00000000 5000 3.50770154 1.00000000 $line = $in->ReadLine(); my ($E1, $E0, $nData, $w); ($E1, $E0, $nData, $EF, $w) = Utils::Split("\\s+", $line); print "nData=$nData\n"; my (@TE, %DOS); for(my $i = 0 ; $i < $nData ; $i++) { $line = $in->ReadLine(); # 指数が3桁の場合、eが削除されるので追加 $line =~ s/(\d)\-(\d)/$1e\-$2/g; my ($e, $tot, $ne) = Utils::Split("\\s+", $line); $TE[$i] = $e; $DOS{Total}[$i] += $tot; $DOS{Interstitial}[$i] += $tot; $DOS{NE}[$i] += $ne; #print " $i: $e\t$up\t$dn\n"; } my $iAtom = 0; while(1) { $line = $in->ReadLine(); # 指数が3桁の場合、eが削除されるので追加 $line =~ s/(\d)\-(\d)/$1e\-$2/g; my ($E1, $E0, $nData, $EF, $w) = Utils::Split("\\s+", $line); my $atomsite = $ExpandedAtomSiteList[$iAtom]; my $AtomName = $atomsite->AtomNameOnly(); print "Site[$iAtom]: $AtomName: nData=$nData\n"; for(my $i = 0 ; $i < $nData ; $i++) { $line = $in->ReadLine(); # 指数が3桁の場合、eが削除されるので追加 $line =~ s/(\d)\-(\d)/$1e\-$2/g; my ($e, @a) = Utils::Split("\\s+", $line); last if(!$line or @a <= 1); if($i == 0) { Utils::DelSpace($line); my $nOrb = scalar @a; print " nO=$nOrb [$line]\n"; } for(my $j = 0 ; $j < @a ; $j++) { my $orb = $Orbitals[$j]; #print("$j: $orb "); $DOS{Interstitial}[$i] -= $a[$j]; $DOS{$AtomName}{Total}[$i] += $a[$j]; $DOS{$AtomName}{$orb}[$i] += $a[$j]; } } last if($in->eof()); $iAtom++; } $in->Close(); return (\@AtomTypeList, \@ExpandedAtomSiteList, \@Orbitals, $EF, $nData, \@TE, \%DOS); } sub ReadDOSCAR { my ($this, $path, $IsSpinPolarized, $IsNonCollinear) = @_; $IsSpinPolarized = $this->IsSpinPolarized() if(!defined $IsSpinPolarized); if(!defined $IsNonCollinear) { my $INCAR = $this->GetINCARFileName($path); my $pINCAR = $this->ReadINCARtoHash($INCAR); $IsNonCollinear = ($pINCAR->{LSORBIT} =~ /[1T]/i or $pINCAR->{LNONCOLLINEAR} =~ /[1T]/i)? 1 : 0; $IsSpinPolarized = 0 if($IsNonCollinear); } my $POSCAR = $this->GetPOSCARFileName($path); print "VASP::ReadDOSCAR: Read [$POSCAR].\n"; my $Crystal = $this->ReadStructureFromCARFiles($POSCAR, 1); my $pPOS = $this->ReadPOSCARtoHash($POSCAR); my @AtomTypeList = $Crystal->GetCAtomTypeList(); my $nAtomType = @AtomTypeList; my %AtomNum; for(my $i = 0 ; $i < $nAtomType ; $i++) { my $name = $AtomTypeList[$i]->AtomNameOnly();; $AtomNum{$name} = 0 if(!defined $AtomNum{$name}); my $n = ++$AtomNum{$name}; $AtomTypeList[$i]->SetAtomName("$name$n"); #print "$i: $name$n\n"; } my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode(); # my @M = $Crystal->GetCnMultiplicityExpandedAtomSiteList(); my $nTotalExpandedAtomSite = @ExpandedAtomSiteList; my @AtomNames; for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) { my $atomsite = $ExpandedAtomSiteList[$i]; $AtomNames[$i] = $atomsite->AtomName(); #AtomNameOnly(); #print "Site[$i]: $AtomNames[$i] ($M[$i])\n"; print "Site[$i]: $AtomNames[$i]\n"; } my $OUTCAR = $this->GetOUTCARFileName($path); my $EF = $this->ReadFermiEnergy($OUTCAR); print "EF: $EF eV\n"; my $in = new JFile($path, "rb"); return undef unless($in); $this->SetDataArray(new GraphDataArray); my $Data0 = new GraphData; my $Data1 = new GraphData; my $Data2 = new GraphData; my $Data3 = new GraphData; my $line; for(my $i = 0 ; $i < 5 ; $i++) { $line = $in->ReadLine(); } # NaCl (dos) my $SampleName = $line; $SampleName =~ s/^\s*//; $SampleName =~ s/\s*$//; $Data0->SetTitle($SampleName); $Data1->SetTitle($SampleName); # 12.29201091 -13.90257885 301 0.14679613 1.00000000 $line = $in->ReadLine(); my ($a,$b,$nData) = Utils::Split("\\s+", $line); print "nData=$nData\n"; my @Energy; my @DOSup; my @DOSdn; my @Neup; my @Nedn; for(my $i = 0 ; $i < $nData ; $i++) { $line = $in->ReadLine(); last if(not defined $line); #my $f = 0; #if($line =~ /\d\-\d/) { #print "i=$i:$line\n"; #$f = 1; #exit; #} # 指数が3桁の場合、eが削除されるので追加 $line =~ s/(\d)\-(\d)/$1e\-$2/g; #if($f) { #print " $line\n"; #exit; #} my ($e,$du,$dd, $nu, $nd) = Utils::Split("\\s+", $line); #print "$i ($nData): $e eV\n"; if(!defined $nu) { $this->SpinPolarized(0); ($du, $nu) = ($du, $dd); } else { $this->SpinPolarized(1); } last if(not defined $e); $Energy[$i] = $e - $EF; $DOSup[$i] = $du + 0.0; $Neup[$i] = $nu + 0.0; if($this->IsSpinPolarized()) { $DOSdn[$i] = $dd; $Nedn[$i] = $nd; } last if($in->eof()); } #print "EF: $EF eV\n"; my @IntDOSup = @DOSup; my @IntDOSdn = @DOSdn; my $nAtomKinds = 0; my %pPDOSupArray; my @pPDOStupArray; my @pPDOSsupArray; my @pPDOSpupArray; my @pPDOSdupArray; my @pPDOSfupArray; my %pPDOSdnArray; my @pPDOStdnArray; my @pPDOSsdnArray; my @pPDOSpdnArray; my @pPDOSddnArray; my @pPDOSfdnArray; my @pPDOSsmxArray; my @pPDOSsmyArray; my @pPDOSsmzArray; my @pPDOSpmxArray; my @pPDOSpmyArray; my @pPDOSpmzArray; my @pPDOSdmxArray; my @pPDOSdmyArray; my @pPDOSdmzArray; my $pAtomType = $pPOS->{pAtomType}; my $pAtomSite = $pPOS->{pAtomSite}; #print "pD=$pPOS, $pAtomType, $pAtomSite\n"; my $cc = 0; while(1) { my $site = $pAtomSite->[$cc]; last if(!$site); #print "cc=$cc: site=$site\n"; my $name = $site->AtomName(); my $occ = $site->Occupancy(); #print "$i: $name: $occ\n"; $cc++; $in->ReadLine(); my @PDOStup; my @PDOSsup; my @PDOSpup; my @PDOSdup; my @PDOSfup; my @PDOStdn; my @PDOSsdn; my @PDOSpdn; my @PDOSddn; my @PDOSfdn; my @PDOSsmx; my @PDOSsmy; my @PDOSsmz; my @PDOSpmx; my @PDOSpmy; my @PDOSpmz; my @PDOSdmx; my @PDOSdmy; my @PDOSdmz; for(my $i = 0 ; $i < $nData ; $i++) { $line = $in->ReadLine(); last if(not defined $line); # 指数が3桁の場合、eが削除されるので追加 $line =~ s/(\d)\-(\d)/$1e\-$2/g; my ($e, $dt, $dsu, $dsd, $dpu, $dpd, $ddu, $ddd, $dfu, $dfd); my ($dsmx, $dsmy, $dsmz, $dpmx, $dpmy, $dpmz, $ddmx, $ddmy, $ddmz); my @aa = Utils::Split("\\s+", $line); #print "n=", scalar @aa, "\n"; if($IsNonCollinear) { ($e, $dsu, $dsmx, $dsmy, $dsmz, $dpu, $dpmx, $dpmy, $dpmz, $ddu, $ddmx, $ddmy, $ddmz) = @aa; $dfu = 0; $dt = $dsu + $dpu + $ddu + $dfu; } elsif($IsSpinPolarized) { ($e, $dsu, $dsd, $dpu, $dpd, $ddu, $ddd, $dfu, $dfd) = @aa; $dt = $dsu + $dpu + $ddu + $dfu; } else { if(@aa == 3) { ($dsu, $dpu, $ddu) = @aa; } else { ($e, $dsu, $dpu, $ddu) = @aa; } $dt = $dsu + $dpu + $ddu + $dfu; } last if(not defined $e); $dfu = 0.0 if(!defined $dfu); $dfd = 0.0 if(!defined $dfd); $PDOStup[$i] = $dt; $PDOSsup[$i] = $dsu + 0.0; $PDOSpup[$i] = $dpu + 0.0; $PDOSdup[$i] = $ddu + 0.0; $PDOSfup[$i] = $dfu + 0.0; $IntDOSup[$i] -= $PDOStup[$i] * $occ; if($IsSpinPolarized) { $PDOStdn[$i] = $dsd + $dpd + $ddd + $dfd; $PDOSsdn[$i] = $dsd + 0.0; $PDOSpdn[$i] = $dpd + 0.0; $PDOSddn[$i] = $ddd + 0.0; $PDOSfdn[$i] = $dfd + 0.0; $IntDOSdn[$i] -= $PDOStdn[$i] * $occ; } last if($in->eof()); } $pPDOStupArray[$nAtomKinds] = \@PDOStup; $pPDOSsupArray[$nAtomKinds] = \@PDOSsup; $pPDOSpupArray[$nAtomKinds] = \@PDOSpup; $pPDOSdupArray[$nAtomKinds] = \@PDOSdup; $pPDOSfupArray[$nAtomKinds] = \@PDOSfup; if($this->IsSpinPolarized()) { $pPDOStdnArray[$nAtomKinds] = \@PDOStdn; $pPDOSsdnArray[$nAtomKinds] = \@PDOSsdn; $pPDOSpdnArray[$nAtomKinds] = \@PDOSpdn; $pPDOSddnArray[$nAtomKinds] = \@PDOSddn; $pPDOSfdnArray[$nAtomKinds] = \@PDOSfdn; } my $aname = $AtomNames[$nAtomKinds]; $aname =~ s/\d+//; #print "atom[$cc]:$aname\n"; my $st = "$aname total"; my $ss = "$aname s"; my $sp = "$aname p"; my $sd = "$aname d"; my $sf = "$aname f"; my $ptu = $pPDOSupArray{$st}; my $psu = $pPDOSupArray{$ss}; my $ppu = $pPDOSupArray{$sp}; my $pdu = $pPDOSupArray{$sd}; my $pfu = $pPDOSupArray{$sf}; my $ptd = $pPDOSdnArray{$st}; my $psd = $pPDOSdnArray{$ss}; my $ppd = $pPDOSdnArray{$sp}; my $pdd = $pPDOSdnArray{$sd}; my $pfd = $pPDOSdnArray{$sf}; if(!defined $psu) { #print "cc=$cc: initialize for [$st]\n"; $ptu = $pPDOSupArray{$st} = []; $psu = $pPDOSupArray{$ss} = []; $ppu = $pPDOSupArray{$sp} = []; $pdu = $pPDOSupArray{$sd} = []; $pfu = $pPDOSupArray{$sf} = []; $ptd = $pPDOSdnArray{$st} = []; $psd = $pPDOSdnArray{$ss} = []; $ppd = $pPDOSdnArray{$sp} = []; $pdd = $pPDOSdnArray{$sd} = []; $pfd = $pPDOSdnArray{$sf} = []; for(my $i = 0 ; $i < $nData ; $i++) { $ptu->[$i] = 0.0; $psu->[$i] = 0.0; $ppu->[$i] = 0.0; $pdu->[$i] = 0.0; $pfu->[$i] = 0.0; $ptd->[$i] = 0.0; $psd->[$i] = 0.0; $ppd->[$i] = 0.0; $pdd->[$i] = 0.0; $pfd->[$i] = 0.0; } } else { #print "cc=$cc: not initialize for [$st]\n"; } for(my $i = 0 ; $i < $nData ; $i++) { $ptu->[$i] += $PDOStup[$i]; $psu->[$i] += $PDOSsup[$i]; $ppu->[$i] += $PDOSpup[$i]; $pdu->[$i] += $PDOSdup[$i]; $pfu->[$i] += $PDOSfup[$i]; if($this->IsSpinPolarized()) { $ptd->[$i] += $PDOStdn[$i]; $psd->[$i] += $PDOSsdn[$i]; $ppd->[$i] += $PDOSpdn[$i]; $pdd->[$i] += $PDOSddn[$i]; $pfd->[$i] += $PDOSfdn[$i]; } } $nAtomKinds++; last if($in->eof()); } $in->Close(); $Data1->{"x0"} = \@Energy; $Data1->{"x0_Name"} = "Energy / eV"; $Data1->{"y0"} = \@Neup; $Data1->{"y0_Name"} = "Ne"; if($this->IsSpinPolarized()) { # $Data1->{'y0_Name'} = "Ne up"; $Data3->{'x0'} = \@Energy; $Data3->{'x0_Name'} = "Energy / eV"; $Data3->{'y0'} = \@Nedn; $Data3->{'y0_Name'} = "Ne down"; } my $cup = 0; my $cdn = 0; $Data0->{"x$cup"} = \@Energy; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y$cup"} = \@DOSup; $Data0->{"y${cup}_Name"} = "DOS"; $cup++; if($this->IsSpinPolarized()) { # $Data0->{"y${cdn}_Name"} = "DOS up"; $Data2->{"x$cdn"} = \@Energy; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y$cdn"} = \@DOSdn; $Data2->{"y${cdn}_Name"} = "DOS down"; $cdn++; } $Data0->{"x$cup"} = \@Energy; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y$cup"} = \@IntDOSup; $Data0->{"y${cup}_Name"} = "Interstitial"; $cup++; if($this->IsSpinPolarized()) { # $Data0->{"y${cup}_Name"} = "Interstitial up"; $Data2->{"x$cdn"} = \@Energy; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y$cdn"} = \@IntDOSdn; $Data2->{"y${cdn}_Name"} = "Interstitial down"; $cdn++; } my $SiteDOS = 0; if($SiteDOS) { for(my $i = 0 ; $i < $nAtomKinds ; $i++) { my $i1 = $i+1; my $pPDOStup = $pPDOStupArray[$i]; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOStup; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "Atom$i total"; $cup++; if($this->IsSpinPolarized()) { my $pPDOStdn = $pPDOStdnArray[$i]; # $Data0->{"y${cdn}_Name"} = "Atom$i total up"; $Data0->{"x$cdn"} = \@Energy; $Data0->{"y$cdn"} = $pPDOStdn; $Data0->{"x${cdn}_Name"} = "Energy / eV"; $Data0->{"y${cdn}_Name"} = "Atom$i total down"; $cdn++; } } for(my $i = 0 ; $i < $nAtomKinds ; $i++) { my $i1 = $i+1; my $pPDOSsup = $pPDOSsupArray[$i]; my $pPDOSpup = $pPDOSpupArray[$i]; my $pPDOSdup = $pPDOSdupArray[$i]; my $pPDOSfup = $pPDOSfupArray[$i]; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOSsup; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "Atom$i s"; $cup++; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOSpup; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "Atom$i p"; $cup++; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOSdup; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "Atom$i d"; $cup++; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOSfup; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "Atom$i f"; $cup++; if($this->IsSpinPolarized()) { my $pPDOSsdn = $pPDOSsdnArray[$i]; my $pPDOSpdn = $pPDOSpdnArray[$i]; my $pPDOSddn = $pPDOSddnArray[$i]; my $pPDOSfdn = $pPDOSfdnArray[$i]; $Data2->{"x$cdn"} = \@Energy; $Data2->{"y$cdn"} = $pPDOSsdn; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y${cdn}_Name"} = "Atom$i s down"; $cdn++; $Data2->{"x$cdn"} = \@Energy; $Data2->{"y$cdn"} = $pPDOSpdn; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y${cdn}_Name"} = "Atom$i p down"; $cdn++; $Data2->{"x$cdn"} = \@Energy; $Data2->{"y$cdn"} = $pPDOSddn; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y${cdn}_Name"} = "Atom$i d down"; $cdn++; $Data2->{"x$cdn"} = \@Energy; $Data2->{"y$cdn"} = $pPDOSfdn; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y${cdn}_Name"} = "Atom$i f down"; $cdn++; } } } #print "c0=$cup $cdn\n"; my $PDOS = 1; if($PDOS) { for(my $i = 0 ; $i < $nAtomType ; $i++) { my $atomtype = $AtomTypeList[$i]; my $atomname = $atomtype->AtomName(); #AtomNameOnly(); my $aname = $atomname; $aname =~ s/\d+//; my $st = "$aname total"; print " PDOS for $st\n"; my $ptup = $pPDOSupArray{$st}; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOSupArray{$st}; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "$st"; $cup++; if($this->IsSpinPolarized()) { my $ptdn = $pPDOSdnArray{$st}; print " PDOS for $st down\n"; $Data2->{"x$cdn"} = \@Energy; $Data2->{"y$cdn"} = $pPDOSdnArray{$st}; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y${cdn}_Name"} = "$st down"; $cdn++; } } for(my $i = 0 ; $i < $nAtomType ; $i++) { my $atomtype = $AtomTypeList[$i]; my $atomname = $atomtype->AtomName(); # AtomNameOnly(); my $aname = $atomname; $aname =~ s/\d+//; my $ss = "$aname s"; my $sp = "$aname p"; my $sd = "$aname d"; my $sf = "$aname f"; print " PDOS for $ss\n"; print " PDOS for $sp\n"; print " PDOS for $sd\n"; print " PDOS for $sf\n"; my $psu = $pPDOSupArray{$ss}; my $ppu = $pPDOSupArray{$sp}; my $pdu = $pPDOSupArray{$sd}; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOSupArray{$ss}; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "$ss"; $cup++; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOSupArray{$sp}; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "$sp"; $cup++; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOSupArray{$sd}; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "$sd"; $cup++; $Data0->{"x$cup"} = \@Energy; $Data0->{"y$cup"} = $pPDOSupArray{$sf}; $Data0->{"x${cup}_Name"} = "Energy / eV"; $Data0->{"y${cup}_Name"} = "$sf"; $cup++; if($this->IsSpinPolarized()) { my $psd = $pPDOSdnArray{$ss}; my $ppd = $pPDOSdnArray{$sp}; my $pdd = $pPDOSdnArray{$sd}; print " PDOS for $ss down\n"; print " PDOS for $sp down\n"; print " PDOS for $sd down\n"; print " PDOS for $sf down\n"; $Data2->{"x$cdn"} = \@Energy; $Data2->{"y$cdn"} = $pPDOSdnArray{$ss}; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y${cdn}_Name"} = "$ss down"; $cdn++; $Data2->{"x$cdn"} = \@Energy; $Data2->{"y$cdn"} = $pPDOSdnArray{$sp}; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y${cdn}_Name"} = "$sp down"; $cdn++; $Data2->{"x$cdn"} = \@Energy; $Data2->{"y$cdn"} = $pPDOSdnArray{$sd}; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y${cdn}_Name"} = "$sd down"; $cdn++; $Data2->{"x$cdn"} = \@Energy; $Data2->{"y$cdn"} = $pPDOSdnArray{$sf}; $Data2->{"x${cdn}_Name"} = "Energy / eV"; $Data2->{"y${cdn}_Name"} = "$sf down"; $cdn++; } #print "c=$cup, $cdn\n" } } #my $p = $Data0->{x0}; #for(my $i = 0 ; $i < @$p ; $i++) { # print "$i: $p->[$i]\n"; #} $this->{EFDOS} = $EF; $Data0->CalMinMax(); $this->{'DataArray'}->AddGraphData($Data0); $Data1->CalMinMax(); $this->{'DataArray'}->AddGraphData($Data1); if($this->IsSpinPolarized()) { #print "Add data for down spins\n"; $Data2->CalMinMax(); $this->{'DataArray'}->AddGraphData($Data2); $Data3->CalMinMax(); $this->{'DataArray'}->AddGraphData($Data3); } return $path; } sub ReadEIGENVALtoArray { my ($this, $EIGENVALPath, $EF) = @_; $EF = 0.0 if(!defined $EF); my $pHash = $this->ReadINCARtoHash($EIGENVALPath); my $ISPIN = $pHash->{ISPIN}; my $in = new JFile($EIGENVALPath, "rb"); return undef unless($in); my $line; for(my $i = 0 ; $i < 5 ; $i++) { $line = $in->ReadLine(); } my $SampleName = $line; $line = $in->ReadLine(); my ($nn, $nK, $nLevels) = Utils::Split("\\s+", $line); my @EnergyBands; my @KPointInf; for(my $iK = 0 ; $iK < $nK ; $iK++) { #Skip blank line $line = $in->ReadLine(); $line =~ s/^\s+//; $line =~ s/\s+$//; if($line eq '') { $line = $in->ReadLine(); } #print "line2: $line\n"; $line =~ s/^.*?://; my ($kx, $ky, $kz, $w) = Utils::Split("\\s+", $line); $KPointInf[$iK] = [$kx, $ky, $kz, $w]; #print "k[$iK]: $kx $ky $kz\n"; for(my $iL = 0 ; $iL < $nLevels ; $iL++) { $line = $in->ReadLine(); #print "l: $line"; my ($ib, $eup, $edn) = Utils::Split("\\s+", $line); $EnergyBands[$iL][$iK][0] = $eup - $EF; if($ISPIN == 2) { #print "Spin Polarized\n"; $this->SpinPolarized(1); $EnergyBands[$iL][$iK][1] = $edn - $EF; #print("VASP.pm: iL=$iL iK=$iK\n"); } else { $this->SpinPolarized(0); } } } $in->Close(); return ($nn, $nK, $nLevels, \@EnergyBands, \@KPointInf); } sub ReadCSVBandFile { my ($this, $path) = @_; print "VASP::ReadCSVBandFile:Read band structure from CSV [$path]\n"; $this->SpinPolarized(0); print " Read EIGENVAL from [$path]\n"; my $in = new JFile($path, "rb"); return undef unless($in); my $line = $in->ReadLine(); my ($kname, $kx, $ky, $kz, $ktot, @E) = split(/\s*,\s*/, $line); my $nLevels = @E; print "nLevels = $nLevels\n"; my $EnergyBandArray = new EnergyBandArray; # $EnergyBandupArray->SetTitle($SampleName); # $EnergyBandupArray->SetCrystal($Crystal); for(my $iL = 0 ; $iL < $nLevels ; $iL++) { $EnergyBandArray->AddEnergyBand(); } for(my $iK = 0 ; ; $iK++) { last if($in->eof()); $line = $in->ReadLine(); ($kname, $kx, $ky, $kz, $ktot, @E) = split(/\s*,\s*/, $line); next if(!defined $E[0]); #print " **k[$iK]: $kx $ky $kz (ktot=$ktot)\n"; for(my $iL = 0 ; $iL < $nLevels ; $iL++) { $EnergyBandArray->AddByKDE($iL, $kx, $ky, $kz, $ktot, $E[$iL]); print " **k[$iK]: $kx $ky $kz (ktot=$ktot) E($iL)=$E[$iL]\n"; } } $EnergyBandArray->CalMinMax(); $EnergyBandArray->GetBandBoundary(); $this->{EnergyBandupArray} = $EnergyBandArray; my $DataArray = new GraphDataArray; $this->SetDataArray($DataArray); $EnergyBandArray->SetGraphDataArray($DataArray); return $path; } sub ReadEIGENVAL { my ($this, $path, $EF, $SkipNonZerow) = @_; $SkipNonZerow = 0 if(!defined $SkipNonZerow); print "VASP::ReadEIGENVAL:Read EIGENVAL from [$path]\n"; my $pHash = $this->ReadINCARtoHash($path); my $ISPIN = $pHash->{ISPIN}; my $IsHF = ($pHash->{LHFCALC} =~ /T/i)? 1 : 0; print " IsHF=$IsHF.\n"; my $POSCAR = $this->GetPOSCARFileName($path); print " Read [$POSCAR].\n"; my $Crystal = $this->ReadStructureFromCARFiles($POSCAR, 1); my $OUTCAR = $this->GetOUTCARFileName($path); print " Read [$OUTCAR].\n"; $EF = $this->ReadFermiEnergy($OUTCAR) if(!defined $EF); print " EF: $EF eV\n"; my $KPOINTS = $this->GetKPOINTSFileName($path); print " Read [$KPOINTS]\n"; my ($nKPoints, $pKPOINTSLines, $pKPOINTSList, $iK0) = $this->ReadKListFromKPOINTS($KPOINTS); $iK0 = 0 if(!$IsHF and !$SkipNonZerow); $this->{iKPoint0} = $iK0; $this->{iKPoint1} = $nKPoints; print " iK range for band plot = $iK0 - $nKPoints\n"; print " Read EIGENVAL from [$path]\n"; my $in = new JFile($path, "rb"); return undef unless($in); my $line; for(my $i = 0 ; $i < 5 ; $i++) { $line = $in->ReadLine(); } #print "line: $line\n"; my $SampleName = $line; $SampleName =~ s/^\s*//; $SampleName =~ s/\s*$//; $line = $in->ReadLine(); my ($nn, $nK, $nLevels) = Utils::Split("\\s+", $line); print " nn,nK,nLevels=$nn, $nK, $nLevels\n"; my $EnergyBandupArray = new EnergyBandArray; my $EnergyBanddnArray = new EnergyBandArray; $EnergyBandupArray->SetTitle($SampleName); $EnergyBandupArray->SetCrystal($Crystal); $EnergyBanddnArray->SetTitle($SampleName); $EnergyBanddnArray->SetCrystal($Crystal); for(my $iL = 0 ; $iL < $nLevels ; $iL++) { $EnergyBandupArray->AddEnergyBand(); $EnergyBanddnArray->AddEnergyBand(); } my $Distance = 0.0; for(my $iK = 0 ; $iK < $nK ; $iK++) { #Skip blank line $line = $in->ReadLine(); $line =~ s/^\s+//; $line =~ s/\s+$//; if($line eq '') { $line = $in->ReadLine(); } #print "line2: $line\n"; my ($kx, $ky, $kz, $w) = Utils::Split("\\s+", $line); print " **k[$iK/$iK0]: $kx $ky $kz (w=$w)\n"; for(my $iL = 0 ; $iL < $nLevels ; $iL++) { $line = $in->ReadLine(); #print "l: $line"; my ($ib, $eup, $edn) = Utils::Split("\\s+", $line); $EnergyBandupArray->AddByKE($iL, $kx, $ky, $kz, $eup-$EF) if($iK >= $iK0); if($ISPIN == 2) { #print "Spin Polarized\n"; $this->SpinPolarized(1); $EnergyBanddnArray->AddByKE($iL, $kx, $ky, $kz, $edn-$EF) if($iK >= $iK0); } else { $this->SpinPolarized(0); } } } $EnergyBandupArray->CalMinMax(); $EnergyBandupArray->GetBandBoundary(); $this->{EnergyBandupArray} = $EnergyBandupArray; if($this->IsSpinPolarized()) { $EnergyBanddnArray->CalMinMax(); $EnergyBanddnArray->GetBandBoundary(); $this->{EnergyBanddnArray} = $EnergyBanddnArray; } my $DataArray = new GraphDataArray; $this->SetDataArray($DataArray); #print "Add up data\n"; $EnergyBandupArray->SetGraphDataArray($DataArray); if($this->IsSpinPolarized()) { #print "Add down data\n"; $EnergyBanddnArray->SetGraphDataArray($DataArray); } return $path; } sub ReadFiles { my ($this, $filename, $TargetData) = @_; $TargetData = 'EnergyConvergence' unless($TargetData); $this->ClearAll(); my $FileType = $this->{'FileType'} = CheckFileType($filename); print "Crystal::VASP: ReadFiles: FileType [$FileType]\n"; $this->SetFileName($filename); if($FileType eq "VASP Output file") { return $this->ReadOUTCAR($filename, $TargetData); # return $this->ReadOUTCAR($filename, "EnergyLevels"); } if($FileType eq "VASP DOSCAR file") { return $this->ReadDOSCAR($filename); } if($FileType eq "VASP EIGENVAL file") { return $this->ReadEIGENVAL($filename); } if($FileType eq "CSV Band file") { return $this->ReadCSVBandFile($filename); } return undef; } #============================================================ # 一般関数 #============================================================ sub RWIGSFromINCAR { my ($this, $filename) = @_; my $in = new JFile($filename, "r"); unless($in) { print "Error: Can not read [$filename].\n"; return -1; } my $line; while(1) { $line = $in->SkipTo("RWIGS\\s*="); last if(!$line); next if($line =~ /#\s*RWIGS\s*=/); last; } ($line) = ($line =~ /RWIGS\s*=\s*(\S.*\S)\s*$/); my @RWIGS = Utils::Split("\\s+", $line); $in->Close(); return @RWIGS; } sub ReadAtomTypesFromPOTCAR { my ($this, $filename, $IsPrint, $AllowDuplicate) = @_; $IsPrint = 1 unless(defined $IsPrint); $AllowDuplicate = 0 if(!defined $AllowDuplicate); my @chars = qw(a b c d e f g h i j k l m n o p q r s t u v w x y z); my $in = new JFile($filename, "r"); unless($in) { print "Error: Can not read [$filename].\n" if($IsPrint); return -1; } my %nAtomTypes; my @AtomTypes; while(!$in->eof()) { my $line = $in->ReadLine(); #print "line: $line\n"; # my ($atomtype) = ($line =~ /(\S+)\s*?$/); my ($atomtype) = ($line =~ /^\s*\S+\s+(\S+)/); $atomtype =~ s/_.*//; ##print "at: $atomtype\n"; if($nAtomTypes{$atomtype}) { if($AllowDuplicate) { my $key = $chars[$nAtomTypes{$atomtype}]; #print "key: $key\n"; push(@AtomTypes, "${atomtype}{$key}"); } } else { push(@AtomTypes, $atomtype); } $nAtomTypes{$atomtype}++; $in->SkipTo("End of Dataset"); } $in->Close(); #for(my $i = 0 ; $i < @AtomTypes ; $i++) { # print "$i: $AtomTypes[$i]\n"; #} return @AtomTypes; } sub ReadStructureFromCARFiles { my ($this, $CARDir, $IsPrint, %hash) = @_; $IsPrint = 1 unless(defined $IsPrint); my $a0 = Sci::a0(); #print "ReadStructureFromCARFiles\n"; $CARDir = $this->GetCARDir($CARDir); my $INCARPath = ($hash{INCARPath})? $hash{INCARPath} : Deps::MakePath($CARDir, "INCAR", 0); my $POSCARPath = ($hash{POSCARPath})? $hash{POSCARPath} : Deps::MakePath($CARDir, "POSCAR", 0); my $POTCARPath = Deps::MakePath($CARDir, "POTCAR", 0); my $pINCAR = $this->ReadINCARtoHash($INCARPath); my @Occ = Utils::Split("\\s+", $pINCAR->{VCA}); my $crystal = new Crystal(); #print "VASP::ReadStructureFromCARFiles: Read [$POTCARPath]\n" if($IsPrint); my @Atomtypes = $this->ReadAtomTypesFromPOTCAR($POTCARPath, 1, 1, \@Occ); return -1 if(@Atomtypes == 0 or $Atomtypes[0] eq "-1"); for(my $i = 0 ; $i < @Atomtypes ; $i++) { my $occ = (defined $Occ[$i])? $Occ[$i] : 1.0; #print "aat occ=$occ\n"; $crystal->AddAtomType($Atomtypes[$i], 0, $occ); #print "\n===\nReadStructureFromCARFiles: Atom[$i]=$Atomtypes[$i]\n"; } #print "VASP::ReadStructureFromCARFiles: Read [$POSCARPath]\n" if($IsPrint); my $in = new JFile($POSCARPath, "r"); unless($in) { print "Error: Can not read [$POSCARPath].\n" if($IsPrint); return -1; } my $line = $in->ReadLine(); Utils::DelSpace($line); $crystal->SetCrystalName($line); $crystal->SetSampleName($line); $line = $in->ReadLine(); my $l0 = $line + 0.0; $line = $in->ReadLine(); my ($l11, $l12, $l13) = Utils::Split("\\s+", $line); $line = $in->ReadLine(); my ($l21, $l22, $l23) = Utils::Split("\\s+", $line); $line = $in->ReadLine(); my ($l31, $l32, $l33) = Utils::Split("\\s+", $line); #print "l0=$l0\n"; #print "l1=$l11, $l12, $l13\n"; #print "l2=$l21, $l22, $l23\n"; #print "l3=$l31, $l32, $l33\n"; #print "l1=", $l11*$l0, $l12*$l0, $l13*$l0, "\n"; #print "l2=", $l21*$l0, $l22*$l0, $l23*$l0, "\n"; #print "l3=", $l31*$l0, $l32*$l0, $l33*$l0, "\n"; $crystal->SetLatticeVector($l11*$l0, $l12*$l0, $l13*$l0, $l21*$l0, $l22*$l0, $l23*$l0, $l31*$l0, $l32*$l0, $l33*$l0); my ($a, $b, $c, $alpha, $beta, $gamma) = $crystal->CalculateLatticeConstantFromVector(); $line = $in->PreReadLine(); if($line !~ /^[\s\d]+$/) { $line = $in->ReadLine(); } $line = $in->ReadLine(); my @nAtomTypes = Utils::Split("\\s+", $line); $in->SkipTo("Direct"); my %AtomCount; for(my $i = 0 ; $i < @nAtomTypes ; $i++) { my $atomtype = $Atomtypes[$i]; my $occ = (defined $Occ[$i])? $Occ[$i] : 1.0; # $crystal->AddAtomType($atomtype, 0, $occ); #print "it=$i:$atomtype occ=$occ\n"; for(my $j = 0 ; $j < $nAtomTypes[$i] ; $j++) { #print " j=$j\n"; $line = $in->ReadLine(); my ($x, $y, $z) = Utils::Split("\\s+", $line); $AtomCount{$atomtype}++; my $Label = $atomtype . $AtomCount{$atomtype}; $crystal->AddAtomSite($Label, $Label, $x, $y, $z, $occ); # $crystal->AddAtomSite($Label, $Label, $x, $y, $z, 1.0); ## $crystal->AddAtomSite($Label, $atomtype, $x, $y, $z, 1.0); } } $crystal->SetLatticeParameters($a, $b, $c, $alpha, $beta, $gamma); $in->Close(); $crystal->ExpandCoordinates(); return $crystal; } sub GetPOTCARList { my ($this, $name, $Functional, $UseDPP, $UseRecommendedPOTCAR) = @_; $UseRecommendedPOTCAR = 0 if(!defined $UseRecommendedPOTCAR); $name =~ s/\{[^\}]*\}//; my $PotDir; my $lcF = lc $Functional; if($lcF eq 'gga') { $PotDir = Deps::MakePath($VASPDBDir, "pot_GGA", 0); } elsif($lcF eq 'paw') { $PotDir = Deps::MakePath($VASPDBDir, "potpaw", 0); } elsif($lcF eq 'paw_gga') { $PotDir = Deps::MakePath($VASPDBDir, "potpaw_GGA", 0); } elsif($lcF eq 'paw_pbe') { $PotDir = Deps::MakePath($VASPDBDir, "potpaw_PBE", 0); } elsif($lcF eq 'paw_lda52') { $PotDir = Deps::MakePath($VASPDBDir, "potpaw_LDA52", 0); } elsif($lcF eq 'paw_pbe52') { $PotDir = Deps::MakePath($VASPDBDir, "potpaw_PBE52", 0); } elsif($lcF eq 'paw_lda54') { $PotDir = Deps::MakePath($VASPDBDir, "potpaw_LDA54", 0); } elsif($lcF eq 'paw_pbe54') { $PotDir = Deps::MakePath($VASPDBDir, "potpaw_PBE54", 0); } elsif($lcF eq 'paw_lda64') { $PotDir = Deps::MakePath($VASPDBDir, "potpaw_LDA64", 0); } elsif($lcF eq 'paw_pbe64') { $PotDir = Deps::MakePath($VASPDBDir, "potpaw_PBE64", 0); } else { #us $PotDir = Deps::MakePath($VASPDBDir, "pot", 0); } my $PotDir2 = Deps::MakePath($PotDir, "elements", 0); if(-e $PotDir2) { $PotDir = $PotDir2; } print("POTCAR Dir [$PotDir] for functional [$Functional]\n"); my @POTFiles; my %POTFileNames; if($UseRecommendedPOTCAR =~ /=/) { my @a = Utils::Split("\\s*,\\s*", $UseRecommendedPOTCAR); for(my $i = 0 ; $i < @a ; $i++) { my ($atom, $file) = Utils::Split("=", $a[$i]); $POTFileNames{$atom} = $file; #print "$atom: $file\n"; } } elsif($UseRecommendedPOTCAR) { if($PPPriority{$name}) { my $p = $PPPriority{$name}; for(my $i = 0 ; $i < @$p ; $i++) { my $PotcarFile = Deps::MakePath($PotDir, [$p->[$i], "POTCAR"], 0); #print "f[$i] [$PotcarFile]\n"; if(-f $PotcarFile) { #print " OK\n"; push(@POTFiles, $PotcarFile); } } return @POTFiles if(@POTFiles > 0); } } my $PotcarDir; my $PotcarFile; if($POTFileNames{$name}) { $PotcarDir = Deps::MakePath($PotDir, $POTFileNames{$name}, 0); $PotcarFile = Deps::MakePath($PotcarDir, "POTCAR", 0); #print "F: $PotcarFile\n"; push(@POTFiles, $PotcarFile); } else { $PotcarDir = Deps::MakePath($PotDir, "${name}_d", 0); if($UseDPP eq '') { $PotcarDir = Deps::MakePath($PotDir, $name, 0); } $PotcarFile = Deps::MakePath($PotcarDir, "POTCAR", 0); unless(-e $PotcarFile) { $PotcarDir = Deps::MakePath($PotDir, $name, 0); $PotcarFile = Deps::MakePath($PotcarDir, "POTCAR", 0); } if(-e $PotcarFile) { push(@POTFiles, $PotcarFile); } foreach my $suffix ("_sv_new", "_sv", "_pv_new", "_pv", "_s_new", "_s", "_h_new", "_h", "_2_new", "_2", "_3_new", "_3", "1.25_new", "1.25") { $PotcarDir = Deps::MakePath($PotDir, "${name}${suffix}", 0); $PotcarFile = Deps::MakePath($PotcarDir, "POTCAR", 0); #print "f [$PotcarFile]\n"; if(-e $PotcarFile) { push(@POTFiles, $PotcarFile); } } } return (@POTFiles); } sub MakePOTCARFile { my ($this, $Crystal, $Functional, $UseDPP, $fname, $pParams) = @_; #print "VASP Old Dir [$VASPProgOldDir]
\n"; print "

Make POTCAR

\n"; my @AtomTypeList = $Crystal->GetCAtomTypeList(); #for(my $i = 0 ; $i < @AtomTypeList ; $i++) { # print "MakePOTCARFile: atom[$i] = ", $AtomTypeList[$i]->AtomNameOnly(), "$LF"; #} my $nAtomType = @AtomTypeList; #ファイル作製開始 if(defined $fname) { unless(open(OUT,">$fname")) { print "Can not write to $fname.$LF$LF"; return 0; } binmode(OUT); } my @POTFiles; for(my $i = 0 ; $i < $nAtomType ; $i++) { my $atom = $AtomTypeList[$i]; # my $name = $atom->Label(); my $name = $atom->AtomNameOnly(); my @POTRecommendations = $this->GetPOTCARList( $name, $Functional, $UseDPP, $pParams->{UseRecommendedPOTCAR}); if(@POTRecommendations == 0) { print "Error in VASP::MakePOTCARFile: Potential for [$name] not found.\n"; print " [$Functional][UseDPP=$UseDPP][UseRecommended=$pParams->{UseRecommendedPOTCAR}]\n"; print("\nPress ENTER to exit>>\n"); ; exit(); } my $PotcarFile = $POTRecommendations[0]; push(@POTFiles, $PotcarFile); #print " [$PotcarFile] is used for [$name]\n"; if(defined $fname) { unless(open(IN, "<$PotcarFile")) { print "

Error: Can not read [$PotcarFile]!!

\n"; return -1; } print "Use $PotcarFile for [$name].
\n"; while() { print OUT $_; } close(IN); } } if(defined $fname) { close(OUT); } return ($fname, @POTFiles); } sub ModifyPOSCARFile { my ($this, $POSCARPath, $A, $a, $b, $c, $alpha, $beta, $gamma, %args) = @_; my $in = new JFile(); my $plines = $in->ReadFileToLines($POSCARPath); my @lines = @$plines; #print join(', ', @lines); my $Function = $this->Args()->GetGetArg("Function"); $Function = 'scf' if($Function eq ''); # my $out = new JFile("${POSCARPath}.new", "w"); my $out = new JFile("${POSCARPath}", "w"); if(!$out) { print "Error in VASP::ModifyPOSCARFile: Can not write to [$POSCARPath].\n"; return undef; } #Si $out->print($lines[0]); my $Crystal = new Crystal; my $A0 = $lines[1] + 0.0; my ($a11, $a12, $a13) = Utils::Split("\\s+", $lines[2]); my ($a21, $a22, $a23) = Utils::Split("\\s+", $lines[3]); my ($a31, $a32, $a33) = Utils::Split("\\s+", $lines[4]); #print "A: $A0, $a11, $a12, $a13, $a21, $a22, $a23, $a31, $a32, $a33\n"; $Crystal->SetLatticeVector($A0*$a11, $A0*$a12, $A0*$a13, $A0*$a21, $A0*$a22, $A0*$a23, $A0*$a31, $A0*$a32, $A0*$a33); my ($a0, $b0, $c0, $alpha0, $beta0, $gamma0) = $Crystal->LatticeParameters(); #print "($a0, $b0, $c0, $alpha0, $beta0, $gamma0)\n"; print "Positions: $args{Positions}\n"; my @a = Utils::Split('\s*;\s*', $args{Positions}); my @NewXYZ; for(my $i = 0; $i < @a ; $i++) { my ($isite, $xyz, $coord) = Utils::Split('\s*:\s*', $a[$i]); if($xyz eq 'x') { $xyz = 0; } elsif($xyz eq 'y') { $xyz = 1; } elsif($xyz eq 'z') { $xyz = 2; } else { next; } print " $i: No.$isite xyz[$xyz] = $coord\n"; $NewXYZ[$isite][$xyz] = $coord; } $A0 = ($A)? $A : $A0; $a0 = ($a)? $a : $a0; $b0 = ($b)? $b : $b0; $c0 = ($c)? $c : $c0; $alpha0 = ($alpha)? $alpha : $alpha0; $beta0 = ($beta)? $beta : $beta0; $gamma0 = ($gamma)? $gamma : $gamma0; $Crystal->SetLatticeParameters($a0, $b0, $c0, $alpha0, $beta0, $gamma0); ($a11, $a12, $a13, $a21, $a22, $a23, $a31, $a32, $a33) = $Crystal->LatticeVectors(); # 5.40640000000000 # 1.0113565403215667 0.0000000000000000 -0.0000000000000000 # 0.0000000000000000 1.0113565403215667 -0.0000000000000000 # 0.0000000000000000 0.0000000000000000 1.0113565403215667 $out->print("$A0\n"); $out->printf(" %21.18f %21.18f %21.18f\n", $a11/$A0, $a12/$A0, $a13/$A0); $out->printf(" %21.18f %21.18f %21.18f\n", $a21/$A0, $a22/$A0, $a23/$A0); $out->printf(" %21.18f %21.18f %21.18f\n", $a31/$A0, $a32/$A0, $a33/$A0); my $iLine = 5; # Cl Na Sn $out->print($lines[$iLine++]) if($lines[$iLine] !~ /^[\s\d]+$/); # 8 8 1 #Selective dynamics #Direct $out->print($lines[$iLine++]); if($Function ne 'phonon' and $lines[$iLine] =~ /dynamics/) { $iLine++; } else { $out->print($lines[$iLine++]) } $out->print($lines[$iLine++]); for(my $is = 0 ; ; $is++) { my $idx = $is + $iLine; last if(!defined $lines[$idx]); #print("$is: ", $lines[$idx]); my ($x, $y, $z, $idx, $idy, $idz) = Utils::Split('\s+', $lines[$idx]); if($idz eq 'T' or $idz eq 'F') { } else { $out->print($lines[$idx]); next; } if(defined $NewXYZ[$is]) { $x = $NewXYZ[$is][0] if(defined $NewXYZ[$is][0]); $y = $NewXYZ[$is][1] if(defined $NewXYZ[$is][1]); $z = $NewXYZ[$is][2] if(defined $NewXYZ[$is][2]); } # $out->print($lines[$idx]); # 0.500000000 0.500000000 0.000000000 T T T printf("$is: %14.9f %14.9f %14.9f %s %s %s\n", $x, $y, $z, $idx, $idy, $idz); $out->printf(" %14.9f %14.9f %14.9f %s %s %s\n", $x, $y, $z, $idx, $idy, $idz); } $out->Close(); } sub ModifyPOSCARFile2 { my ($this, $Function, $InputFile, $OutputFile, %hash) = @_; #print "p=$Function, $InputFile, $OutputFile, %hash\n"; unlink($OutputFile); my $plines = JFile->new()->ReadFileToLines($InputFile); my @lines = @$plines; return undef if(@lines == 0); my $out = new JFile; $out->Open($OutputFile, "w") or return undef; my $iline = 0; #Si # 5.40640000000000 # 1.0113565403215667 0.0000000000000000 -0.0000000000000000 # 0.0000000000000000 1.0113565403215667 -0.0000000000000000 # 0.0000000000000000 0.0000000000000000 1.0113565403215667 $out->print($lines[$iline++]); $out->print($lines[$iline++]); $out->print($lines[$iline++]); $out->print($lines[$iline++]); # Si # 8 $out->print($lines[$iline++]); $out->print($lines[$iline]); #print "l**: $lines[$iline]\n"; if($lines[$iline] =~ /[a-zA-Z]/) { $iline++; $out->print($lines[$iline]); } #print "l**: $lines[$iline]\n"; my (@nAtoms) = Utils::Split("\\s+", $lines[$iline++]); print("VASP::ModifyPOSCARFile: nAtoms: ", join(', ', @nAtoms), "\n"); #Selective dynamics #Direct if($Function =~ /phonon/ and $lines[$iline] =~ /selective/i) { $iline++; } else { $out->print($lines[$iline++]) } $out->print($lines[$iline++]); for(my $i = 0 ; $i < @nAtoms ; $i++) { for(my $j = 0 ; $j < $nAtoms[$i] ; $j++) { $out->print($lines[$iline++]); } } if(!$hash{InitializeVelocity}) { while(1) { last if(!defined $lines[$iline]); $out->print($lines[$iline++]); } } $out->Close(); } sub ModifyINCARFile { my ($this, $Function, $InputFile, $OutputFile, $AllSeparated, $MinEnergy, $MaxEnergy, $DOSMeasuredFromEF, $FromScratch, $Precision, $KeepSymmetry, $nMesh, $SpinPolarized, $PStress, $pParamHash, $NBANDS, $NELECT, $pParams) = @_; $Precision = "Normal" if($Precision eq ''); $KeepSymmetry = 0 if($KeepSymmetry eq ''); if($SpinPolarized ne '') { $SpinPolarized = 1 if($SpinPolarized eq 'No'); $SpinPolarized = 2 if($SpinPolarized eq 'Yes'); } if($pParams->{HybridFunctional} ne '') { $pParamHash->{LHFCALC} = ".TRUE."; } #print "0: HybridFunctional=[$pParams->{HybridFunctional}]\n"; #print "0: LHFCALC=[$pParamHash->{LHFCALC}]\n"; if(!defined $pParams->{METAGGA}) { $pParams->{METAGGA} = ''; } # $PStress = 0 if($PStress eq ''); Utils::DelSpace($MinEnergy); Utils::DelSpace($MaxEnergy); $DOSMeasuredFromEF = 1 if(!defined $DOSMeasuredFromEF or $DOSMeasuredFromEF eq ''); if($pParams->{HybridFunctional}) { # $pParams->{IBRION} = 5 if($pParams->{IBRION} == 7); # $pParams->{IBRION} = 6 if($pParams->{IBRION} == 8); } # my $v = $this->ReadKeyValue("NBANDS\\s*=\\s*(\\S+)", undef, $OUTCAR); my $POSCAR = $this->GetPOSCARFileName($InputFile); if($NBANDS) { my $v = $this->EstimateDefaultNBANDS($POSCAR); my $v = $this->GetTotalValenceElectrons($POSCAR); if($NBANDS =~ /^\-(.*)$/) { $NBANDS = $v - $1; } elsif($NBANDS =~ /^\+(.*)$/) { $NBANDS = $v + $1; } elsif($NBANDS =~ /^x(.*)$/) { $NBANDS = $v * $1; } elsif($NBANDS =~ /^\/(.*)$/) { $NBANDS = $v / $1; } $NBANDS = int($NBANDS); print "NBANDS changed from $v to $NBANDS\n"; } my $Crystal = $this->ReadStructureFromCARFiles($InputFile, 0); #print "ak=$pParams->{aKProduct}\n"; my ($nx, $ny, $nz, $NKREDX, $NKREDY, $NKREDZ) = $this->AnalyzeaKProduct($Crystal, $pParams->{aKProduct}); if($Function =~ /band/i) { $NKREDX = 1; $NKREDY = 1; $NKREDZ = 1; } print "(nx,ny,nz)=($nx,$ny,$nz)\n"; print "(NKREDX,NKREDY,NKREDZ)=($NKREDX,$NKREDY,$NKREDZ)\n"; $pParamHash->{NKREDX} = $NKREDX if(defined $NKREDX); $pParamHash->{NKREDY} = $NKREDY if(defined $NKREDY); $pParamHash->{NKREDZ} = $NKREDZ if(defined $NKREDZ); my $OUTCAR = $this->GetOUTCARFileName($InputFile); my $EF = 0; if(!$DOSMeasuredFromEF) { print(" OUTCAR : $OUTCAR\n"); $EF = $this->ReadFermiEnergy($OUTCAR); print(" EF = $EF eV\n"); if($MinEnergy ne '' and $MaxEnergy ne '') { $MinEnergy += $EF; $MaxEnergy += $EF; } print(" DOS range: $MinEnergy - $MaxEnergy eV\n"); } unless(open(IN, "<$InputFile")) { print "Can not read $InputFile.$LF$LF"; return; } my @in; while(not eof(IN)) { my $line = ; chomp($line); push(@in, $line); #print "l: $line [", scalar @in, "]\n"; } close(IN); unless(open(OUT, ">$OutputFile")) { print "Can not write to $OutputFile.$LF$LF"; return; } binmode(OUT); #print "ENCUT=[$pParams->{ENCUT}]\n"; #exit; for(my $i = 0 ; $i < @in ; $i++) { my $line = $in[$i]; #print "line: $line\n"; my ($a,$a2,$b,$c); my ($head,$key,$equal,$val,$rest); if($line =~ /#LDAUTYPE: 1:.*2:the same/) { print OUT " #LDAUTYPE: 1: Rotational invaliant LSDA+U 4:the same as 1, but LDA+U\n"; print OUT " # 2: Dudarev's LSDA+U\n"; $i++; print OUT " #LDAUTYPE = 2\n"; $i++; next; } if( ($head,$key,$equal,$val,$rest) = ($line =~ /^([\s#]*)([^=\s]*)(\s*=\s*)(\S.*)?$/) ) { #print "key: $key = $val [$pParamHash->{$key}]\n"; if(defined $pParamHash->{$key}) { if($key eq 'KPAR' and ($pParamHash->{KPAR} eq '' or $Function =~ /eDensity/)) { $head =~ s/#//; print OUT "$head#$key$equal$pParamHash->{$key}$rest\n"; } elsif($key eq 'NPAR' and $pParamHash->{NPAR} eq '') { $head =~ s/#//; print OUT "$head#$key$equal$pParamHash->{$key}$rest\n"; } else { $head =~ s/#//; print OUT "$head$key$equal$pParamHash->{$key}$rest\n"; } next; } } my $AGGAC; if( ($a,$b,$c) = ($line =~ /^(\s*SYSTEM\s*=)(.+)$/) ) { #print "b: $b\n"; $b =~ s/\([^()]+\)/($Function)/; print OUT "$a$b\n"; next; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PREC\s*=\s*)(\S+)(.*)$/) ) { if($Precision !~ /Keep/i) { print OUT "${a}$Precision$c\n"; } else { print OUT "$a$b$c\n"; } next; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISPIN\s*=\s*)(\S+)(.*)$/) ) { if($SpinPolarized ne '') { print OUT "${a}$SpinPolarized$c\n"; } else { print OUT "$a$b$c\n"; } next; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PSTRESS\s*=\s*)(\S+)(.*)$/) ) { if($PStress ne '') { $a =~ s/^(\s*)#/$1/; print OUT "${a}$PStress$c\n"; } else { print OUT "$a$b$c\n"; } next; } elsif(($a,$b,$c) = ($line =~ /^([\s#]*ENCUT\s*=\s*)(\S*)(.*)$/) ) { if($pParams->{ENCUT} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{ENCUT}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } next; } elsif(($a,$b,$c) = ($line =~ /^([\s#]*NBANDS\s*=\s*)(\S*)(.*)$/) ) { print "NBANDS=$NBANDS\n"; if($NBANDS ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$NBANDS$c\n"; } else { # $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } next; } elsif($NELECT ne '' and ($a,$b,$c) = ($line =~ /^([\s#]*NELECT\s*=\s*)(\S*)(.*)$/) ) { my $v = $this->ReadKeyValue("NELECT\\s*=\\s*(\\S+)", undef, $OUTCAR); if($NELECT =~ /^\-(.*)$/) { $NELECT = $v - $1; } elsif($NELECT =~ /^\+(.*)$/) { $NELECT = $v + $1; } elsif($NELECT =~ /^x(.*)$/) { $NELECT = $v * $1; } elsif($NELECT =~ /^\/(.*)$/) { $NELECT = $v / $1; } print "NELECT changed from $v to $NELECT$c\n"; $a =~ s/^(\s*)#/$1/; print OUT "$a$NELECT$c\n"; next; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LHFCALC\s*=\s*)(\S*)(.*)$/) ) { #print "LHFCALC=[$pParams->{LHFCALC}]\n"; #exit; if(defined $pParams->{LHFCALC}) { if($pParams->{LHFCALC} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "${a}$pParams->{LHFCALC}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; #print "1 $a$b$c\n"; #exit; } } elsif(!defined $pParams->{LHFCALC}) { # $a =~ s/^(\s*)#/$1/; # print OUT "${a}$pParams->{LHFCALC}$c\n"; $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; #print "2 $a$b$c\n"; #exit; } elsif(defined $pParams->{HybridFunctional}) { if($pParams->{HybridFunctional} eq '') { $a =~ s/^(\s*)([^#\s])/$1#$2/; } else { $a =~ s/^(\s*)#/$1/; } print OUT "${a}.TRUE.$c\n"; } elsif($pParams->{HybridFunctional} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "${a}.TRUE.$c\n"; } else { $a =~ s/^(\s*)#/$1/; print OUT "${a}$pParams->{LHFCALC}$c\n"; } next; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*AEXX\s*=\s*)(\S*)(.*)$/) ) { if(!defined $pParams->{HybridFunctional} or $pParams->{HybridFunctional} eq '') { $a =~ s/^(\s*)([^#\s])/$1#$2/; } else { $a =~ s/^(\s*)#/$1/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*AGGAC\s*=\s*)(\S*)(.*)$/) ) { $AGGAC = $b if(!defined $AGGAC); if(defined $pParams->{AGGAC}) { $AGGAC = $pParams->{AGGAC}; $a =~ s/^(\s*)#/$1/; } elsif(!defined $pParams->{HybridFunctional} or $pParams->{HybridFunctional} eq '') { $a =~ s/^(\s*)([^#\s])/$1#$2/; } else { $a =~ s/^(\s*)#/$1/; } print OUT "$a$AGGAC$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ALDAC\s*=\s*)(\S*)(.*)$/) ) { if(!defined $pParams->{HybridFunctional} or $pParams->{HybridFunctional} eq '') { $a =~ s/^(\s*)([^#\s])/$1#$2/; } else { $a =~ s/^(\s*)#/$1/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*HFSCREEN\s*=\s*)(\S*)(.*)$/) ) { if(!defined $pParams->{HybridFunctional} or $pParams->{HybridFunctional} eq '' or $pParams->{HybridFunctional} =~ /(PBE0|HF)/) { $a =~ s/^(\s*)([^#\s])/$1#$2/; } else { $a =~ s/^(\s*)#/$1/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PRECFOCK\s*=\s*)(\S*)(.*)$/) ) { if(!defined $pParams->{HybridFunctional} or $pParams->{HybridFunctional} eq '') { $a =~ s/^(\s*)([^#\s])/$1#$2/; } else { $a =~ s/^(\s*)#/$1/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IMIX\s*=\s*)(\S*)(.*)$/) ) { print "IMIX=$pParams->{IMIX}\n"; if(defined $pParams->{IMIX} and $pParams->{IMIX} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{IMIX}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NELM\s*=\s*)(\S*)(.*)$/) ) { print "NELM=$pParams->{NELM}\n"; if(defined $pParams->{NELM}) { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{NELM}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LASPH\s*=\s*)(\S*)(.*)$/) ) { print "LASPH=$pParams->{LASPH}\n"; if(defined $pParams->{LASPH} and $pParams->{LASPH} eq '.TRUE.') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{LASPH}$c\n"; } elsif(defined $pParams->{LASPH}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{LASPH}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ADDGRID\s*=\s*)(\S*)(.*)$/) ) { print "ADDGRID=$pParams->{ADDGRID}\n"; if(defined $pParams->{ADDGRID}) { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{LASPH}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*METAGGA\s*=\s*)(\S*)(.*)$/) ) { print "METAGGA=$pParams->{METAGGA}\n"; if(defined $pParams->{METAGGA} and $pParams->{METAGGA} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{METAGGA}$c\n"; } elsif(defined $pParams->{METAGGA}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{METAGGA}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*CMBJA\s*=\s*)(\S*)(.*)$/) ) { print "CMBJA=$pParams->{CMBJA}\n"; if(defined $pParams->{CMBJA} and $pParams->{CMBJA} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{CMBJA}$c\n"; } elsif(defined $pParams->{CMBJA}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{CMBJA}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*CMBJB\s*=\s*)(\S*)(.*)$/) ) { print "CMBJB=$pParams->{CMBJB}\n"; if(defined $pParams->{CMBJB} and $pParams->{CMBJB} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{CMBJB}$c\n"; } elsif(defined $pParams->{CMBJA}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{CMBJB}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*CMBJ\s*=\s*)(\S*)(.*)$/) ) { $pParams->{CMBJ} =~ s/,/ /g if(defined $pParams->{CMBJ}); print "CMBJ=$pParams->{CMBJ}\n"; if(defined $pParams->{CMBJ} and $pParams->{CMBJ} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{CMBJ}\n"; } elsif(defined $pParams->{CMBJ}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{CMBJ}\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LMAXTAU\s*=\s*)(\S*)(.*)$/) ) { print "LMAXTAU=$pParams->{LMAXTAU}\n"; if(defined $pParams->{LMAXTAU} and $pParams->{LMAXTAU} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{CMBJ}$c\n"; } elsif(defined $pParams->{LMAXTAU}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{LMAXTAU}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LMIXTAU\s*=\s*)(\S*)(.*)$/) ) { print "LMIXTAU=$pParams->{LMIXTAU}\n"; if(defined $pParams->{LMIXTAU} and $pParams->{LMIXTAU} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{LMAXTAU}$c\n"; } elsif(defined $pParams->{LMIXTAU}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{LMAXTAU}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LSORBIT\s*=\s*)(\S*)(.*)$/) ) { print "SO=$pParams->{SpinOrbit}\n"; if(defined $pParams->{SpinOrbit} and $pParams->{SpinOrbit} =~ /[1T]/i) { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{SpinOrbit}$c\n"; } elsif(defined $pParams->{SpinOrbit}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{SpinOrbit}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LNONCOLLINEAR\s*=\s*)(\S*)(.*)$/) ) { if(defined $pParams->{NonCollinear} and $pParams->{NonCollinear} =~ /[1T]/i) { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{NonCollinear}$c\n"; } elsif(defined $pParams->{NonCollinear}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{NonCollinear}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LMAXMIX\s*=\s*)(\S*)(.*)$/) ) { print "LMM=$pParams->{LMAXMIX}\n"; if(!defined $pParams->{LMAXMIX} or $pParams->{LMAXMIX} eq '') { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif(defined $pParams->{LMAXMIX} and $pParams->{LMAXMIX} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "$a$pParams->{LMAXMIX}$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$pParams->{LMAXMIX}$c\n"; } } elsif($Function =~ /band/i or $Function =~ /FS/i) { if( ($a,$b,$c) = ($line =~ /^([\s#]*ISTART\s*=\s*)(\S+)(.*)$/) ) { print OUT "${a}1$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ICHARG\s*=\s*)(\S+)(.*)$/) ) { if($pParams->{HybridFunctional} ne '' or $pParams->{METAGGA} ne '') { $a =~ s/^(\s*)#/$1/; print OUT "${a}0$c\n"; } else { $a =~ s/^(\s*)#/$1/; # print OUT "${a}10$c\n"; print OUT "${a}11$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*INIWAV\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IBRION\s*=\s*)(\S+)(.*)$/)) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LEPSILON\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LRPA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LOPTICS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*CSHIFT\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NSW\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*TIME\s*=\s*)(\S+)(.*)$/) ) { if($pParams->{HybridFunctional} ne '') { $a =~ s/^(\s*)([^#\s])/$1$2/; print OUT "$a$b$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*POTIM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISIF\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*MDALGO\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA_L\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISYM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}1$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISMEAR\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; # tetrahedron method can not be used for strings of k-points print OUT "${a}-1$c\n"; # print OUT "${a}$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SIGMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$a2,$b,$c) = ($line =~ /^([\s#]*(LPARD|NBMOD|EINT|IBNAD|KPUSE|LSEPB|LSEPK)\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } else { print OUT "$line\n"; } } elsif($Function =~ /scf/i or $Function =~ /phonon/i) { if( ($a,$b,$c) = ($line =~ /^([\s#]*ISTART\s*=\s*)(\S+)(.*)$/) ) { if($FromScratch) { print OUT "${a}0$c\n"; } else { print OUT "${a}1$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ICHARG\s*=\s*)(\S+)(.*)$/) ) { if($FromScratch) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } else { $a =~ s/#//; print OUT "${a}0$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*INIWAV\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IBRION\s*=\s*)(\S+)(.*)$/)) { if($Function =~ /phonon/ or $pParams->{CalVibration}) { $a =~ s/#//; $b = (defined $pParams->{IBRION})? $pParams->{IBRION} : 8; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NPAR\s*=\s*)(\S+)(.*)$/)) { if($Function =~ /phonon/ or $pParams->{CalVibration}) { $a =~ s/^(\s*)([^#\s])/$1#$2/; } elsif(defined $pParams->{NPAR}) { $a =~ s/#//; $b = $pParams->{NPAR}; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*MDALGO\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA_L\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NWRITE\s*=\s*)(\S+)(.*)$/) ) { if($Function =~ /phonon/ or $pParams->{CalVibration}) { $a =~ s/#//; $b = 3; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LEPSILON\s*=\s*)(\S+)(.*)$/) ) { if($Function =~ /phonon/ or $pParams->{CalVibration}) { $a =~ s/#//; $b = '.TRUE.'; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LRPA\s*=\s*)(\S+)(.*)$/) ) { if($pParams->{CalVibration}) { $a =~ s/#//; $b = (defined $pParams->{LRPA})? $pParams->{LRPA} : $b; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LOPTICS\s*=\s*)(\S+)(.*)$/) ) { if($pParams->{CalOptics}) { $a =~ s/#//; $b = '.TRUE.'; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*CSHIFT\s*=\s*)(\S+)(.*)$/) ) { if($pParams->{CalOptics}) { $a =~ s/#//; $b = (defined $pParams->{CSHIFT})? $pParams->{CSHIFT} : $b; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NSW\s*=\s*)(\S+)(.*)$/) ) { if($Function =~ /phonon/) { $a =~ s/#//; $b = 1; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*POTIM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISIF\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IBRION\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISYM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}1$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISMEAR\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SIGMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$a2,$b,$c) = ($line =~ /^([\s#]*(LPARD|NBMOD|EINT|IBNAD|KPUSE|LSEPB|LSEPK)\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } else { print OUT "$line\n"; } } elsif($Function =~ /dos/i) { if( ($a,$b,$c) = ($line =~ /^([\s#]*ISTART\s*=\s*)(\S+)(.*)$/) ) { print OUT "${a}1$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ICHARG\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; if( $pParams->{METAGGA} eq '' ) { # print OUT "${a}10$c\n"; print OUT "${a}11$c\n"; } else { print OUT "${a}0$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*INIWAV\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SIGMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IBRION\s*=\s*)(\S+)(.*)$/)) { if($pParams->{CalVibration}) { $a =~ s/#//; $b = (defined $pParams->{IBRION})? $pParams->{IBRION} : 8; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*MDALGO\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA_L\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LEPSILON\s*=\s*)(\S+)(.*)$/) ) { if($pParams->{CalVibration}) { $a =~ s/#//; $b = '.TRUE.'; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LRPA\s*=\s*)(\S+)(.*)$/) ) { if($pParams->{CalVibration}) { $a =~ s/#//; $b = (defined $pParams->{LRPA})? $pParams->{LRPA} : $b; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LOPTICS\s*=\s*)(\S+)(.*)$/) ) { if($pParams->{CalOptics}) { $a =~ s/#//; $b = '.TRUE.'; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*CSHIFT\s*=\s*)(\S+)(.*)$/) ) { if($pParams->{CalOptics}) { $a =~ s/#//; $b = (defined $pParams->{CSHIFT})? $pParams->{CSHIFT} : $b; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NSW\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*POTIM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISIF\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IBRION\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISYM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}1$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISMEAR\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SIGMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*EMIN\s*=\s*)(\S+)(.*)$/) ) { # if($MinEnergy ne '' and $MaxEnergy ne '' and $nMesh ne '') { if($MinEnergy ne '' and $MaxEnergy ne '') { $a =~ s/#//; print OUT "$a$MinEnergy$c\n"; } else { print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*EMAX\s*=\s*)(\S+)(.*)$/) ) { # if($MinEnergy ne '' and $MaxEnergy ne '' and $nMesh ne '') { if($MinEnergy ne '' and $MaxEnergy ne '') { $a =~ s/#//; print OUT "$a$MaxEnergy$c\n"; } else { print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NEDOS\s*=\s*)(\S+)(.*)$/) ) { # if($MinEnergy ne '' and $MaxEnergy ne '' and $nMesh ne '') { if($nMesh ne '') { $a =~ s/#//; print OUT "$a$nMesh$c\n"; } else { print OUT "$a$b$c\n"; } } elsif( ($a,$a2,$b,$c) = ($line =~ /^([\s#]*(LPARD|NBMOD|EINT|IBNAD|KPUSE|LSEPB|LSEPK)\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } else { print OUT "$line\n"; } } elsif($Function =~ /eDensity/i) { if( ($a,$b,$c) = ($line =~ /^([\s#]*ISTART\s*=\s*)(\S+)(.*)$/) ) { print OUT "${a}1$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*KPAR\s*=\s*)(\S+)(.*)$/) ) { # Never entered to this line if --Param:KPAR= is active $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "#$a$b$c\n"; } # elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PREC\s*=\s*)(\S+)(.*)$/) ) { # print OUT "${a}Normal$c\n"; # } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ICHARG\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; if( $pParams->{METAGGA} eq '') { # print OUT "${a}10$c\n"; print OUT "${a}11$c\n"; } else { print OUT "${a}0$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*INIWAV\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IBRION\s*=\s*)(\S+)(.*)$/)) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*MDALGO\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA_L\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LEPSILON\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LRPA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LOPTICS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*CSHIFT\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SIGMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NSW\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*POTIM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISIF\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISYM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}1$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISMEAR\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SIGMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LPARD\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NBMOD\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; if($AllSeparated and ($MinEnergy eq '' or $MaxEnergy eq '')) { print OUT "${a}0$c\n"; } else { if($DOSMeasuredFromEF) { print OUT "${a}-3$c\n"; } else { print OUT "${a}-2$c\n"; } } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*EINT\s*=\s*)(\S+\s+\S+)(.*)$/) ) { if($AllSeparated and ($MinEnergy eq '' or $MaxEnergy eq '')) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } else { $a =~ s/#//; print OUT "${a} $MinEnergy $MaxEnergy$c\n"; } } elsif( ($a,$a2,$b,$c) = ($line =~ /^([\s#]*(LSEPB|LSEPK)\s*=\s*)(\S+)(.*)$/) ) { if($AllSeparated) { $a =~ s/#//; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; } print OUT "$a$b$c\n"; } else { print OUT "$line\n"; } } elsif($Function =~ /md/i) { if( ($a,$b,$c) = ($line =~ /^([\s#]*ISTART\s*=\s*)(\S+)(.*)$/) ) { if($FromScratch) { print OUT "${a}0$c\n"; } else { print OUT "${a}1$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ICHARG\s*=\s*)(\S+)(.*)$/) ) { if($FromScratch) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } else { $a =~ s/#//; print OUT "${a}0$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*INIWAV\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISIF\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; if($Function =~ /vc/i) { print OUT "${a}3$c\n"; } else { print OUT "${a}0$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IBRION\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}0$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NSW\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*MDALGO\s*=\s*)(\S+)(.*)$/) ) { if($Function =~ /vc/i) { $a =~ s/#//; print OUT "${a}3\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA\s*=\s*)(\S+)(.*)$/) ) { if($Function =~ /vc/i) { $a =~ s/#//; print OUT "$a$b$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA_L\s*=\s*)(\S+)(.*)$/) ) { if($Function =~ /vc/i) { $a =~ s/#//; print OUT "$a$b$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PMASS\s*=\s*)(\S+)(.*)$/) ) { if($Function =~ /vc/i) { $a =~ s/#//; print OUT "$a$b$c\n"; } else { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISYM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}$KeepSymmetry$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*POTIM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*TEBEG\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*TEEND\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PSTRESS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*POMASS\s*=\s*)(\S+)(.*)$/) ) { # $a =~ s/#//; $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ZVAL\s*=\s*)(\S+)(.*)$/) ) { # $a =~ s/#//; $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } else { print OUT "$line\n"; } } elsif($Function =~ /relax/i) { if( ($a,$b,$c) = ($line =~ /^([\s#]*ISTART\s*=\s*)(\S+)(.*)$/) ) { if($FromScratch) { print OUT "${a}0$c\n"; } else { print OUT "${a}1$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ICHARG\s*=\s*)(\S+)(.*)$/) ) { if($FromScratch) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } else { $a =~ s/#//; print OUT "${a}0$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*INIWAV\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NSW\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISIF\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; if($Function =~ /vc-relax/i) { print OUT "${a}3$c\n"; } else { print OUT "${a}2$c\n"; } } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*MDALGO\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; # $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; # $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LANGEVIN_GAMMA_L\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; # $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*PMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; # $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*POMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; # $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ZVAL\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; # $a =~ s/#//; print OUT "$a$b$c\n"; } # elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IBRION\s*=\s*)(\S+)(.*)$/)) { # $a =~ s/#//; ## $a =~ s/^(\s*)([^#\s])/$1#$2/; # print OUT "$a$b$c\n"; # } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*IBRION\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}2$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*NBLOCK\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; # $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*TEBEG\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; # $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*TEEND\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; # $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*POTIM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISYM\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}$KeepSymmetry$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SMASS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; print OUT "${a}-3$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LEPSILON\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LRPA\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*LOPTICS\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*CSHIFT\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ISMEAR\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/#//; # if($pParams->{HybridFunctional} ne '') { # print OUT "${a}$pParams->{ISMEARHybridFunctional}$c\n"; # } # else { print OUT "${a}$b$c\n"; # } # $a =~ s/^(\s*)([^#\s])/$1#$2/; # print OUT "$a$b$c\n"; } elsif( ($a,$b,$c) = ($line =~ /^([\s#]*SIGMA\s*=\s*)(\S+)(.*)$/) ) { # $a =~ s/^(\s*)([^#\s])/$1#$2/; $a =~ s/#//; # if($pParams->{HybridFunctional} ne '') { # print OUT "${a}$pParams->{SIGMAHybridFunctionl}$c\n"; # } # else { print OUT "$a$b$c\n"; # } } elsif( ($a,$a2,$b,$c) = ($line =~ /^([\s#]*(LPARD|NBMOD|EINT|IBAND|KPUSE|LSEPB|LSEPK)\s*=\s*)(\S+)(.*)$/) ) { $a =~ s/^(\s*)([^#\s])/$1#$2/; print OUT "$a$b$c\n"; } else { print OUT "$line\n"; } } } close(OUT); } sub ReadElementFromPOT { my ($this, $potfile) = @_; unless(open(IN,"<$potfile")) { print "ReadElementFromPOT: Can not read [$potfile].$LF$LF"; return -1; } binmode(IN); my $line = ; my ($val) = ($line =~ /US\s*(\S+)/i); ($val) = ($line =~ /PAW_PBE\s+(\S+)/i) if($val eq ''); ($val) = ($line =~ /PAW\s+(\S+)/i) if($val eq ''); $val =~ s/\_.*$//; close(IN); return $val; } sub ReadRWIGSFromPOT { my ($this, $potfile) = @_; unless(open(IN,"<$potfile")) { print "ReadRWIGSFromPOT: Can not read [$potfile].$LF$LF"; return -1; } binmode(IN); my $val; while(!eof(IN)) { my $line = ; ($val) = ($line =~ /RWIGS\s*=\s*(\S+)\s+?wigner/i); last if(defined $val); } close(IN); return $val; } sub ReadSystemName { my ($this, $infile) = @_; $infile = $this->GetINCARFileName($infile); #print "in: $infile\n"; my $pHash = $this->ReadINCARtoHash($infile); return undef if(!defined $pHash->{SYSTEM}); $pHash->{SYSTEM} =~ s/(\s+\[.*$)//; Utils::DelSpace($pHash->{SYSTEM}); return $pHash->{SYSTEM}; } sub GetFileNameFromSystemName { my ($this, $dir, $ext) = @_; my $fname = $this->ReadSystemName($dir); return undef if(!defined $fname); #print "f: $fname\n"; my ($drive, $directory, $filename, $ext1, $lastdir, $filebody) = Deps::SplitFilePath($dir); $ext = $ext1 if(!defined $ext); return Utils::ConvertToValidFileName(Deps::MakePath("$drive$directory", "$fname$ext", 0)); } sub LatticeConversionForDensityFile { my ($this, $InputVASPFile, $ConvertedVASPFile, $NewCrystal, $T, $tRT) = @_; my $Tinv = $tRT->inverse(); #&PrintMatrix("FCC to Primitive coordinate matrix:\n", $Tinv); my $pDensity = $this->ReadDensityFileToHash($InputVASPFile); print "Title: [$pDensity->{Title}]\n"; my ($a11,$a12,$a13,$a21,$a22,$a23,$a31,$a32,$a33) = $NewCrystal->LatticeVectors(); $pDensity->{Base} = $a11; ($pDensity->{a11}, $pDensity->{a12}, $pDensity->{a13}) = ($a11/$a11, $a12/$a11, $a13/$a11); ($pDensity->{a21}, $pDensity->{a22}, $pDensity->{a23}) = ($a21/$a11, $a22/$a11, $a23/$a11); ($pDensity->{a31}, $pDensity->{a32}, $pDensity->{a33}) = ($a31/$a11, $a32/$a11, $a33/$a11); my @AtomType = $NewCrystal->GetCAtomTypeList(); my @site = $NewCrystal->GetCAsymmetricAtomSiteList(); my %nAtoms; for(my $i = 0 ; $i < @site ; $i++) { my $type = lc $site[$i]->AtomNameOnly(); $nAtoms{$type}++; #print "i=$i: $type\n"; } my @nAtoms; my @pos; my $ic = 0; for(my $i = 0 ; $i < @AtomType ; $i++) { my $name = lc $AtomType[$i]->AtomNameOnly(); $nAtoms[$i] = $nAtoms{$name}; #print "i=$i: $name\n"; for(my $is = 0 ; $is < @site ; $is++) { my $name1 = lc $site[$is]->AtomNameOnly(); next if($name ne $name1); my ($x, $y, $z) = $site[$is]->Position(); $pos[$ic] = [$x, $y, $z]; $ic++; } } $pDensity->{pnAtoms} = \@nAtoms; $pDensity->{pAtomPos} = \@pos; my $pPrimValues = $pDensity->{pValues}; my @ConvValues; my $v = new Math::MatrixReal(3, 1); for(my $ix = 0 ; $ix < $pDensity->{nx} ; $ix++) { for(my $iy = 0 ; $iy < $pDensity->{ny} ; $iy++) { for(my $iz = 0 ; $iz < $pDensity->{nz} ; $iz++) { my $x = $ix / $pDensity->{nx}; my $y = $iy / $pDensity->{ny}; my $z = $iz / $pDensity->{nz}; $v->assign(1, 1, $x); $v->assign(2, 1, $y); $v->assign(3, 1, $z); my $v2 = $T * $v; my ($x2, $y2, $z2) = ($v2->element(1,1), $v2->element(2,1), $v2->element(3,1)); my $v = Algorism::InterpolateValuesInCube( $pDensity->{nx}, $pDensity->{ny},$pDensity->{nz}, $pPrimValues, $x2, $y2, $z2); $ConvValues[$ix][$iy][$iz] = $v; #printf "$ix,$iy,$iz: (%g,%g,%g) => (%g,%g,%g)\n", $x, $y, $z, $x2, $y2, $z2; #print "($ix,$iy,$iz) => ($ix2,$iy2,$iz2)\n"; } } } $pDensity->{pValues} = \@ConvValues; $this->SaveDensityFileFromHash($ConvertedVASPFile, $pDensity); } # Charge density * Vcell is returned in $hash{pValues} sub ReadDensityFileToHash { my ($this, $path, $CoreChargePath) = @_; my $pCore; if($CoreChargePath) { print "Read Core Charge from [$CoreChargePath]\n"; $pCore = $this->ReadDensityFileToHash($CoreChargePath); return undef if(!$pCore); } print "Read Charge from [$path]\n"; my %hash; my $in = new JFile; return undef if(!$in->Open($path, "r")); my $line = $in->ReadLine(); $hash{Title} = Utils::DelSpace($line); $line = $in->ReadLine(); $hash{Base} = $line + 0.0; ($hash{a11}, $hash{a12}, $hash{a13}) = Utils::Split("\\s+", $in->ReadLine()); ($hash{a21}, $hash{a22}, $hash{a23}) = Utils::Split("\\s+", $in->ReadLine()); ($hash{a31}, $hash{a32}, $hash{a33}) = Utils::Split("\\s+", $in->ReadLine()); $line = $in->ReadLine(); if($line !~ /^(\d\s)$/) { $line =~ s/[\r\n]+$//; $hash{Atoms} = $line; $line = $in->ReadLine() } my @nAtoms = Utils::Split("\\s+", $line); $hash{pnAtoms} = \@nAtoms; $line = $in->ReadLine(); $hash{LatticeMode} = Utils::DelSpace($line); my @AtomPos; my $ic = 0; for(my $i = 0 ; $i < @nAtoms ; $i++) { for(my $j = 0 ; $j < $nAtoms[$i] ; $j++) { my ($x, $y, $z) = Utils::Split("\\s+", $in->ReadLine()); $AtomPos[$ic] = [$x, $y, $z]; $ic++; } } $hash{pAtomPos} = \@AtomPos; $in->ReadLine(); ($hash{nx}, $hash{ny}, $hash{nz}) = Utils::Split("\\s+", $in->ReadLine()); my ($ix, $iy, $iz) = (0, 0, 0); my @t; my @v; while(1) { $line = $in->ReadLine(); last if(!defined $line); my @a = Utils::Split("\\s+", $line); last if(@a == 0); push(@t, @a); } my $c = 0; my $sum = 0.0; for(my $iz = 0 ; $iz < $hash{nz} ; $iz++) { # for(my $ix = 0 ; $ix < $hash{nx} ; $ix++) { for(my $iy = 0 ; $iy < $hash{ny} ; $iy++) { for(my $ix = 0 ; $ix < $hash{nx} ; $ix++) { # for(my $iz = 0 ; $iz < $hash{nz} ; $iz++) { $v[$ix][$iy][$iz] = $t[$c] + 0.0; $sum += $v[$ix][$iy][$iz]; $c++; } } } $hash{pValues} = \@v; $in->Close(); if($pCore) { print "Merge Valence and Core Charges\n"; $sum = 0.0; for(my $iz = 0 ; $iz < $hash{nz} ; $iz++) { for(my $iy = 0 ; $iy < $hash{ny} ; $iy++) { for(my $ix = 0 ; $ix < $hash{nx} ; $ix++) { # $sum += $v[$ix][$iy][$iz]; $v[$ix][$iy][$iz] += $pCore->{pValues}[$ix][$iy][$iz]; $sum += $v[$ix][$iy][$iz]; } } } } $hash{Sum} = $sum; # $hash{Sum} = Algorism::Integrate3D($hash{nx}, $hash{ny}, $hash{nz}, $hash{pValues}); #print "sum=$sum / $hash{Sum}\n"; #exit; return \%hash; } sub SaveDensityFileFromHash { my ($this, $path, $phash) = @_; my $out = new JFile; return undef if(!$out->Open($path, "w")); $out->print("$phash->{Title}\n"); $out->printf("%6.4f\n", $phash->{Base}); $out->printf(" %10.6f %10.6f %10.6f\n", $phash->{a11}, $phash->{a12}, $phash->{a13}); $out->printf(" %10.6f %10.6f %10.6f\n", $phash->{a12}, $phash->{a22}, $phash->{a23}); $out->printf(" %10.6f %10.6f %10.6f\n", $phash->{a13}, $phash->{a32}, $phash->{a33}); my $pnAtoms = $phash->{pnAtoms}; for(my $i = 0 ; $i < @$pnAtoms ; $i++) { $out->printf(" %4d", $pnAtoms->[$i]); } $out->print("\n"); $out->print("$phash->{LatticeMode}\n"); my $pAtomPos = $phash->{pAtomPos}; for(my $i = 0 ; $i < @$pAtomPos ; $i++) { $out->printf(" %9.6f %9.6f %9.6f\n", $pAtomPos->[$i][0], $pAtomPos->[$i][1], $pAtomPos->[$i][2]); } $out->print("\n"); $out->printf(" %d %d %d\n", $phash->{nx}, $phash->{ny}, $phash->{nz}); my $pv = $phash->{pValues}; my $ic = 0; for(my $ix = 0 ; $ix < $phash->{nx} ; $ix++) { for(my $iy = 0 ; $iy < $phash->{ny} ; $iy++) { for(my $iz = 0 ; $iz < $phash->{nz} ; $iz++) { $out->printf(" %11.4g", $pv->[$ix][$iy][$iz]); $ic++; if($ic % 10 == 0) { $out->print("\n"); } } } } $out->Close(); } sub ReadINCARtoHash { my ($this, $infile) = @_; $infile = $this->GetINCARFileName($infile); my $in = new JFile; if(!$in->Open($infile, "r")) { print("Error in ReadINCARtoHash: Can not read [$infile].\n"); return undef; } my %hash; while(1) { my $line = $in->ReadLine(1); last if(!defined $line); next if($line =~ /^#/); $line =~ s/#.*$//; if($line =~ /^Source:\s*(\S.*)\s*/) { $hash{Source} = $1; next; } my ($key, $val) = ($line =~ /^\s*(\S+)\s*=\s*(.*)$/); # my ($key, $val) = ($line =~ /^\s*(\S+)\s*=\s*(\S*)/); $val =~ s/#.*$// if(defined $val); Utils::DelSpace($val); next if(!defined $key); $hash{$key} = $val; #print("$key: $val\n"); } $in->Close(); if(defined $hash{ISPIN} and $hash{ISPIN} == 2) { $this->{IsSpinPolarized} = 1; } else { $this->{IsSpinPolarized} = 0; } return \%hash; } sub ReadKPOINTStoHash { my ($this, $infile) = @_; print "VASP::ReadKPOINTStoHash from [$infile]\n"; my $pHash = $this->ReadINCARtoHash($infile); my $ISPIN = $pHash->{ISPIN}; my $IsHF = ($pHash->{LHFCALC} =~ /T/i)? 1 : 0; print "VASP::ReadKPOINTStoHash: IsHF=$IsHF.\n"; my $in = new JFile; if(!$in->Open($infile, "r")) { print("Error in ReadKPOINTStoHash: Can not read [$infile].\n"); return undef; } my %hash; my $s = ''; my $line = $in->ReadLine(); $s .= $line; Utils::DelSpace($line); $hash{Title} = $line; $line = $in->ReadLine(); $s .= $line; Utils::DelSpace($line); $hash{nKPoints} = $line; $line = $in->ReadLine(); $s .= $line; Utils::DelSpace($line); $hash{KPointMode} = $line; if($hash{KPointMode} =~ /^rec/i or $hash{KPointMode} =~ /^dir/i) { $hash{LatticeMode} = $line; } else { $line = $in->ReadLine(); $s .= $line; Utils::DelSpace($line); $hash{LatticeMode} = $line; } while(1) { my $line = $in->ReadLine(); last if(!defined $line); $s .= $line; } $in->Close(); $hash{KPOINTS} = $s; return \%hash; } sub ReadPOTCARtoHash { my ($this, $infile) = @_; $infile = $this->GetPOTCARFileName($infile); my $in = new JFile; if(!$in->Open($infile, "r")) { print("Error in ReadPOTCARtoHash: Can not read [$infile].\n"); return undef; } my %hash = (FileName => $infile); my $count = 0; while(1) { my $PPKey = "PseudoPotential$count"; my $line = $in->ReadLine(); Utils::DelSpace($line); $hash{$PPKey} = $line; $hash{PseudoPotential} = $line . "\n"; my ($AtomName) = ($line =~ / ([A-Z][a-z]?)/); my $PPHashKey = "PseudoPotential${count}Hash"; $line = $in->SkipTo("VRHFIN\\s*=\\s*(\\w.*)\$"); my ($VRHFIN) = ($line =~ /VRHFIN\s*=\s*(\w.*)$/); $hash{$PPHashKey} = {AtomName => $AtomName, VRHFIN => $VRHFIN}; while(1) { $line = $in->ReadLine(); Utils::DelSpace($line); if($line eq 'Description') { last; } #print "l: $line\n"; if($line =~ /(\w+)\s*=\s*([\+\-\.\w]+)\s*;\s*(\w+)\s*=\s*([\+\-\.\w]+)/) { my ($key1, $val1, $key2, $val2) = ($1, $2, $3, $4); if($key1 eq $key2) { $key1 .= '1'; $key2 .= '2'; } #print "$key1=$val1; $key2=$val2\n"; $hash{$PPHashKey}{$key1} = $val1; $hash{$PPHashKey}{$key2} = $val2; } elsif($line =~ /(\w+)\s*=\s*([\+\-\.\w]+)/) { my ($key1, $val1) = ($1, $2); #print "$key1=$val1\n"; $hash{$PPHashKey}{$key1} = $val1; } } $line = $in->SkipTo("\\s*End of Dataset"); last if(!defined $line); $count++; } $in->Close(); return \%hash; } sub EstimateDefaultNBANDS { my ($this, $infile) = @_; my $NIONS = $this->GetNIONS($infile, 1); my $NELE = $this->GetTotalValenceElectrons($infile); my $NBANDS = int( ($NIONS + $NELE + 0.5) / 2.0 ); $NBANDS = 8 if($NBANDS < 8); return $NBANDS; } sub GetNIONS { my ($this, $infile, $ConsiderOccupancy) = @_; $ConsiderOccupancy = 0 if(!defined $ConsiderOccupancy); my $Crystal = $this->ReadStructureFromCARFiles($infile); # my @AtomTypeList = $Crystal->GetCAtomTypeList(); my @AtomSiteList = $Crystal->GetCExpandedAtomSiteList(); return @AtomSiteList if(!$ConsiderOccupancy); my $n = 0; for(my $i = 0 ; $i < @AtomSiteList ; $i++) { my $site = $AtomSiteList[$i]; $n += $site->Occupancy(); } return $n; } sub GetTotalValenceElectrons { my ($this, $infile) = @_; return undef if(!-f $infile); #print "in:$infile GetTotalValenceElectrons\n"; my $POTCAR = $this->GetPOTCARFileName($infile); my $POSCAR = $this->GetPOSCARFileName($infile); #print "POSCAR=[$POSCAR]\n"; #print "POTCAR=[$POTCAR]\n"; my $pPOT = $this->ReadPOTCARtoHash($POTCAR); my $pPOS = $this->ReadPOSCARtoHash($POSCAR); my $pn = $pPOS->{pnAtomsForEachSite}; my $pAtomType = $pPOS->{pAtomType}; # my $pAtomSite = $pPOS->{pAtomSite}; my $nVEL = 0; for(my $i = 0 ; $i < @$pn ; $i++) { my $atom = $pAtomType->[$i]; my $occ = $atom->Occupancy(); my $key = "PseudoPotential$i"; my $p = $pPOT->{"${key}Hash"}; $nVEL += $pn->[$i] * $p->{ZVAL} * $occ; #print "VASP:pm: GetTotalValenceElectrons: Atom#$i: n(site)=$pn->[$i]: " # ."$p->{AtomName}: ZVAL = $p->{ZVAL}: nVEL = $nVEL\n"; } return $nVEL; } sub GetFinalIonCharges { my ($this, $infile) = @_; my $OUTCARPath = $this->GetOUTCARFileName($infile); my $pOUT = $this->ReadOUTCARtoHash($OUTCARPath); my $pCharge = $pOUT->{pCharge}; my $pMagnetization = $pOUT->{pMagnetization}; my $pPOT = $this->ReadPOTCARtoHash($infile); my $pPOS = $this->ReadPOSCARtoHash($infile); my $pn = $pPOS->{pnAtomsForEachSite}; my $isite = 0; my (@AtomName, @SiteIndex, @Charge, @Magnetization, @ZVAL); for(my $i = 0 ; $i < @$pn ; $i++) { my $key = "PseudoPotential$i"; my $p = $pPOT->{"${key}Hash"}; for(my $j = 0 ; $j < $pn->[$i] ; $j++) { print "$i: $pn->[$i]: $p->{AtomName}: nVEL = $p->{ZVAL} ($pCharge->[$isite])\n"; $AtomName[$isite] = $p->{AtomName}; $ZVAL[$isite] = $p->{ZVAL}; $Charge[$isite] = $p->{ZVAL} - $pCharge->[$isite] if(defined $pCharge->[$isite]); $Magnetization[$isite] = $pMagnetization->[$isite] if(defined $pMagnetization->[$isite]); $SiteIndex[$isite] = $i; $isite++; } } return (\@AtomName, \@SiteIndex, \@Charge, \@Magnetization, \@ZVAL); } sub ReadBaderOuttoHash { my ($this, $dir) = @_; $dir = Deps::ExtractDirectory($dir) if(-f $dir); my $InFile = Deps::MakePath($dir, "Bader.out", 0); print "Bader.out [$InFile]\n"; return undef if(!-f $InFile); my $in = JFile->new($InFile, "r") or return undef; my $line = $in->SkipTo("AtomType:"); my ($nAtomType) = ($line =~ /:\s*(\d+)/); print "nAtomType=$nAtomType\n"; my @AtomType; for(my $i = 0 ; $i < $nAtomType ; $i++) { $line = $in->ReadLine(); my @a = Utils::Split( "\\s+", $line); $AtomType[$i]->{Name} = $a[1]; #print " $i: $AtomType[$i]->{Name}\n"; } $line = $in->SkipTo("Site:"); my ($nAtomSite) = ($line =~ /:\s*(\d+)/); print "nAtomSite=$nAtomSite\n"; my @AtomSite; for(my $i = 0 ; $i < $nAtomSite ; $i++) { $line = $in->ReadLine(); my @a = Utils::Split("[\\s\\(\\),]+", $line); $AtomSite[$i] = { Label => $a[1], x => $a[2]+0, y => $a[3]+0, z => $a[4]+0, }; #print " $i: $AtomSite[$i]->{Label} ($AtomSite[$i]->{x}, $AtomSite[$i]->{y}, $AtomSite[$i]->{z})\n"; } $in->SkipTo("Ion charges"); for(my $i = 0 ; $i < $nAtomSite ; $i++) { $line = $in->ReadLine(); my ($Z) = ($line =~ /Charge\s*=\s*(\S+)/); $AtomSite[$i]->{BaderCharge} = $Z+0; print " $i: $AtomSite[$i]->{Label} ($AtomSite[$i]->{x}, $AtomSite[$i]->{y}, $AtomSite[$i]->{z}) Z=$AtomSite[$i]->{BaderCharge}\n"; } $in->SkipTo("Ion charges re-adjusted"); for(my $i = 0 ; $i < $nAtomType ; $i++) { $line = $in->ReadLine(); my ($Z) = ($line =~ /Charge\s*=\s*(\S+)/); $AtomType[$i]->{BaderCharge} = $Z+0; print " $i: $AtomType[$i]->{Name} Z=$AtomType[$i]->{BaderCharge}\n"; } my %hash = ( DirName => $dir, nAtomType => $nAtomType, nAtomSite => $nAtomSite, pAtomType => \@AtomType, pAtomSite => \@AtomSite, ); $hash{BaderCharges} = ''; for(my $i = 0 ; $i < $nAtomSite ; $i++) { $hash{BaderCharges} .= "$AtomSite[$i]->{Label} " ."($AtomSite[$i]->{x}, $AtomSite[$i]->{y}, $AtomSite[$i]->{z}): " . Utils::Round($AtomSite[$i]->{BaderCharge}, 4) . "\n"; } for(my $i = 0 ; $i < $nAtomType ; $i++) { $hash{BaderCharges} .= "$AtomType[$i]->{Name}: " . Utils::Round($AtomType[$i]->{BaderCharge}, 4) . "\n"; } return \%hash; } sub ReadMadelungPotentialtoHash { my ($this, $dir) = @_; $dir = Deps::ExtractDirectory($dir) if(-f $dir); my $InFile1 = Deps::MakePath($dir, "LDEnergy.out", 0); my $InFile2 = Deps::MakePath($dir, "LDEnergy-modified.out", 0); my $p1 = $this->ReadMadelungPotentialtoHash1($InFile1); my $p2 = $this->ReadMadelungPotentialtoHash1($InFile2); my %hash = ( DirName => $dir, pFormalCharge => $p1, pBaderCharge => $p2, ); if($p1) { my $key = 'MP(Formal Z)'; $hash{$key} = ''; my $nAtom = $p1->{nAtom}; my $p = $p1->{pAtomSite}; for(my $i = 0 ; $i < $nAtom ; $i++) { my $p2 = $p->[$i]; $hash{$key} .= "$p2->{Name}: " . Utils::Round($p2->{MP}, 4) . "\n"; } } if($p2) { my $key = 'MP(Bader Z)'; $hash{$key} = ''; my $nAtom = $p2->{nAtom}; my $p = $p2->{pAtomSite}; for(my $i = 0 ; $i < $nAtom ; $i++) { my $p2 = $p->[$i]; $hash{$key} .= "$p2->{Name}: " . Utils::Round($p2->{MP}, 4) . "\n"; #print "$p2->{Name}: $p2->{MP} eV\n"; } } return \%hash; } sub ReadMadelungPotentialtoHash1 { my ($this, $InFile) = @_; print "Energy.out [$InFile]\n"; return undef if(!-f $InFile); my $in = JFile->new($InFile, "r") or return undef; my $line = $in->SkipTo("<>"); my $nAtom = 0; my @AtomSite; while(1) { $line = $in->SkipTo("No\\."); last if(!defined $line); my ($idx, $Name) = ($line =~ /No\.\s*(\d+)\s+(\S+)/); $line = $in->SkipTo("Madelung potential:"); my ($MP) = ($line =~ /:\s+(\S+)/); last if(!defined $MP); $AtomSite[$nAtom] = { idx => $idx+0, Name => $Name, MP => $MP+0, }; print "idx=$idx: Name=$Name MP=$MP eV\n"; $nAtom++; } my %hash = ( nAtom => $nAtom, pAtomSite => \@AtomSite, ); return \%hash; } sub ReadPOSCARtoHash { my ($this, $dir) = @_; $dir = Deps::ExtractDirectory($dir) if(-f $dir); #print "dir:[$dir]\n"; my $Crystal = $this->ReadStructureFromCARFiles($dir, 0); #print "C[$Crystal]\n"; if(!$Crystal or $Crystal <= 0) { print("Error in ReadPOSCARtoHash: Can not read [$dir].\n"); return undef; } my %hash = (DirName => $dir); my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParametersByOutputMode(0); $hash{pCrystal} = $Crystal; $hash{a} = $a; $hash{b} = $b; $hash{c} = $c; $hash{alpha} = $alpha; $hash{beta} = $beta; $hash{gamma} = $gamma; $hash{Latt} = "$a\n$b\n$c\n$alpha\n$beta\n$gamma"; $hash{Volume} = $Crystal->Volume(); $hash{Density} = $Crystal->Density(); $hash{FormulaUnit} = $Crystal->FormulaUnit(); $hash{SumChemicalComposition} = $Crystal->SumChemicalComposition(); $hash{ChemicalComposition} = $Crystal->ChemicalComposition(); my @AtomTypeList = $Crystal->GetCAtomTypeList(); my @AtomSiteList = $Crystal->GetCExpandedAtomSiteList(); $hash{pAtomType} = \@AtomTypeList; $hash{AtomTypes} = join("\n", @AtomTypeList); $hash{nAtomType} = scalar @AtomTypeList; $hash{pAtomSite} = \@AtomSiteList; $hash{nAtomSite} = scalar @AtomSiteList; $hash{AtomSites} = ''; for(my $i = 0 ; $i < @AtomSiteList ; $i++) { my $site = $AtomSiteList[$i]; my $name = $site->AtomNameOnly(); my ($x, $y, $z) = $site->Position(); my $i1 = $i; $hash{AtomSites} .= ($hash{AtomSites} eq '')? sprintf("%03d: %2s:(%4.3g,%4.3g,%4.3g)", $i1, $name, $x, $y, $z) : sprintf("\n%03d: %2s:(%4.3g,%4.3g,%4.3g)", $i1, $name, $x, $y, $z); #printf("%03d: %2s:(%4.3g,%4.3g,%4.3g)", $i1, $name, $x, $y, $z); } $hash{nAtomSite} = scalar @AtomSiteList; my $POSCARPath = $this->GetPOSCARFileName("$dir/POSCAR"); my $in = new JFile($POSCARPath, "r"); if($in) { $in->ReadLine(); $in->ReadLine(); $in->ReadLine(); $in->ReadLine(); $in->ReadLine(); my $line = $in->ReadLine(); if($line !~ /^[\s\d]+$/) { $line = $in->ReadLine(); } my @n = Utils::Split("\\s+", $line); $hash{pnAtomsForEachSite} = \@n; $in->Close(); } #print "ReadPOSCARtoHash out\n"; return \%hash; } sub ReadStructuresFromOUTCAR { my ($this, $infile, $IsPrint) = @_; $IsPrint = 1 if(!defined $IsPrint); my $Crystal = $this->ReadStructureFromCARFiles($infile); my @AtomSiteList = $Crystal->GetCExpandedAtomSiteList(); my $in = new JFile; $in->Open($infile, "r") or return (); my $line; my @Crystals; my $iCrystal = 0; while(1) { my $pos = $in->tell(); # external pressure = -80.85 kB Pullay stress = 0.00 kB $line = $in->SkipTo(" external pressure ="); my ($Pext, $PPullay) = ($line =~ /external pressure =\s*(\S+)\s*kB\s+Pullay stress =\s*(\S+)\s+kB/); #print "*Pext,pullay: $Pext, $PPullay\n"; # kinetic energy (ideal gas correction) = 39.58 kB $line = $in->SkipTo(" kinetic energy"); my ($Pkin) = ($line =~ /=\s*(\S+)/); #print "Pkin: $Pkin\n"; # Total+kin. -31.487 -46.886 -45.454 -6.709 -51.500 -11.152 $line = $in->SkipTo(" Total\\+kin\\."); my ($P11, $P22, $P33, $P23, $P13, $P12) = ($line =~ /kin\.\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/); my ($P32, $P31, $P21) = ($P23, $P13, $P12); #print "Pij: $P11,$P22,$P33\n"; $in->seek($pos); # VOLUME and BASIS-vectors are now : $line = $in->SkipTo(" VOLUME and"); # $line = $in->SkipTo(" VOLUME and BASIS-vectors are"); #print "**i=$iCrystal: l[$line]\n"; if(!defined $line) { print "Can not find \" VOLUME and BASIS-vectors are now \"\n"; last; } $line = $in->SkipTo(" direct lattice vectors "); if(!defined $line) { print "Can not find \" direct lattice vectors \"\n"; last; } $Crystals[$iCrystal] = new Crystal; $Crystals[$iCrystal]->{Pexternal} = $Pext; $Crystals[$iCrystal]->{PPullay} = $Pext; $Crystals[$iCrystal]->{Pkin} = $Pkin; $Crystals[$iCrystal]->{P11} = $P11; $Crystals[$iCrystal]->{P12} = $P12; $Crystals[$iCrystal]->{P13} = $P13; $Crystals[$iCrystal]->{P21} = $P21; $Crystals[$iCrystal]->{P22} = $P22; $Crystals[$iCrystal]->{P23} = $P23; $Crystals[$iCrystal]->{P31} = $P31; $Crystals[$iCrystal]->{P32} = $P32; $Crystals[$iCrystal]->{P33} = $P33; # $Crystals[$iCrystal]->{TMD} = $TMD; my ($a11, $a12, $a13) = Utils::Split("\\s+", $in->ReadLine()); my ($a21, $a22, $a23) = Utils::Split("\\s+", $in->ReadLine()); my ($a31, $a32, $a33) = Utils::Split("\\s+", $in->ReadLine()); print "$iCrystal: Vector($a11, $a12, $a13, $a11, $a22, $a23, $a31, $a32, $a33)\n" if($IsPrint); $Crystals[$iCrystal]->SetLatticeVector($a11, $a12, $a13, $a21, $a22, $a23, $a31, $a32, $a33); $line = $in->SkipTo(" POSITION "); $in->ReadLine(); for(my $i = 0 ; $i < @AtomSiteList ; $i++) { my $site = $AtomSiteList[$i]; $line = $in->ReadLine(1); last if($line =~ /-----/); my ($xc, $yc, $zc, $fx, $fy, $fz) = Utils::Split("\\s+", $line); my ($x, $y, $z) = $Crystals[$iCrystal]->CartesianToFractional($xc, $yc, $zc); print " Pos=($x, $y, $z) Force=($fx, $fy, $fz)\n" if($IsPrint); $Crystals[$iCrystal]->AddAtomSite($site->Label(), $site->AtomNameOnly(), $x, $y, $z, $site->Occupancy, $fx, $fy, $fz); } $Crystals[$iCrystal]->ExpandCoordinates(); $pos = $in->tell(); # FREE ENERGIE OF THE ION-ELECTRON SYSTEM (eV) $line = $in->SkipTo("\\s*FREE ENERGIE OF THE ION\\-ELECTRON SYSTEM"); if($line) { # free energy TOTEN = -526.50050340 eV $line = $in->SkipTo("TOTEN\\s*="); ($Crystals[$iCrystal]->{TOTEN}) = ($line =~ /TOTEN\s*=\s*(\S+)/); # energy without entropy= -526.52119211 energy(sigma->0) = -526.50739963 $line = $in->SkipTo("energy without entropy="); ($Crystals[$iCrystal]->{TOTENwithEntropy}) = ($line =~ /energy\(signma-\>0\)\s*=\s*(\S+)/); } else { $in->seek($pos); } $pos = $in->tell(); $line = $in->SkipTo("\\s*ENERGY OF THE ELECTRON-ION-THERMOSTAT"); #print "l1[$line]\n"; $line = $in->SkipTo(".*temperature\\s+(.*)\\s*K"); #print "l2[$line]\n"; if($line) { my ($T) = ($line =~ /temperature\s+(.*?)\s*?K/); $Crystals[$iCrystal]->SetTemperature($T); } else { $in->seek($pos); } #print "T=$T\n"; # ENERGY OF THE ELECTRON-ION-THERMOSTAT SYSTEM (eV) # kin. lattice EKIN_LAT= 0.777034 (temperature 2000.38 K) $iCrystal++; } $in->Close(); return (@Crystals); } sub ReadOUTCARtoHash { my ($this, $infile) = @_; my $in = new JFile; if(!$in->Open($infile, "r")) { print("Error in ReadOUTCARtoHash: Can not read [$infile].\n"); return undef; } my (@charge, @magnetization, @Charge, @Magnetization, @PhononMode); my %hash = (FileName => $infile, pCharge => \@Charge, pMagnetization => \@Magnetization); while(1) { my $line = $in->ReadLine(); last if(!defined $line); #print "l: $line\n"; if($line =~ /!!!/ and $line !~ /g\s+!!!/i) { for(my $i = 0 ; $i < 5 ; $i++) { my $line = $in->ReadLine(); } my $s = ''; for(my $i = 0 ; $i < 3 ; $i++) { my $s2 = $in->ReadLine(); $s2 =~ s/^[\|\s]*//; $s2 =~ s/[\|\s]*$/ /; $s .= $s2; } Utils::DelSpace($s); $hash{Warning} = $s; } if($line =~ /static.*point symmetry\s+(\S+)/) { $hash{StaticSymmetry} = $1; } elsif($line =~ /Fermi energy:\s*(\S+);/) { $hash{EF} = $1; } # E-fermi : -2.4956 XC(G=0): -3.7271 alpha+bet : -4.0683 elsif($line =~ /E\-fermi\s*:\s*(\S+)/) { $hash{EF} = $1; } elsif($line =~ /dynamic.*point symmetry\s+(\S+)/) { $hash{DynamicSymmetry} = $1; } elsif($line =~ /constrained.*point symmetry\s+(\S+)/) { $hash{ConstrainedSymmetry} = $1; } elsif($line =~ /ENCUT\s*=\s*([\d\.Ee+\-]+)/) { $hash{ENCUT} = $1; } elsif($line =~ /NBANDS\s*=\s*(\d+)/) { $hash{NBANDS} = $1; } elsif($line =~ /NKPTS\s*=\s*(\d+).*NBANDS\s*=\s*(\d+)/) { $hash{NKPTS} = $1; $hash{NBANDS} = $2; } elsif($line =~ /NEDOS\s*=\s*(\d+).*NIONS\s*=\s*(\d+)/) { $hash{NEDOS} = $1; $hash{NIONS} = $2; } elsif($line =~ /LDIM\s*=\s*(\d+).*LMDIM\s*=\s*(\d+)/) { $hash{LDIM} = $1; $hash{LMDIM} = $2; } elsif($line =~ /NPLWV\s*=\s*(\d+)/) { $hash{NPLWV} = $1; } elsif($line =~ /dimension x,y,z NGX\s*=\s*(\d+).*NGY\s*=\s*(\d+).*NGZ\s*=\s*(\d+)/) { $hash{CurrNGXYZ} = "$1,$2,$3"; } elsif($line =~ /I would recommend the setting:/) { $line = $in->ReadLine; if($line =~ /dimension x,y,z NGX\s*=\s*(\d+).*NGY\s*=\s*(\d+).*NGZ\s*=\s*(\d+)/) { $hash{RecommendNGXYZ} = "$1,$2,$3"; } } elsif($line =~ /TEIN\s*=\s*(\d+)/) { $hash{TEIN} = $1; } elsif($line =~ /TEBEG\s*=\s*(\S+);.*TEEND\s*=\s*(\S+)/) { $hash{TEBEG} = $1; $hash{TEEND} = $2; } elsif($line =~ /POMASS\s*=\s*(.*?)\s*$/) { $hash{POMASS} = $1; } elsif($line =~ /ZVAL\s*=\s*(.*?)\s*$/) { $hash{ZVAL} = $1; } elsif($line =~ /NELECT\s*=\s*([+\-\d+\.eE]+)/) { $hash{NELECT} = $1; } elsif($line =~ /NUPDOWN\s*=\s*([\-\d]+)/) { $hash{NUPDOWN} = $1; } elsif($line =~ /IALGO\s*=\s*(\d+)/) { $hash{IALGO} = $1; } elsif($line =~ /LDIAG\s*=\s*(\S+)/) { $hash{LDIAG} = $1; } elsif($line =~ /IMIX\s*=\s*(\d+)/) { $hash{IMIX} = $1; } elsif($line =~ /AMIX\s*=\s*([\d\.]+)/) { $hash{AMIX} = $1; $line =~ /BMIX\s*=\s*([\d\.]+)/; $hash{BMIX} = $1; } elsif($line =~ /AMIX\_MAG\s*=\s*([\d\.]+)/) { $hash{AMIX_MAG} = $1; $line =~ /BMIX_MAG\s*=\s*([\d\.]+)/; $hash{BMIX_MAG} = $1; } elsif($line =~ /AMIN\s*=\s*([\d\.]+)/) { $hash{AMIN} = $1; } elsif($line =~ /TIME\s*=\s*(\d+)/) { $hash{TIME} = $1; } elsif($line =~ /LSECVAR\s*=\s*(\S+)/) { $hash{LSECVAR} = $1; } elsif($line =~ /IDIPOL\s*=\s*(\S+)/) { $hash{IDIPOL} = $1; } elsif($line =~ /LWAVE\s*=\s*(\S+)/) { $hash{LWAVE} = $1; } elsif($line =~ /LCHARG\s*=\s*(\S+)/) { $hash{LCHARG} = $1; } elsif($line =~ /LVTOT\s*=\s*(\S+)/) { $hash{LVTOT} = $1; } elsif($line =~ /LVHAR\s*=\s*(\S+)/) { $hash{LVHAR} = $1; } elsif($line =~ /LELF\s*=\s*(\S+)/) { $hash{LELF} = $1; } elsif($line =~ /LORBIT\s*=\s*(\S+)/) { $hash{LORBIT} = $1; } elsif($line =~ /LMONO\s*=\s*(\S+)/) { $hash{LMONO} = $1; } elsif($line =~ /LDIPOL\s*=\s*(\S+)/) { $hash{LDIPOL} = $1; } elsif($line =~ /IDIPOL\s*=\s*(\d+)/) { $hash{IDIPOL} = $1; } elsif($line =~ /EPSILON\s*=\s*([\d\.Ee+\-]+)/) { $hash{EPSILON} = $1; } elsif($line =~ /LEPSILON\s*=\s*(\S+)/) { $hash{LEPSILON} = $1; } elsif($line =~ /LRPA\s*=\s*(\S+)/) { $hash{LRPA} = $1; } elsif($line =~ /CSHIFT\s*=\s*([\d\.+\-Ee]+)/) { $hash{CSHIFT} = $1; } elsif($line =~ /GGA\s*=\s*(\S+)/) { $hash{EPSILON} = $1; } elsif($line =~ /LEXCH\s*=\s*(\d+)/) { $hash{LEXCH} = $1; } elsif($line =~ /LHFCALC\s*=\s*(\S+)/) { $hash{LHFCALC} = $1; } elsif($line =~ /PRECFOCK\s*=\s*(\S+)/) { $hash{PRECFOCK} = $1; } elsif($line =~ /LTHOMAS\s*=\s*(\S+)/) { $hash{LTHOMAS} = $1; } elsif($line =~ /LMAXFOCK\s*=\s*(\S+)/) { $hash{LMAXFOCK} = $1; } elsif($line =~ /AEXX\s*=\s*([\d+\-\.Ee]+)/) { $hash{AEXX} = $1; } elsif($line =~ /HFSCREEN\s*=\s*([\d+\-\.Ee]+)/) { $hash{HFSCREEN} = $1; } elsif($line =~ /ALDAX\s*=\s*([\d+\-\.Ee]+)/) { $hash{ALDAX} = $1; } elsif($line =~ /AGGAX\s*=\s*([\d+\-\.Ee]+)/) { $hash{AGGAX} = $1; } elsif($line =~ /ALDAC\s*=\s*([\d+\-\.Ee]+)/) { $hash{ALDAC} = $1; } elsif($line =~ /AGGAC\s*=\s*([\d+\-\.Ee]+)/) { $hash{AGGAC} = $1; } elsif($line =~ /ENCUT\s*=\s*(\S+)/) { # ENCUT = 400.0 eV 29.40 Ry 5.42 a.u. 5.29 5.29 8.47*2*pi/ulx,y,z $hash{ENCUT} = $1; } elsif($line =~ /TOTEN\s*=\s*(\S+)/) { $hash{TOTEN} = $1; } elsif($line =~ /energy\s+without\s+entropy\s*=\s*(\S+).*sigma-\>0\)\s*=\s*(\S+)/) { $hash{TOTENwoS} = $1; $hash{TOTENwoSlim} = $2; } elsif($line =~ /Total CPU time.*:\s*(\S+)/) { $hash{TotCPUTime} = $1; } elsif($line =~ /User time.*:\s*(\S+)/) { $hash{UserTime} = $1; } elsif($line =~ /System time.*:\s*(\S+)/) { $hash{SystemTime} = $1; } elsif($line =~ /Elapsed time.*:\s*(\S+)/) { $hash{ElapsedTime} = $1; } elsif($line =~ /(abort.*?)[\-\s]*$/) { $hash{AbortMessage} = $1; } elsif($line =~ /^(.*reached required accuracy.*)$/) { $hash{RequiredAccuracyMessage} = $1; } elsif($line =~ /^ *total charge +$/) { #print "l2: [$line]\n"; $hash{pChargeLines} = \@charge; $in->SkipTo("-----"); my $nCharge = 0; while(1) { $line = $in->ReadLine(); Utils::DelSpace($line); last if(!defined $line or $line eq ''); last if($line =~ /-----/); #print "l3: [$line]\n"; my @a = Utils::Split("\\s+", $line); #print "l3: [$line]: ", scalar @a, "\n"; $charge[$nCharge] = $line; $Charge[$nCharge++] = $a[@a-1]; } $line = $in->ReadLine(); $hash{TotalChargeLine} = $line; } elsif($line =~ /^ *magnetization \(x\) *$/) { $hash{pMagnetizationLines} = \@magnetization; $in->SkipTo("-----"); my $nCharge = 0; while(1) { $line = $in->ReadLine(); Utils::DelSpace($line); last if(!defined $line or $line eq ''); last if($line =~ /-----/); my @a = Utils::Split("\\s+", $line); $magnetization[$nCharge] = $line; $Magnetization[$nCharge++] = $a[@a-1]; } $line = $in->ReadLine(); $hash{TotalMagnetizationLine} = $line; } elsif($line =~ /Eigenvectors/) { # elsif($line =~ /^ *Eigenvectors and eigenvalues of the dynamical matrix *$/) { $hash{pPhononModeLines} = \@PhononMode; $line = $in->ReadLine(); my $nPhononMode = 0; my $iline = 0; while(1) { $line = $in->ReadLine(1); last if(!defined $line); next if($line eq ''); last if($line =~ /-----/); $PhononMode[$iline++] = $line; #print "$nPhononMode: $line\n"; if($line =~ /\d+\s+f(\/i)?\s*=\s+\d/) { $nPhononMode++; } } $hash{nPhononMode} = $nPhononMode; } } $in->Close(); return \%hash; } #=================================================================== # DOS/OUTCARからエネルギー準位を読み取り、EVB, ECB, Egを読み取る #=================================================================== sub ReadEgFromDOSOUTCAR { my ($this, $DOSOUTCAR) = @_; #print "\n=== From $DOSOUTCAR\n"; my $in = new JFile; if(!$in->Open($DOSOUTCAR, "r")) { print "Error: Can not read [$DOSOUTCAR].\n"; return (); } my $line = $in->SkipTo("E-fermi :"); my ($EF) = ($line =~ /:\s*([\d+-\.eE]+)/); #print "line: [$line] [EF = $EF]\n"; #print " EF = $EF eV\n"; my ($VBM, $CBM); while(1) { $line = $in->SkipTo("k-point\\s+\\d+\\s:"); last if(!$line); #print "line: $line"; $line = $in->ReadLine(); for(my $i = 0 ; ; $i++) { $line = $in->ReadLine(); my ($iband, $E, $occ) = Utils::Split("\\s+", $line); #, "\\s+"); last if(!defined $occ); #print " $iband: $E, $occ\n"; if($occ > 0.1 and $E <= $EF) { if(!defined $VBM or $VBM < $E) { $VBM = $E; #print " VB: $iband: $E, $occ\n"; } } elsif($occ < 0.1 and $E >= $EF) { if(!defined $CBM or $CBM > $E) { $CBM = $E; #print " CB: $iband: $E, $occ\n"; } } } } my $Eg = $CBM - $VBM; #print " VBM=$VBM CBM=$CBM Eg=$Eg eV\n"; $in->Close(); return ($EF, $VBM, $CBM, $Eg); } #=================================================================== # DOS/*.csvからDOSを読み取り、EVB, ECB, Eg, Ne, Nspinを読み取る #=================================================================== sub ReadFromDOSCSV { my ($this, $Dir) = @_; my @DOSupFiles = glob(Deps::MakePath2($Dir, ["DOS", "*-1.csv"], 0)); if(@DOSupFiles == 0) { @DOSupFiles = glob(Deps::MakePath2($Dir, ["DOS", "DOS-up.csv"], 0)); } my @DOSdnFiles = glob(Deps::MakePath2($Dir, ["DOS", "*-2.csv"], 0)); if(@DOSdnFiles == 0) { @DOSdnFiles = glob(Deps::MakePath2($Dir, ["DOS", "DOS-dn.csv"], 0)); } my $DOSup = $DOSupFiles[0]; my $DOSdn = $DOSdnFiles[0]; my ($DEFup, $DEFdn, $NVBup, $NVBdn, $Ntotup, $Ntotdn); my ($EVBLowestup, $EVBLowestdn); my ($pXup, $pYup, $pXdn, $pYdn, $iXVBLowestup, $iXVBLowestdn); foreach my $file ($DOSup, $DOSdn) { next if(!-e $file); #print "\n=== From $file\n"; my $csv = new CSV; $csv->Read($file, 1); my $pLabelArray = $csv->LabelArray(); my $pDataArray = $csv->DataArray(); my $nData = $csv->nData(); #print " nData: $nData\n"; my $pX = $pDataArray->[0]; my $pY = $pDataArray->[1]; last if(!defined $pY); #print @$pLabelArray, "\n"; my ($YMin, $YMax) = Utils::CalMinMax($pY); my $Yth = $YMax * 1.0e-3; #print " Y: $YMin - $YMax Yth=$Yth\n"; my $iXZero; for(my $i = 0 ; $i < $nData ; $i++) { #print "$i: $pX->[$i]\n"; if($pX->[$i] >= -1.0e-4) { $iXZero = $i; #print "iXZero=$iXZero [$nData]\n"; last; } } my $nzero = 0; my $iXVBLowest; for(my $i = $iXZero ; $i >= 0 ; $i--) { if($pY->[$i] < $Yth) { $nzero++; #print "i=$i: nzero=$nzero\n"; if($nzero > 10) { $iXVBLowest = $i; last; }; } else { $nzero = 0; } } #print "iXVBLowest=$iXVBLowest\n"; if($file eq $DOSup) { $EVBLowestup = $pX->[$iXVBLowest]; $iXVBLowestup = $iXVBLowest; #print "iXVBLowestup=$iXVBLowestup\n"; $pXup = $pX; $pYup = $pY; } else { $EVBLowestdn = $pX->[$iXVBLowest]; $iXVBLowestdn = $iXVBLowest; #print "iXVBLowestdn=$iXVBLowestdn\n"; $pXdn = $pX; $pYdn = $pY; } } my $iXVBLowest = (!defined $iXVBLowestdn or $iXVBLowestup < $iXVBLowestdn)? $iXVBLowestup : $iXVBLowestdn; my $EVBLowest = ($EVBLowestup < $EVBLowestdn)? $EVBLowestup : $EVBLowestdn; #print "EVBLowest: $EVBLowest [$iXVBLowest] (up=$EVBLowestup [$iXVBLowestup] dn=$EVBLowestdn [$iXVBLowestdn])\n"; my ($pSup, $pSVBLowestup, $pSEFup); if($pYup) { my $csv = new CSV; $pSup = Algorism::IntegrateByConstantStepSimpson(scalar @$pXup, $pXup->[1] - $pXup->[0], $pYup); $pSVBLowestup = $pSup->[$iXVBLowest]; $pSEFup = $csv->YVal($pXup, $pSup, 0.0); #print "diff: $pSEFup - $pSVBLowestup\n"; $NVBup = $pSEFup - $pSVBLowestup; $DEFup = $csv->YVal($pXup, $pYup, 0.0); #print " Total electrons in VB: up=$NVBup e\n"; #print " D(EF): up=$DEFup e/eV\n"; } my ($pSdn, $pSVBLowestdn, $pSEFdn); if($pYdn) { my $csv = new CSV; $pSdn = Algorism::IntegrateByConstantStepSimpson(scalar @$pXdn, $pXdn->[1] - $pXdn->[0], $pYdn); $pSVBLowestdn = $pSdn->[$iXVBLowest]; $pSEFdn = $csv->YVal($pXdn, $pSdn, 0.0); $NVBdn = $pSEFdn - $pSVBLowestdn; $DEFdn = $csv->YVal($pXdn, $pYdn, 0.0); #print " Total electrons in VB: dn=$NVBdn e\n"; #print " D(EF): dn=$DEFdn e/eV\n"; } if($pYup and $pYdn) { my $Ntottotal = $Ntotup + $Ntotdn; my $Ntotspin = $Ntotup - $Ntotdn; my $NVBtotal = $NVBup + $NVBdn; my $NVBspin = $NVBup - $NVBdn; my $DEFtotal = $DEFup + $DEFdn; my $DEFspin = $DEFup - $DEFdn; #printf " Ntot(total)=%9.6f NVB(total)=%9.6f DEF(total)=%9.6f\n", $Ntottotal, $NVBtotal, $DEFtotal; #printf " Ntot(spin) =%9.6f NVB(spin) =%9.6f DEF(spin) =%9.6f\n", $Ntotspin, $NVBspin, $DEFspin; } } sub MakeINCARFile { my ($this, $Crystal, $Function, $Functional, $UseDPP, $SpinPolarized, $fname, $pParams) = @_; print "

Make INCAR

\n"; if($pParams->{HybridFunctional}) { # $pParams->{IBRION} = 5 if($pParams->{IBRION} == 7); # $pParams->{IBRION} = 6 if($pParams->{IBRION} == 8); } #print "f=$pParams->{SpinOrbit},$pParams->{NonCollinear},$pParams->{LMAXMIX}\n"; my ($f, @POTFiles) = $this->MakePOTCARFile($Crystal, $Functional, $UseDPP, undef, $pParams); my @Element; for(my $i = 0 ; $i < @POTFiles ; $i++) { my $s = $this->ReadElementFromPOT($POTFiles[$i]); #print " Element from @POTFiles[$i]: $s$LF"; push(@Element, $s); } my @RWIGS; for(my $i = 0 ; $i < @POTFiles ; $i++) { my $s = $this->ReadRWIGSFromPOT($POTFiles[$i]); #print " RWIGS for $Element[$i] from $POTFiles[$i]: $s$LF"; push(@RWIGS, $s); } my @AtomTypeList = $Crystal->GetCAtomTypeList(); my $nAtomType = @AtomTypeList; my @AtomSiteList = $Crystal->GetCExpandedAtomSiteList(); my $nAtomSite = @AtomSiteList; #ファイル作製開始 unless(open(OUT,">$fname")) { print "Can not write to $fname.$LF$LF"; return 0; } binmode(OUT); my $Sample = $this->SampleName(); my $Volume = $Crystal->Volume(); if(defined $Crystal->{'CIFFileName'} and $Crystal->{'CIFFileName'} ne '') { print OUT "Source: $Crystal->{'CIFFileName'}\n"; } print OUT "SYSTEM = $Sample [$Functional] ($Function)\n"; for(my $i = 0 ; $i < @POTFiles ; $i++) { print OUT " #POTFiles: $POTFiles[$i]\n"; } print OUT "\n"; print OUT "Start parameters for this Run:\n"; print OUT " #ISTART: 0:from scratch 1:restart with the same Ecut\n"; print OUT " # 2:restart with the same basis set 3:full restart\n"; print OUT " ISTART = 0\n"; print OUT " #ICHARG: 0:Charge from initial wavef 1: CHGCAR 2:Atomic charge\n"; print OUT " # +10: Non-selfconsistent\n"; if($Function =~ /band|dos/i) { print OUT " ICHARG = 11\n"; # print OUT " ICHARG = 10\n"; } else { print OUT " #ICHARG = 1\n"; } print OUT " #INIWAV: Only for ISTART=0\n"; print OUT " INIWAV = 1\n"; print OUT " NWRITE = 2 # Larger, more verbose. Must be 3 for phonon.\n"; print OUT " #PREC: High|Accurate|Normal|Medium|Low\n"; if($Function =~ /vc-relax/i) { print OUT " PREC = Accurate\n"; } else { print OUT " PREC = Normal\n"; } print OUT " #NBANDS: Set NBANDS to double for collinear calculation\n"; print OUT " #NBANDS = \n"; if(defined $pParams->{ADDGRID}) { print OUT " ADDGRID = $pParams->{ADDGRID}\n"; } else { print OUT " #ADDGRID = .TRUE.\n"; } print OUT "\n"; print OUT "Electronic Relaxation\n"; print OUT " #NELECT = \n"; print OUT " #Energy correction\n"; print OUT " EDIFF = 1e-04 stopping-criterion for ELM\n"; print OUT " # Critera for relaxation. In energy for positive value, force for negative value\n"; print OUT " EDIFFG = 1.0e-3\n"; print OUT " #LREAL: .TRUE.|.FALSE.|A|O\n"; if($Volume > 7.0*7.0*7.0) { print OUT " LREAL = .TRUE.\n"; } else { print OUT " LREAL = .FALSE.\n"; } print OUT " #ENCUT = 200.00 eV\n"; print OUT " #Algorithm 8:CG, 38: Davidson, 48:RMM=DIIS, 8,48: for NPAR=1, 48: for NPAR > 1\n"; print OUT " #Algorithm Normal Damped All Diag\n"; print OUT " # For hybrid: All, Diag, or Damped. ISMEAR=-5 is not recommended for All\n"; print OUT " #IALGO = 48\n"; print OUT " # DFT functional\n"; print OUT " # PE: PBE RE: revPBE RP: RPBE PS: PBEsol AM: AM05\n"; print OUT " # B3: B3LYP with VWN3 B5: B3LYP with VWN5\n"; if(defined $pParams->{GGA} and $pParams->{GGA} ne '') { print OUT " GGA=$pParams->{GGA}\n"; } else { print OUT " #GGA=PE\n"; } print OUT "\n"; my $HFALGO = 'All'; # my $HFALGO = ($Function =~ /(dos|band|eDensity)/i)? '53' : 'Auto'; print OUT " # For wannnier90: Use ALGO = None\n"; print OUT " #LWANNIER90_RUN = .FALSE.\n"; if($pParams->{HybridFunctional} eq 'HF') { print OUT " ALGO = $HFALGO\n"; print OUT " #LDIAG = .TRUE.\n"; print OUT " LHFCALC = .TRUE.\n"; print OUT " AEXX = 1.0\n"; print OUT " AGGAC = 0.0\n"; print OUT " ALDAC = 0.0\n"; print OUT " #HFSCREEN = 0.2\n"; print OUT " #ENCUTFOCK = 0 #No lognger used in vasp.5.2.x\n"; print OUT " PRECFOCK = N #PrecFock=L|M|F|N|A\n"; print OUT " #LMAXFOCK = 4\n"; print OUT " TIME = 0.4\n"; } elsif($pParams->{HybridFunctional} =~ /^HSE/) { print OUT " ALGO = $HFALGO\n"; print OUT " #LDIAG = .TRUE.\n"; print OUT " LHFCALC = .TRUE.\n"; print OUT " AEXX = 0.25\n"; print OUT " AGGAC = 1.0\n"; print OUT " ALDAC = 1.0\n"; print OUT " HFSCREEN = 0.2\n"; print OUT " #ENCUTFOCK = 0\n"; print OUT " PRECFOCK = N #PrecFock=L|M|F|N|A\n"; print OUT " #LMAXFOCK = 4\n"; print OUT " TIME = 0.4\n"; } elsif($pParams->{HybridFunctional} eq 'PBE0') { print OUT " ALGO = $HFALGO\n"; print OUT " #LDIAG = .TRUE.\n"; print OUT " LHFCALC = .TRUE.\n"; print OUT " AEXX = 0.25\n"; print OUT " AGGAC = 1.0\n"; print OUT " ALDAC = 1.0\n"; print OUT " #HFSCREEN = 0.2\n"; print OUT " #ENCUTFOCK = 0\n"; print OUT " PRECFOCK = N #PrecFock=L|M|F|N|A\n"; print OUT " #LMAXFOCK = 4\n"; print OUT " TIME = 0.4\n"; } else { print OUT " ALGO = $HFALGO\n"; print OUT " #LDIAG = .TRUE.\n"; print OUT " #LHFCALC = .TRUE.\n"; print OUT " #AEXX = 0.25\n"; print OUT " #AGGAC = 1.0\n"; print OUT " #ALDAC = 1.0\n"; print OUT " #HFSCREEN = 0.2\n"; print OUT " #ENCUTFOCK = 0 #No lognger used in vasp.5.2.x\n"; print OUT " #PRECFOCK = N #PrecFock=L|M|F|N|A\n"; print OUT " #LMAXFOCK = 4\n"; print OUT " #TIME = 0.4\n"; } print OUT " #NKRED = 2\n"; print OUT " #NKREDX =\n"; print OUT " #NKREDY =\n"; print OUT " #NKREDZ =\n"; if(defined $pParams->{IMIX}) { print OUT " #IMIX = $pParams->{IMIX}\n"; } else { print OUT " #IMIX = 4\n"; } print OUT " #AMIX = 0.4\n"; print OUT " #BMIX = 1.0\n"; print OUT " #NSIM = 4\n"; print OUT " #NELM: Number of electronic steps\n"; if($Function =~ /band/i) { print OUT " NELMIN = 0 # 5 at least for hybrid band calc\n"; print OUT " NELM = 0\n"; print OUT " NELMDL = 3 # of ELM steps"; } elsif($Function =~ /wannier/i) { print OUT " #NELMIN = 0 # 5 at least for hybrid band calc\n"; print OUT " NELM = 1\n"; print OUT " #NELMDL = 3 # of ELM steps"; } else { print OUT " NELMIN = 0 # 5 at least for hybrid band calc\n"; if(defined $pParams->{NELM}) { print OUT " #NELM = $pParams->{NELM}\n"; } else { print OUT " #NELM = 100\n"; } print OUT " #NELMDL = 3 # of ELM steps\n"; } print OUT "\n"; print OUT " #IDIPOL = 4\n"; print OUT " #DIPOL = 0.00000 0.00000 0.00000\n"; print OUT " #LDIPOL = .TRUE.\n"; print OUT " #Spin-orbit\n"; if(defined $pParams->{SpinOrbit} and $pParams->{SpinOrbit} =~ /[1T]/i) { print OUT " LSORBIT = $pParams->{SpinOrbit}\n"; print OUT " SAXIS = 0 0 1\n"; } else { print OUT " #LSORBIT = .TRUE.\n"; print OUT " #SAXIS = 0 0 1\n"; } print OUT " #Non-collinear setup\n"; if(defined $pParams->{NonCollinear} and $pParams->{NonCollinear} ne '') { print OUT " LNONCOLLINEAR = $pParams->{NonCollinear}\n"; } else { print OUT " #LNONCOLLINEAR = .TRUE.\n"; } print OUT " #MAGMOM = "; for(my $ia = 0 ; $ia < $nAtomType ; $ia++) { my $atomtype = $AtomTypeList[$ia]; my $typename = $atomtype->AtomNameOnly(); for(my $i = 0 ; $i < @AtomSiteList ; $i++) { my $atom = $AtomSiteList[$i]; my $atomname = $atom->AtomNameOnly(); next if(uc $typename ne uc $atomname); print OUT "0 0 1 "; } } print OUT "\n"; print OUT " #NBANDS: Set NBANDS to double of collinear calculation\n"; print OUT " #GGA_COMPAT = .FALSE.\n"; print OUT " #ISPIN: 1:Non-polarized 2:Spin-polarized\n"; if($SpinPolarized =~ /Yes/i or $SpinPolarized >= 2) { print OUT " ISPIN = 2\n"; } else { print OUT " ISPIN = 1\n"; } print OUT " #mmmmmm = "; for(my $ia = 0 ; $ia < $nAtomType ; $ia++) { my $atomtype = $AtomTypeList[$ia]; my $typename = $atomtype->AtomNameOnly(); for(my $i = 0 ; $i < @AtomSiteList ; $i++) { my $atom = $AtomSiteList[$i]; my $atomname = $atom->AtomNameOnly(); next if(uc $typename ne uc $atomname); printf OUT "%2s", $atomname; } } print OUT "\n"; print OUT " #MAGMOM = "; for(my $ia = 0 ; $ia < $nAtomType ; $ia++) { my $atomtype = $AtomTypeList[$ia]; my $typename = $atomtype->AtomNameOnly(); for(my $i = 0 ; $i < @AtomSiteList ; $i++) { my $atom = $AtomSiteList[$i]; my $atomname = $atom->AtomNameOnly(); next if(uc $typename ne uc $atomname); printf OUT " 0"; } } print OUT "\n"; print OUT " #NUPDOWN = 0\n"; print OUT "\n"; print OUT " #PAW Control:\n"; print OUT " #LMAXMIX: Default: 2\n"; print OUT " # Use 4 and 6 for d and f orbitals in NSCF/SOC/NC/L(S)DA+U calculations\n"; if(defined $pParams->{LMAXMIX} and $pParams->{LMAXMIX} ne '') { print OUT " LMAXMIX = $pParams->{LMAXMIX}\n"; } else { print OUT " #LMAXMIX = 4\n"; } print OUT " #LMAXPAW: Default: 2*lmax\n"; print OUT " # -1: No on-site correction 0: Only spherical terms\n"; print OUT " #LMAXPAW = 0\n"; print OUT "\n"; print OUT "Functional\n"; if(defined $pParams->{LASPH}) { print OUT " LASPH = $pParams->{LASPH}\n"; } else { print OUT " #LASPH = .TRUE.\n"; } print OUT "\n"; print OUT " # van der Waals correction by DFT-D method of Grimme\n"; print OUT " #LVDW = .TRUE.\n"; print OUT " # Other vdW-DF\n"; print OUT " #LUSE_VDW = .TRUE.\n"; print OUT " # vdWDFT (Dion): AGGAC=0, GGA=RE, no Zab_vdW\n"; print OUT " # vdW2 : AGGAC=0, GGA=ML, no Zab_vdW=-1.8867)\n"; print OUT " # optPBE : AGGAC=0, GGA=OR, no Zab_vdW)\n"; print OUT " # optB88 : AGGAC=0, GGA=BO, PARAM1=0.1833333333, PARAM2=0.22, no Zab_vdW)\n"; print OUT " # optB86b: AGGAC=0, GGA=MK, PARAM1=0.1234, PARAM2=1.0, no Zab_vdW)\n"; # print OUT " #AGGAC = 0.000\n"; print OUT " #PARAM1 = 0.1234\n"; print OUT " #PARAM2 = 1.0000\n"; print OUT " #Zab_vdW = -1.8867\n"; print OUT "\n"; print OUT " #METAGGA: TPSS|RTPSS|M06L|MBJ\n"; if(defined $pParams->{METAGGA} and $pParams->{METAGGA} ne '') { print OUT " METAGGA=$pParams->{METAGGA}\n"; } else { print OUT " #METAGGA=MBJ\n"; } print OUT " #CMBJA=-0.012\n"; print OUT " #CMBJB=1.023 # bohr\n"; print OUT " #CMBJ: c parameters: One ently per atomic type: c_1 c_2 .. c_n\n"; print OUT " #CMBJ="; for(my $i = 0 ; $i < $nAtomType ; $i++) { print OUT " c_$i"; } print OUT "\n"; print OUT " #LMAXTAU = 0\n"; print OUT " #LMIXTAU = F\n"; print OUT "\n"; print OUT " #LDA+U setup\n"; print OUT " #LDAU = .TRUE.\n"; print OUT " #LDAUTYPE: 1: Rotational invaliant LSDA+U 4:the same as 1, but LDA+U\n"; print OUT " # 2: Dudarev's LSDA+U\n"; print OUT " #LDAUTYPE = 2\n"; # print OUT " #LDAUL = 2 -1 -1\n"; print OUT " #LDAUL = 2 "; for(my $i = 1 ; $i < $nAtomType ; $i++) { print OUT "-1 "; } print OUT "\n"; # print OUT " #LDAUU = 4.0 0.0 0.0\n"; print OUT " #LDAUU = 4.0 "; for(my $i = 1 ; $i < $nAtomType ; $i++) { print OUT "0.0 "; } print OUT "\n"; # print OUT " #LDAUJ = 0.0 0.0 0.0\n"; print OUT " #LDAUJ = "; for(my $i = 0 ; $i < $nAtomType ; $i++) { print OUT "0.0 "; } print OUT "\n"; print OUT " #LDAUPRINT: 0:silent 1:medium 2:detail\n"; print OUT " #LDAUPRINT = 2\n"; print OUT "\n"; print OUT "Ionic Relaxation\n"; if($Function =~ /relax/i) { print OUT " #ISIF: 0:Ion relax only 2:Cell fixed/Calc.Pressure 3:VC-Relax/VC-MD\n"; print OUT " # 4: Variable shape fixed V (not implemented) 7: fixed shape variable volume (not implemented)\n"; if($Function =~ /vc/i) { print OUT " ISIF = 3\n"; } else { print OUT " ISIF = 0\n"; } print OUT " #NSW: Number of ion steps.Should be 0 for phonon.\n"; print OUT " NSW = 100\n"; print OUT " # Invoke Langevin dynamics (MDALGO=3)\n"; print OUT " #MDALGO=3\n"; print OUT " # Friction coefficients for atomic degrees of freedom, one for each species defiend in POSCAR\n"; print OUT " # (in ps^-1, typically 0(no thermostating) - 100 ps^-1)\n"; print OUT " # See e.g. book of Allen and Tildesley: Computer simulations of liquids\n"; print OUT " #LANGEVIN_GAMMA="; for(my $i = 0 ; $i < $nAtomType ; $i++) { print OUT "100 "; } print OUT "\n"; print OUT " # Friction coefficients for lattice degrees of freedom\n"; print OUT " #LANGEVIN_GAMMA_L=100\n"; print OUT " # Fictitious mass for lattice degrees of freedom (in amu) used\n"; print OUT " # in Parrinello-Rahman dynamics (Default 1000, typically 1-10?)\n"; print OUT " #PMASS=10\n"; print OUT " #IBRION: -1:Ion position fiexed 0:MD\n"; print OUT " 1: Quasi-Newton 2:Conjugate Gradient\n"; print OUT " 3: Damped MD, use dumping factor(SMASS/POTIM)\n"; print OUT " 5,6: Hessian matrix calculated by finite-difference. 6 considers symmetry\n"; print OUT " 7,8: Hessian matrix calculated analytically. 8 considers symmetry\n"; print OUT " IBRION = 2\n"; print OUT " # Nose mass definition: -3: a micro canonical ensemble (constant energy molecular dynamics)\n"; print OUT " # -2: the initial velocities are kept constant -1: the velocities are scaled each NBLOCK step\n"; print OUT " # >=0: a canonical ensemble by Nose algorism\n"; print OUT " SMASS = -3\n"; print OUT " #NBLOCK = 50\n"; print OUT " POTIM = 0.5 fs time-step for ion-motion\n"; print OUT " TEBEG = 0000.0\n"; print OUT " TEEND = 0000.0\n"; print OUT " PSTRESS = 0.0 kBar\n"; print OUT " #POMASS and ZVAL are read from POTCAR for default\n"; print OUT " #POMASS = 102.91\n"; print OUT " #ZVAL = 11.0\n"; print OUT " #ISYM: 0:Break symmetry 1,2:Keep symmetry\n"; print OUT " 2:More effecient memory use\n"; print OUT " ISYM = 0\n"; print OUT " #SYMPREC: deault 1e-5\n"; print OUT " #SYMPREC = 1e-5\n"; } elsif($Function =~ /md/i) { print OUT " #ISIF: 0:Ion relax only 2:Cell fixed/Calc.Pressure 3:VC-Relax/VC-MD\n"; print OUT " # 4: Variable shape fixed V (not implemented) 7: fixed shape variable volume (not implemented)\n"; if($Function =~ /vc/i) { print OUT " ISIF = 3\n"; } else { print OUT " ISIF = 0\n"; } print OUT " #NSW: Number of ion steps\n"; print OUT " NSW = 100\n"; print OUT " # Invoke Langevin dynamics (MDALGO=3)\n"; if($Function =~ /vc/i) { print OUT " MDALGO=3\n"; } else { print OUT " #MDALGO=3\n"; } print OUT " # Friction coefficients for atomic degrees of freedom, one for each species defiend in POSCAR\n"; print OUT " # (in ps^-1, typically 0(no thermostating) - 100 ps^-1)\n"; print OUT " # See e.g. book of Allen and Tildesley: Computer simulations of liquids\n"; if($Function =~ /vc/i) { print OUT " #LANGEVIN_GAMMA="; for(my $i = 0 ; $i < $nAtomType ; $i++) { print OUT "100 "; } print OUT "\n"; print OUT " # Friction coefficients for lattice degrees of freedom\n"; print OUT " LANGEVIN_GAMMA_L=100\n"; } else { print OUT " #LANGEVIN_GAMMA="; for(my $i = 0 ; $i < $nAtomType ; $i++) { print OUT "100 "; } print OUT "\n"; print OUT " # Friction coefficients for lattice degrees of freedom\n"; print OUT " #LANGEVIN_GAMMA_L=100\n"; } print OUT " # Fictitious mass for lattice degrees of freedom (in amu) used\n"; print OUT " # in Parrinello-Rahman dynamics (Default 1000, typically 1-10?)\n"; if($Function =~ /vc/i) { print OUT " PMASS=10\n"; } else { print OUT " #PMASS=10\n"; } print OUT " #IBRION: -1:Ion position fiexed 0:MD\n"; print OUT " 1: Quasi-Newton 2:Conjugate Gradient\n"; print OUT " 3: Damped MD, use dumping factor(SMASS/POTIM)\n"; print OUT " 5,6: Hessian matrix calculated by finite-difference. 6 considers symmetry\n"; print OUT " 7,8: Hessian matrix calculated analytically. 8 considers symmetry\n"; print OUT " IBRION = 0\n"; print OUT " # Nose mass definition: -3: a micro canonical ensemble (constant energy molecular dynamics)\n"; print OUT " # -2: the initial velocities are kept constant -1: the velocities are scaled each NBLOCK step\n"; print OUT " # >=0: a canonical ensemble by Nose algorism\n"; print OUT " SMASS = -3\n"; print OUT " #NBLOCK = 50\n"; print OUT " POTIM = 2.0 fs time-step for ion-motion\n"; print OUT " TEBEG = 300.0\n"; print OUT " TEEND = 300.0\n"; print OUT " PSTRESS = 0.0 kBar\n"; print OUT " #POMASS and ZVAL are read from POTCAR for default\n"; print OUT " #POMASS = 102.91\n"; print OUT " #ZVAL = 11.0\n"; print OUT " #ISYM: 0:Break symmetry 1,2:Keep symmetry\n"; print OUT " 2:More effecient memory use\n"; print OUT " ISYM = 0\n"; print OUT " #SYMPREC: deault 1e-5\n"; print OUT " #SYMPREC = 1e-5\n"; } else { print OUT " #ISIF: 0:Ion relax only 2:Cell fixed/Calc.Pressure 3:VC-Relax/VC-MD\n"; print OUT " # 4: Variable shape fixed V (not implemented) 7: fixed shape variable volume (not implemented)\n"; print OUT " #ISIF = 3\n"; print OUT " #NSW: Number of ion steps\n"; print OUT " #NSW = 100\n"; print OUT " # Invoke Langevin dynamics (MDALGO=3)\n"; print OUT " #MDALGO=3\n"; print OUT " # Friction coefficients for atomic degrees of freedom, one for each species defiend in POSCAR\n"; print OUT " # (in ps^-1, typically 0(no thermostating) - 100 ps^-1)\n"; print OUT " # See e.g. book of Allen and Tildesley: Computer simulations of liquids\n"; print OUT " #LANGEVIN_GAMMA="; for(my $i = 0 ; $i < $nAtomType ; $i++) { print OUT "100 "; } print OUT "\n"; print OUT " # Friction coefficients for lattice degrees of freedom\n"; print OUT " #LANGEVIN_GAMMA_L=100\n"; print OUT " # Fictitious mass for lattice degrees of freedom (in amu) used\n"; print OUT " # in Parrinello-Rahman dynamics (Default 1000, typically 1-10?)\n"; print OUT " #PMASS=10\n"; print OUT " #IBRION: -1:Ion position fiexed 0:MD\n"; print OUT " 1: Quasi-Newton 2:Conjugate Gradient\n"; print OUT " 3: Damped MD, use dumping factor(SMASS/POTIM)\n"; print OUT " 5,6: Hessian matrix calculated by finite-difference. 6 considers symmetry\n"; print OUT " 7,8: Hessian matrix calculated analytically. 8 considers symmetry\n"; print OUT " IBRION = -1\n"; print OUT " # Nose mass definition: -3: a micro canonical ensemble (constant energy molecular dynamics)\n"; print OUT " # -2: the initial velocities are kept constant -1: the velocities are scaled each NBLOCK step\n"; print OUT " # >=0: a canonical ensemble by Nose algorism\n"; print OUT " #SMASS = -3\n"; print OUT " #NBLOCK = 50\n"; print OUT " #POTIM = 2.0 fs time-step for ion-motion\n"; print OUT " #TEBEG = 300.0\n"; print OUT " #TEEND = 300.0\n"; print OUT " #PSTRESS = 0.0 kBar\n"; print OUT " #POMASS and ZVAL are read from POTCAR for default\n"; print OUT " #POMASS = 102.91\n"; print OUT " #ZVAL = 11.0\n"; print OUT " #ISYM: 0:Break symmetry 1,2:Keep symmetry\n"; print OUT " 2:More effecient memory use\n"; print OUT " ISYM = 1\n"; print OUT " #SYMPREC: deault 1e-5\n"; print OUT " #SYMPREC = 1e-5\n"; } print OUT "\n"; print OUT "# EFERMI: LEGACY, MIDGAP, real: Position of Efermi in OUTCAR for semiconductor\n"; print OUT " EFERMI=MIDGAP\n"; print OUT "\n"; print OUT " #LEPSILON=.TRUE.\n"; print OUT " #LRPA=.FALSE.\n"; print OUT " #LOPTICS=.TRUE.\n"; print OUT " #CSHIFT=0.1\n"; print OUT "\n"; print OUT "File write controls:\n"; print OUT " LWAVE = .TRUE.\n"; print OUT " LCHARG = .TRUE.\n"; print OUT " # LVHAR, LVTOT: Write Hartree (LVHAR=.T.) or Total (LVTOT=.T.)local potential to LOCPOT in vasp.5.x\n"; print OUT " #LVHAR = .TRUE.\n"; print OUT " LVTOT = .TRUE.\n"; if(defined $pParams->{LKPOINTS_OPT} and $pParams->{LKPOINTS_OPT} ne '') { print OUT " LKPOINTS_OPT = $pParams->{LKPOINTS_OPT}\n"; } else { print OUT " #LKPOINTS_OPT = .TRUE.\n"; } print OUT " #LORBIT = 2\n"; print OUT " #LELF = .TRUE.\n"; print OUT " # LAECHG: Write core charge to AECCAR0, valance charge to AECCAR2 e.g. for Bader analysis\n"; print OUT " LAECHG = .TRUE.\n"; print OUT "\n"; print OUT "Parallelization configuration:\n"; print OUT " #Parallelizaion over bands and plane wave coeff.(the latter is default)\n"; print OUT " # For dense cluster: NPAR ~ sqrt(Number of cores) or Number of cores per computer node\n"; print OUT " NPAR = 1\n"; print OUT " #NCORE = 1 # NCORE = Total number of cores / NPAR\n"; print OUT " #LPLANE = .TRUE.\n"; print OUT " #KPAR = 1\n"; print OUT "\n"; print OUT "DOS related values:\n"; my $IsPartial = 0; for(my $i = 0 ; $i < @AtomSiteList ; $i++) { my $atom = $AtomSiteList[$i]; my $occupancy = $atom->Occupancy(); if(abs($occupancy-1.0) > 1.0e-4) { $IsPartial = 1; last; } } if($IsPartial) { print OUT " #Elements: ", join(" ", @Element), "\n"; my %Done; print OUT " VCA = "; my %Done; for(my $ia = 0 ; $ia < $nAtomType ; $ia++) { my $atomtype = $AtomTypeList[$ia]; my $typenameraw = $atomtype->Label(); my $typename = $atomtype->AtomNameOnly(); my $occupancy = $atomtype->Occupancy(); print "$ia: $typenameraw\n"; next if($Done{$typenameraw}); $Done{$typenameraw}++; printf OUT "%6.4f ", $occupancy; } print OUT "\n"; } print OUT " #Elements: ", join(" ", @Element), "\n"; print OUT " RWIGS = ", join(" ", @RWIGS), "\n"; print OUT " #ISMEAR: -1: Fermi-smearing 0: Gaussian smearing N: Methfessel-Paxton order N\n"; print OUT " # -4 tetrahedron method without Blochl corrections\n"; print OUT " # -5 tetrahedron method with Blochl corrections\n"; print OUT " # use -5 for semiconductors/insulators, 1/2 for metals\n"; print OUT " # use -1/0/1/2 for Band\n"; print OUT " ISMEAR = 1\n"; print OUT " SIGMA = 0.2 broad. in eV\n"; print OUT " #DOS range and # of mesh\n"; print OUT " #EMIN = -35\n"; print OUT " #EMAX = 15\n"; print OUT " #NEDOS = 5000\n"; print OUT "\n"; print OUT "Band decomposed charge density:\n"; print OUT " #LPARD = .TRUE.\n"; print OUT " #Mode: 0: Total charge density incl. unoccupied bands.\n"; print OUT " # -1: Usual total charge density (default).\n"; print OUT " # -2: Partial charge density within energies specified by EINT.\n"; print OUT " # -3: The same as -2, but the energy is measured from the Fermi energy.\n"; print OUT " #NBMOD = 0\n"; print OUT " #Energy range to be incorporated\n"; print OUT " #EINT = -5.0 0.0\n"; print OUT " #Indexes of bands to be used (see EIGENVAL or OUTCAR)\n"; print OUT " #IBAND = 20 21 22 23\n"; print OUT " #Indexes of K points to be used (see IBZKPT)\n"; print OUT " #KPUSE = 1 2 3 4\n"; print OUT " #Write band decomposed density to PARCHG.nb.* separately if .TRUE.\n"; print OUT " #LSEPB = .TRUE.\n"; print OUT " #Write K-point decomposed density to PARCHG.*.nk separately if .TRUE.\n"; print OUT " #LSEPK = .TRUE.\n"; print OUT "\n"; close(OUT); return 1; } sub MakePOSCARFile { my ($this, $Crystal, $Function, $fname, $UseConventionalCell, $pParams) = @_; print "

Make POSCAR

\n"; #ファイル作製開始 unless(open(OUT,">$fname")) { print "Can not write to $fname.$LF$LF"; return 0; } binmode(OUT); my $Sample = $this->SampleName(); my $SPG = $Crystal->GetCSpaceGroup(); my $SPGName = $SPG->SPGName(); #print "SPG in VASP.pm:[$this->{ConventionalSPGName}][$SPGName]\n"; #exit; print OUT "$Sample\n"; my ($a, $b, $c, $alpha, $beta, $gamma); #print "C[$Crystal->{ConventionalSPGName}]n"; if(defined $Crystal->{ConventionalSPGName} and $Crystal->{ConventionalSPGName} =~ /^\s*[FIABC]/i) { my $pl = $Crystal->{ConventionalLatticeParameters}; #print "pl[$pl]\n"; ($a, $b, $c, $alpha, $beta, $gamma) = @$pl; } else { ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParametersByOutputMode(0); } print "***L [Conv cell SPG: $Crystal->{ConventionalSPGName}]: $a, $b, $c, $alpha, $beta, $gamma\n"; printf OUT " %12.6f\n", $a; my ($ax,$ay,$az,$bx,$by,$bz,$cx,$cy,$cz) = $Crystal->LatticeVectorsByOutputMode(0); printf OUT " %10.6f %10.6f %10.6f\n", $ax/$a, $ay/$a, $az/$a; printf OUT " %10.6f %10.6f %10.6f\n", $bx/$a, $by/$a, $bz/$a; printf OUT " %10.6f %10.6f %10.6f\n", $cx/$a, $cy/$a, $cz/$a; my @AtomTypeList = $Crystal->GetCAtomTypeList(); my $nAtomType = @AtomTypeList; my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode(); my $nTotalExpandedAtomSite = @ExpandedAtomSiteList; #for(my $i = 0 ; $i < @AtomTypeList ; $i++) { # print "MakePOSCARFile: atom[$i] = ", $AtomTypeList[$i]->AtomNameOnly(), "$LF"; #} for(my $i = 0 ; $i < $nAtomType ; $i++) { my $atom = $AtomTypeList[$i]; my $name = $atom->AtomNameOnly(); printf OUT " %4s", $name; } print OUT "\n"; my %nAtomTypes; for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) { my $atom = $ExpandedAtomSiteList[$i]; my $name = $atom->AtomName(); # my $name = $atom->AtomNameOnly(); $nAtomTypes{$name}++; } my %Done; for(my $i = 0 ; $i < $nAtomType ; $i++) { my $atom = $AtomTypeList[$i]; my $name = $atom->Label(); # my $name = $atom->AtomNameOnly(); next if($Done{$name}); $Done{$name}++; printf OUT " %4d", $nAtomTypes{$name}; } print OUT "\n"; # print OUT "Selective dynamics # Necessary to specify T or F for coordinates, but removed for phonon\n"; print OUT "Direct\n"; my $iCount = 0; %Done = {}; for(my $ia = 0 ; $ia < $nAtomType ; $ia++) { my $atomtype = $AtomTypeList[$ia]; # my $typename = $atomtype->AtomName(); my $typename = $atomtype->Label(); # my $typename = $atomtype->AtomNameOnly(); next if($Done{$typename}); $Done{$typename}++; #print "ia=$ia atom=$typename$LF"; for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) { my $atom = $ExpandedAtomSiteList[$i]; my $atomname = $atom->AtomName(); #print "name: $atomname [type $typename]\n"; # my $atomname = $atom->AtomNameOnly(); #print " i=$i atom=$atomname$LF"; next if(uc $typename ne uc $atomname); #print "passed\n"; my $charge = $atom->Charge(); my ($x,$y,$z) = $atom->Position(1); my $occupancy = $atom->Occupancy(); #Occupancyが1のサイト # my ($xc,$yc,$zc) = $Crystal->FractionalToCartesian($x,$y,$z); # printf "%-2s %14.9f %14.9f %14.9f T T T\n", $atomname, $x, $y, $z; if($occupancy >= 0.9999) { if($iCount == 0) { printf OUT " %14.9f %14.9f %14.9f T T T\n", $x, $y, $z; } else { printf OUT " %14.9f %14.9f %14.9f T T T\n", $x, $y, $z; } } else { my $i1 = $i+1; if($iCount == 0) { printf OUT " %14.9f %14.9f %14.9f T T T\n", $x, $y, $z; # printf OUT "PAtom%d %14.9f %14.9f %14.9f T T T\n", $i1, $x, $y, $z; } else { printf OUT " %14.9f %14.9f %14.9f T T T\n", $x, $y, $z; # printf OUT "PAtom%d %14.9f %14.9f %14.9f T T T\n", $i1, $x, $y, $z; } } $iCount++; } } close(OUT); return 1; } sub SaveVASPFiles { my ($this, $Crystal, $CellType, $UseConventionalCell, $Function, $Functional, $UseDPP, $SpinPolarized, $Dir, $IsChooseRandomly, $pParams) = @_; my $LF = "
\n"; my $INCAR = Deps::MakePath($Dir, "INCAR", 0); if(unlink($INCAR)) { print "$INCAR was deleted.$LF"; } my $POSCAR = Deps::MakePath($Dir, "POSCAR", 0); if(unlink($POSCAR)) { print "$POSCAR was deleted.$LF"; } my $POTCAR = Deps::MakePath($Dir, "POTCAR", 0); if(unlink($POTCAR)) { print "$POTCAR was deleted.$LF"; } my $KPOINTS = Deps::MakePath($Dir, "KPOINTS", 0); if(unlink($KPOINTS)) { print "$KPOINTS was deleted.$LF"; } my $ret = $this->MakeINCARFile($Crystal, $Function, $Functional, $UseDPP, $SpinPolarized, $INCAR, $pParams); return () if($ret <= 0); $ret = $this->MakePOSCARFile($Crystal, $Function, $POSCAR, $UseConventionalCell, $pParams); return ($INCAR) if($ret <= 0); $ret = $this->MakePOTCARFile($Crystal, $Functional, $UseDPP, $POTCAR, $pParams); return ($INCAR, $POSCAR) if($ret <= 0); my $KListFile = $this->MakeKPOINTSFile($Crystal, $CellType, $Function, $KPOINTS, $pParams); #print "KListFile: $KListFile
\n"; return ($INCAR, $POSCAR, $POTCAR) if(!defined $KListFile); return ($KListFile, $INCAR, $POSCAR, $POTCAR, $KPOINTS); } sub ReadVASPResults { my ($this, $RootDir, $IsPrint) = @_; my ($drive, $directory, $filename, $ext1, $lastdir, $filebody) = Deps::SplitFilePath($RootDir); my $VCRelaxDir = Deps::MakePath($RootDir, "VCRelax", 0); my $SCFDir = Deps::MakePath($RootDir, "SCF", 0); my $DOSDir = Deps::MakePath($RootDir, "DOS", 0); my $INCARHash = $this->ReadINCARtoHash(Utils::MakePath($SCFDir, 'INCAR', '/', 0)); my $KPOINTSHash = $this->ReadKPOINTStoHash(Utils::MakePath($SCFDir, 'KPOINTS', '/', 0)); my $VCRelaxKPOINTSHash = $this->ReadKPOINTStoHash(Utils::MakePath($VCRelaxDir, 'KPOINTS', '/', 0)); my $POTCARHash = $this->ReadPOTCARtoHash(Utils::MakePath($SCFDir, 'POTCAR', '/', 0)); my $POSCARHash = $this->ReadPOSCARtoHash(Utils::MakePath($SCFDir, 'POSCAR', '/', 0)); my $SCFOUTCARHash = $this->ReadOUTCARtoHash(Utils::MakePath($SCFDir, 'OUTCAR', '/', 0)); my $VCROUTCARHash = $this->ReadOUTCARtoHash(Utils::MakePath($VCRelaxDir, 'OUTCAR', '/', 0)); my $DOSCARPath = $this->ReadDOSCAR(Utils::MakePath($DOSDir, 'DOSCAR', '/', 0)); my $pDataArray = $this->{'DataArray'}; my $pDOSupArray = $pDataArray->GetGraphData(0); my $pNeupArray = $pDataArray->GetGraphData(1); my $pDOSdnArray = $pDataArray->GetGraphData(2); my $pNednArray = $pDataArray->GetGraphData(3); #print("this->{'DataArray'}: [$pDataArray] [$pDOSupArray] [$pNeupArray] [$pDOSdnArray] [$pNednArray]\n"); #foreach my $key (%$pDOSupArray) { # print("key: $key\n"); #} my $nData = $pDOSupArray->nData(); my $title = $pDOSupArray->Title(); my $pEDOS = $pDOSupArray->GetDataArray("x0"); # last if(not defined $pX0); $nData = @$pEDOS; my $xlabel = $pDOSupArray->{"x0_Name"}; #print("Title: $title\n"); #print(" X: $xlabel\n"); #print("nData in DOS(up): $nData\n"); for(my $id = 0 ; ; $id++) { my $pY0 = $pDOSupArray->GetDataArray("y$id"); last if(not defined $pY0); my $label0 = $pDOSupArray->{"y${id}_Name"}; #print(" Y: $label0\n"); } # for(my $i = 0 ; $i < $nData ; $i++) { # my $x = $pX0->[$i]; # $out1->print("$x"); # for(my $id = 0 ; ; $id++) { # my $pY0 = $Data0->GetDataArray("y$id"); # last if(!defined $pY0); # my $y = $pY0->[$i]; # $out1->print(",$y"); # } # $out1->print("\n"); # } my $Status = ''; if(-d $VCRelaxDir and $VCROUTCARHash->{RequiredAccuracyMessage} =~ /^\s*$/) { $Status = 'Relaxation not converged(1)'; } elsif(-d $VCRelaxDir and $VCROUTCARHash->{AbortMessage} !~ /is\s+reached/) { $Status = 'Relaxation not converged(2)'; } elsif(-d $VCRelaxDir and $VCROUTCARHash->{TotCPUTime} eq '') { $Status = 'VCR aborted(1)'; } elsif($SCFOUTCARHash->{AbortMessage} =~ /^\s*$/) { $Status = 'SCF not converged(1)'; } elsif($SCFOUTCARHash->{TotCPUTime} eq '') { $Status = 'SCF aborted(1)'; } if($Status ne '') { print("Error in ReadDOSCSV: Abort due to [$Status].\n"); return ('Error', $Status); } my ($EF, $VBM, $CBM, $Eg, $pEDOS, $pDOS) = $this->ReadEgFromDOSOUTCAR(Deps::MakePath($DOSDir, 'OUTCAR', 0)); print("ISPIN=$INCARHash->{ISPIN}\n"); print("PREC=$INCARHash->{PREC}\n"); print("EDIFF=$INCARHash->{EDIFF}\n"); print("EDIFFG=$INCARHash->{EDIFFG}\n"); print("LDAU=$INCARHash->{LDAU}\n"); print("LDAUTYPE=$INCARHash->{LDAUTYPE}\n"); print("LDAUU=$INCARHash->{LDAUU}\n"); print("LDAUJ=$INCARHash->{LDAUJ}\n"); print("ISMEAR=$INCARHash->{ISMEAR}\n"); print("SIGMA=$INCARHash->{SIGMA}\n"); $POTCARHash->{PseudoPotential} =~ s/ .*$//s; print("PseudoPotential=$POTCARHash->{PseudoPotential}\n"); $VCRelaxKPOINTSHash->{KPOINTS} =~ s/^[^\n]*\n[^\n]*\n[^\n]*\n//m; $VCRelaxKPOINTSHash->{KPOINTS} =~ s/\n.*$//m; Utils::DelSpace($VCRelaxKPOINTSHash->{KPOINTS}); my @nKVCRelax = Utils::Split("\\s+", $VCRelaxKPOINTSHash->{KPOINTS}); $KPOINTSHash->{KPOINTS} =~ s/^[^\n]*\n[^\n]*\n[^\n]*\n//m; $KPOINTSHash->{KPOINTS} =~ s/\n.*$//m; Utils::DelSpace($KPOINTSHash->{KPOINTS}); my @nK = Utils::Split("\\s+", $KPOINTSHash->{KPOINTS}); print("KPOINTS=$KPOINTSHash->{KPOINTS}\n"); print("ISPIN=$INCARHash->{ISPIN}\n"); print("Etot=$SCFOUTCARHash->{TOTEN}\n"); print("EF(SCF)=$SCFOUTCARHash->{EF}\n"); print("EF(DOS)=$EF\n"); print("EVBM(DOS)=$VBM\n"); print("ECBM(DOS)=$CBM\n"); print("Eg(DOS)=$Eg\n"); print("SumChemicalComposition=$POSCARHash->{SumChemicalComposition}\n"); print("ChemicalComposition=$POSCARHash->{ChemicalComposition}\n"); print("FormulaUnit=$POSCARHash->{FormulaUnit}\n"); $POSCARHash->{Latt} =~ s/\n/,/g; my @latt = Utils::Split(",+", $POSCARHash->{Latt}); my @aKVCRelax = ($latt[0]*$nKVCRelax[0], $latt[1]*$nKVCRelax[1], $latt[2]*$nKVCRelax[2]); my ($aKminVCRelax, $aKmaxVCRelax) = Utils::CalMinMax(\@aKVCRelax); $aKminVCRelax = sprintf("%4.1f", $aKminVCRelax); my @aK = ($latt[0]*$nK[0], $latt[1]*$nK[1], $latt[2]*$nK[2]); my ($aKmin, $aKmax) = Utils::CalMinMax(\@aK); $aKmin = sprintf("%4.1f", $aKmin); print("Latt=$POSCARHash->{Latt}\n"); print("aKMax=$aKmin-$aKmax\n"); print("Volume=$POSCARHash->{Volume}\n"); print("Density=$POSCARHash->{Density}\n"); my $R = new ChemicalReaction; my $Ref = Deps::MakePath(cwd(), $RootDir, 0); $Ref =~ s/$ENV{HOME}//; my $Eavrg = $SCFOUTCARHash->{TOTEN} / $POSCARHash->{FormulaUnit}; my $Compound = $POSCARHash->{ChemicalComposition}; # my $Compuond = $POSCARHash->{SumChemicalComposition}; my $SortedComposition = $R->SortChemicalFormula($POSCARHash->{ChemicalComposition}); $Compound =~ s/\s//g; $Status .= " / SCFWarning:$SCFOUTCARHash->{Warning}" if($SCFOUTCARHash->{Warning} ne ''); $Status .= " / VCRWarning:$VCROUTCARHash->{Warning}" if($VCROUTCARHash->{Warning} ne ''); if($Status ne '') { print("\n\nWarning in ReadDOSCSV: [$Status].\n\n"); } # $out->print("$filebody,$Compound,$SortedComposition,$POSCARHash->{SumChemicalComposition},," # ."$POSCARHash->{FormulaUnit},$SCFOUTCARHash->{TOTEN},$Eavrg,$SCFOUTCARHash->{EF}," # ."$EF,$VBM,$CBM,$Eg," # ."$POSCARHash->{Density},$latt[0],$latt[1],$latt[2],$POSCARHash->{Volume}," # ."$POTCARHash->{PseudoPotential}," # ."$INCARHash->{PREC},$aKmin,$aKminVCRelax,$INCARHash->{EDIFF},$INCARHash->{EDIFFG}," # ."$INCARHash->{NBANDS}," # ."$INCARHash->{ISPIN},$INCARHash->{NUPDOWN},$INCARHash->{LDAU},$INCARHash->{LDAUU},$INCARHash->{LDAUJ}," # ."$INCARHash->{ISMEAR},$INCARHash->{SIGMA}," # ."$Status,$Ref\n"); return ($EF, $VBM, $CBM, $Eg, $pDOSupArray, $pDOSdnArray, $INCARHash, $KPOINTSHash, $VCRelaxKPOINTSHash, $POTCARHash, $POSCARHash, $SCFOUTCARHash, $VCROUTCARHash); } sub AnalyzeaKProduct { my ($this, $Crystal, $aKProduct) = @_; if(!$Crystal) { print "Error in VASP::AnalyzeaKProduct: Can not get Crystal object\n"; exit; } my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParametersByOutputMode(0); my ($nx, $ny, $nz); my ($NKREDX, $NKREDY, $NKREDZ) = (); if($aKProduct =~ /^fix:(.*)$/i) { my ($a1, $a2, $a3) = Utils::Split(",", $1); ($nx, $NKREDX) = Utils::Split("[/_]", $a1); ($ny, $NKREDY) = Utils::Split("[/_]", $a2); ($nz, $NKREDZ) = Utils::Split("[/_]", $a3); } else { my $an = $aKProduct * 10.0; $nx = int($an / $a) + 1; $ny = int($an / $b) + 1; $nz = int($an / $c) + 1; } return ($nx, $ny, $nz, $NKREDX, $NKREDY, $NKREDZ); } sub ReadIBZKPTToArray { my ($this, $IBZKPTFile) = @_; my $in = JFile->new($IBZKPTFile, 'r') or die "$!: Can not read [$IBZKPTFile].\n"; $in->ReadLine(); my $nK = $in->ReadLine() + 0; $in->ReadLine(); my @k; for(my $i = 0 ; $i < $nK ; $i++) { my $line = $in->ReadLine(); last if(!defined $line); my ($kx, $ky, $kz, $w) = Utils::Split("\\s+", $line); $k[$i] = { kx => $kx, ky => $ky, kz => $kz, w => $w, }; } $in->Close(); return ($nK, \@k); } sub ReadIBZKPT { my ($this, $IBZKPTFile) = @_; open(IN, $IBZKPTFile) or die "$!: Can not read [$IBZKPTFile].\n"; my (@lines, @SCFKList); my $c = 0; $lines[$c++] = ; #Automatically generated mesh my $nK = $lines[$c++] = ; # 6 $lines[$c++] = ; #Reciprocal lattice for(my $i = 0 ; $i < $nK ; $i++) { my $line = ; $lines[$c++] = $line; chomp($line); $SCFKList[$i] = $line; } close(IN); return ($nK, \@lines, \@SCFKList); } sub ReadKListFromklist { my ($this, $klistFile, $nKPointDiv) = @_; my $IsLineMode = 0; my @klists; my @lines; my $c = 0; my $in = JFile->new($klistFile, "r") or die "$!: Can not read [$klistFile].\n"; #k-points along high symmetry linesA my $line = $in->ReadLine(); #15 $line = $in->ReadLine(); #Line-mode $line = $in->ReadLine(); if($line =~ /Line-mode/i) { $IsLineMode = 1; #Reciprocal $line = $in->ReadLine(); my ($kx0, $ky0, $kz0); while(1) { my $line = $in->ReadLine(); last if(!defined $line); Utils::DelSpace($line); next if($line eq ''); #print "l:[$line"; my ($kx, $ky, $kz, $comment, $name) = Utils::Split("\\s+", $line); next if(!defined $kz); next if(abs($kx-$kx0) < 1.0e-4 and abs($ky-$ky0) < 1.0e-4 and abs($kz-$kz0) < 1.0e-4); #print "GLH: ", $GLabelHash{a}, "\n"; $name = '' if(!defined $name); #print "l:[$name, $kx, $ky, $kz]\n"; push(@klists, sprintf("%10.8f %10.8f %10.8f 0.0", $kx, $ky, $kz)); $c++; $kx0 = $kx; $ky0 = $ky; $kz0 = $kz; } } else { $in->rewind(); while(1) { my $line = $in->ReadLine(); last if(!defined $line); $lines[$c++] = $line; Utils::DelSpace($line); last if($line =~ /^END/i); $line =~ s/^\s*[a-zA-Z]+\s+//; my ($kx, $ky, $kz, $ndiv) = Utils::Split("\\s+", $line); if($ndiv ne '') { push(@klists, sprintf("%10.8f %10.8f %10.8f 0.0", $kx/$ndiv, $ky/$ndiv, $kz/$ndiv)); } } } close(IN); if($IsLineMode) { my @a = @klists; @klists = (); my $nd = int($nKPointDiv / @a); $nd = 1 if($nd == 0); for(my $i = 0 ; $i < @a - 1 ; $i++) { my ($x0, $y0, $z0) = Utils::Split("\\s+", $a[$i]); my ($x1, $y1, $z1) = Utils::Split("\\s+", $a[$i+1]); for(my $j = 0 ; $j < $nd ; $j++) { my $kx = $x0 + ($x1 - $x0) / $nd * $j; my $ky = $y0 + ($y1 - $y0) / $nd * $j; my $kz = $z0 + ($z1 - $z0) / $nd * $j; push(@klists, sprintf("%10.8f %10.8f %10.8f 0.0", $kx, $ky, $kz)); } } push(@klists, $a[@a-1]); } my $nKPoints = @klists; return ($nKPoints, \@lines, \@klists); } sub ReadKListFromKPOINTS { my ($this, $klistFile, $SkipNonZerow) = @_; $SkipNonZerow = 0 if(!defined $SkipNonZerow); my @klists; my @lines; my $c = 0; open(IN, $klistFile) or die "$!: Can not read [$klistFile].\n"; my $line0 = $lines[$c++] = ; #kpoints along high symmetry linesA my $nK = $lines[$c++] = ; # 11 $nK += 0; my $c = 0; my $mode; if($line0 =~ /^Explicit/i) { $mode = $line0; } else { $mode = $lines[$c++] = ; # Line-mode or Reciprocal } my $Space; my $iK0 = 0; print "mode: $mode\n"; if($mode =~ /^Line-mode/i) { $Space = $lines[$c++] = ; # Reciprocal while(1) { my $line1 = ; #print "line1(1): $line1\n"; while(1) { last if(eof(IN)); Utils::DelSpace($line1); last if($line1 ne ''); $line1 = ; } last if(eof(IN)); my $line2 = ; last if(eof(IN)); my ($kx0, $ky0, $kz0) = Utils::Split("\\s+", $line1); my ($kx1, $ky1, $kz1) = Utils::Split("\\s+", $line2); for(my $i = 0 ; $i < $nK ; $i++) { my $f = 1.0 * $i / ($nK-1); my $kx = $kx0 + ($kx1 - $kx0) * $f; my $ky = $ky0 + ($ky1 - $ky0) * $f; my $kz = $kz0 + ($kz1 - $kz0) * $f; $lines[$c] = sprintf("%10.8f %10.8f %10.8f 0.0", $kx, $ky, $kz); # $klists[$c] = [$kx, $ky, $kz, 0]; push(@klists, sprintf("%10.8f %10.8f %10.8f 0.0", $kx, $ky, $kz)); #print "k[$c]=($kx,$ky,$kz)\n"; $c++; } } } elsif($mode =~ /^Explicit/i) { $Space = $lines[$c++] = ; # Reciprocal for(my $i = 0 ; $i < $nK ; $i++) { my $line1 = ; last if(!defined $line1); # last if(eof(IN)); my ($kx, $ky, $kz, $w) = Utils::Split("\\s+", $line1); $lines[$c] = sprintf("%10.8f %10.8f %10.8f %10.8f", $kx, $ky, $kz, $w); # $klists[$c] = [$kx, $ky, $kz, 0]; push(@klists, sprintf("%10.8f %10.8f %10.8f 0.0", $kx, $ky, $kz)); $c++; $iK0 = $i if($iK0 == 0 and $w == 0.0); } } else { $Space = $mode; $mode = ''; while(1) { my $line1 = ; last if(eof(IN)); my ($kx, $ky, $kz, $w) = Utils::Split("\\s+", $line1); next if($kz eq ''); $lines[$c] = sprintf("%10.8f %10.8f %10.8f %10.8f", $kx, $ky, $kz, $w); # $klists[$c] = [$kx, $ky, $kz, 0]; push(@klists, sprintf("%10.8f %10.8f %10.8f 0.0", $kx, $ky, $kz)); $c++; } } close(IN); # my $nKPoints = @lines; my $nKPoints = @klists; #print "nKPoints=$nKPoints/$iK0\n"; #exit; return ($nKPoints, \@lines, \@klists, $iK0); } sub MakeKPOINTSForFS { my ($this, $KListPath, $CheckPath, $Crystal, $Title, $UseSymmetry, $nx, $ny, $nz, $K, $IsPrint) = @_; $UseSymmetry = 0 if(!defined $UseSymmetry); $nx = 5 if(!defined $nx); $ny = 5 if(!defined $ny); $nz = 5 if(!defined $nz); $K = 1.0 if(!defined $K); $IsPrint = 1 if(!defined $IsPrint); $Crystal->SetLatticeSystem(undef, 1, 1.0e-3, 1.0e-2); my $check; if($CheckPath) { $check = new JFile(); if(!$check->Open($CheckPath, "w")) { print("$!: Can not write to [$CheckPath].\n") if($IsPrint); } } my @KIndex; my $count = 0; my $BandName = ""; my @lines; print("kx range: (0 - $nx)\n") if($IsPrint); for(my $ix = 0 ; $ix <= $nx ; $ix++) { for(my $iy = 0 ; $iy <= $ny ; $iy++) { my $BandNamePrinted = 0; for(my $iz = 0 ; $iz <= $nz ; $iz++) { my ($IsConverted, $cix, $ciy, $ciz) = $Crystal->ConvertLatticeIndexByLatticeSystem($ix, $iy, $iz); #print("VASP.pm: $ix-$iy-$iz: $IsConverted, $cix, $ciy, $ciz\n"); if($UseSymmetry and $IsConverted) { next; } my $x = 1.0 * $K * $ix / $nx; my $y = 1.0 * $K * $iy / $ny; my $z = 1.0 * $K * $iz / $nz; my $weight = 1.0; if(!$BandNamePrinted) { $BandNamePrinted = 1; $lines[$count] = sprintf("%8.4f %8.4f %8.4f %8.4f ! B%02d%02d\n", $x, $y, $z, $weight, $ix+1, $iy+1); } else { $lines[$count] = sprintf("%8.4f %8.4f %8.4f %8.4f\n", $x, $y, $z, $weight); } if($check) { $KIndex[$count] = sprintf("%03d%03d%03d", $ix, $iy, $iz); $check->printf("%05d: %2d %2d %2d [%s]\n", $count, $ix, $iy, $iz, $KIndex[$count]); } $count++; } } } if($check) { $check->Close(); } print("Save to [$KListPath]\n") if($IsPrint); my $out = new JFile; if(!$out->Open($KListPath, "w")) { print("Error: $!: Can not write to [$KListPath]\n") if($IsPrint); return (0); } $out->print("$Title\n"); $out->print("$count\n"); #($nx+1) * ($ny+1) * ($nz+1), "\n"); # $out->print("Cartesian\n"); $out->print("Reciprocal\n"); for(my $i = 0 ; $i < $count ; $i++) { $out->print($lines[$i]); } $out->printf("END\n\n"); $out->Close(); return (1, @KIndex); } sub MakeBandKPOINTSFileFromKLISTForHF { my ($this, $Function, $OutputName, $klistFile, $UseGammaOnly, $nKPointDiv, $KPoints, $aKProduct, $pParams) = @_; $UseGammaOnly = 0 if(!defined $UseGammaOnly); $nKPointDiv = 11 if(!defined $nKPointDiv or $nKPointDiv <= 0); $KPoints = 'File' if(!defined $KPoints); $aKProduct = 2.0 if(!defined $aKProduct); my $IBZKPTFile = "SCF/IBZKPT"; $IBZKPTFile = "../SCF/IBZKPT" if(!-f $IBZKPTFile); print "*Read [$IBZKPTFile] for HF$LF"; my ($nK, $pHeader, $pSCFKList) = $this->ReadIBZKPT($IBZKPTFile);; my @SCFKList = @$pSCFKList; #klistファイル読み込み my @klists; if($KPoints =~ /File/i and $klistFile =~ /\.KPOINTS$/) { # print "KPOINTS: Copy [$klistFile] to [KPOINTS].\n"; # Utils::CopyFile($klistFile, $OutputName); # return; print "*Read [$klistFile] for HF$LF"; my ($nKPoints, $plines, $pklists) = $this->ReadKListFromKPOINTS($klistFile); @klists = @$pklists; } elsif($KPoints =~ /File/i and $klistFile ne '') { print "*Read [$klistFile] for HF$LF"; my ($nKPoints, $plines, $pklists) = $this->ReadKListFromklist($klistFile, $nKPointDiv); @klists = @$pklists; } #ファイル作製開始 print "*Create [$OutputName]$LF"; unless(open(OUT,">$OutputName")) { print "Can not write to $OutputName.$LF$LF"; return undef; } binmode(OUT); my $nKTotal = @SCFKList + @klists; print OUT "Explicit k-points\n"; print OUT "$nKTotal\n"; print OUT "Reciprocal\n"; for(my $i = 0 ; $i < @SCFKList ; $i++) { print OUT "$SCFKList[$i]\n"; } for(my $i = 0 ; $i < @klists ; $i++) { print "klist[$i]=$klists[$i]\n"; my $i1 = $i+1; print "klist[$i1]=$klists[$i1]\n" if($i == @klists-2); printf OUT "$klists[$i]\n"; } close(OUT); } sub MakeBandKPOINTSFileForHF { my ($this, $Crystal, $CellType, $Function, $fname, $UseGammaOnly, $nKPointDiv, $KPoints, $aKProduct, $pParams) = @_; my $IBZKPTFile = "SCF/IBZKPT"; print "*Read [$IBZKPTFile]$LF"; my ($nK, $pHeader, $pSCFKList) = $this->ReadIBZKPT($IBZKPTFile);; my @SCFKList = @$pSCFKList; #ファイル作製開始 unless(open(OUT,">$fname")) { print "Can not write to $fname.$LF$LF"; return undef; } binmode(OUT); my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParametersByOutputMode(0); my ($nx, $ny, $nz, $NKREDX, $NKREDY, $NKREDZ) = $this->AnalyzeaKProduct($Crystal, $aKProduct); my $XC = new XCrySDen; my $KListDBDir = $XC->SetKListDBDir($this->KListDBDir); my $SPGName = $Crystal->SPGName(); my $iSPG = $Crystal->iSPG(); my ($KListFilePath, @KList) = $XC->ReadKList($iSPG, $SPGName, $CellType); my $nKList = @KList; my $nKTotal = @SCFKList + @KList; print OUT "Explicit k-points\n"; print OUT "$nKTotal\n"; print OUT "Reciprocal\n"; for(my $i = 0 ; $i < @SCFKList ; $i++) { print OUT "$SCFKList[$i]\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'}; printf OUT "%10.4f %10.4f %10.4f 0.0\n", $kx1, $ky1, $kz1; printf OUT "%10.4f %10.4f %10.4f 0.0\n", $kx2, $ky2, $kz2; print OUT "\n"; } } sub MakeKPOINTSFileFromKLIST { my ($this, $Function, $OutputName, $LKPOINTS_OPT, $klistFile, $UseGammaOnly, $nKPointDiv, $KPoints, $aKProduct, $pParams) = @_; $UseGammaOnly = 0 if(!defined $UseGammaOnly); $nKPointDiv = 11 if(!defined $nKPointDiv or $nKPointDiv <= 0); $KPoints = 'File' if(!defined $KPoints); $aKProduct = 2.0 if(!defined $aKProduct); if(!defined $pParams->{METAGGA}) { $pParams->{METAGGA} = ''; } print "

6113: Make KPOINTS from KLIST [$klistFile]

\n"; if($Function =~ /band/) { #klistファイル読み込み print "*Read [$klistFile]$LF"; if($pParams->{HybridFunctional} ne '' or $pParams->{METAGGA} ne '') { print("Hybrid : [$pParams->{HybridFunctional}]\n"); print("METAGGA: [$pParams->{METAGGA}]\n"); print("LKPOINTS_OPT: [$LKPOINTS_OPT]\n"); if($LKPOINTS_OPT ne '.TRUE.') { print("Run MakeBandKPOINTSFileFromKLISTForHF\n"); return $this->MakeBandKPOINTSFileFromKLISTForHF( $Function, $OutputName, $klistFile, $UseGammaOnly, $nKPointDiv, $KPoints, $aKProduct, $pParams); } } my @klists; if($KPoints =~ /File/i and $klistFile =~ /\.KPOINTS$/) { print "KPOINTS: Copy [$klistFile] to [KPOINTS].\n"; Utils::CopyFile($klistFile, $OutputName); return; } elsif($KPoints =~ /File/i and $klistFile ne '') { my $in = JFile->new($klistFile, "r") or die "$!: Can not read [$klistFile].\n"; #k-points along high symmetry linesA my $line = $in->ReadLine(); #15 $line = $in->ReadLine(); #Line-mode $line = $in->ReadLine(); if($line =~ /Line-mode/i) { #Reciprocal $line = $in->ReadLine(); my ($kx0, $ky0, $kz0); while(1) { $line = $in->ReadLine(); last if(!defined $line); my ($kx, $ky, $kz, $comm, $name) = Utils::Split("\\s+", $line); next if(!defined $kz); next if(abs($kx-$kx0) < 1.0e-3 and abs($ky-$ky0) < 1.0e-3 and abs($kz-$kz0) < 1.0e-3); my $s = sprintf("%-7s %f %f %f 1", $name, $kx, $ky, $kz); push(@klists, $s); $kx0 = $kx; $ky0 = $ky; $kz0 = $kz; } } else { $in->rewind(); while(1) { $line = $in->ReadLine();; last if(!defined $line); chomp($line); my $s = substr($line, 0, 10); $s =~ s/^\s*//; $s =~ s/\s*$//; last if($s =~ /^END/i); next if($s =~ /^DELTA/i); next if($s =~ /^LAMBDA/i); next if($s =~ /^SIGMA/i); if($s ne '') { my ($xyz) = ($line =~ /^(\S+\s+\S+\s+\S+\s+\S+\s+\S+)/); push(@klists, $xyz); print " k points: $xyz$LF"; } } } $in->Close(); } elsif($KPoints =~ /File/i) { print "Can not read $klistFile.$LF"; print "Use default klists.$LF"; push(@klists, "R 1 1 1 2"); push(@klists, "GAMMA 0 0 0 2"); push(@klists, "X 1 0 0 2"); push(@klists, "Z 0 0 1 2"); push(@klists, "M 1 1 0 2"); push(@klists, "GAMMA 0 0 0 2"); } else { if(length($KPoints) == 1) { $KPoints = "$KPoints$KPoints"; } for(my $i = 0 ; $i < length($KPoints) ; $i++) { my $c0 = substr($KPoints, $i, 1); #print "$i: $c0\n"; if($c0 =~ /G/i) { push(@klists, "GAMMA 0 0 0 2"); } elsif($c0 =~ /X/i) { push(@klists, "X 1 0 0 2"); } elsif($c0 =~ /Y/i) { push(@klists, "Y 0 1 0 2"); } elsif($c0 =~ /Z/i) { push(@klists, "Z 0 0 1 2"); } elsif($c0 =~ /R/i) { push(@klists, "R 1 1 1 2"); } elsif($c0 =~ /M/i) { push(@klists, "M 1 1 0 2"); } } } #ファイル作製開始 print "*Create [$OutputName]$LF"; unless(open(OUT,">$OutputName")) { print "Can not write to $OutputName.$LF$LF"; return undef; } binmode(OUT); print OUT "k-points along high symmetry linesA\n"; print OUT "$nKPointDiv\n"; print OUT "Line-mode\n"; print OUT "Reciprocal\n"; for(my $i = 0 ; $i < @klists-1 ; $i++) { print "klist[$i]=$klists[$i]\n"; my $i1 = $i+1; print "klist[$i1]=$klists[$i1]\n" if($i == @klists-2); my ($name0,$x0,$y0,$z0,$m0) = ($klists[$i] =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/); my ($name1,$x1,$y1,$z1,$m1) = ($klists[$i+1] =~ /(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/); printf OUT " %8.4f %8.4f %8.4f ! %s\n", $x0/$m0, $y0/$m0, $z0/$m0, $name0; printf OUT " %8.4f %8.4f %8.4f ! %s\n", $x1/$m1, $y1/$m1, $z1/$m1, $name1; print OUT "\n"; } close(OUT); } else { my ($drive, $dir, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($OutputName); my $CARDir; if($drive) { $CARDir = "$drive$dir"; } else { $CARDir = $dir; } my $Crystal = $this->ReadStructureFromCARFiles($CARDir, 0); my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParametersByOutputMode(0); my ($nx, $ny, $nz, $NKREDX, $NKREDY, $NKREDZ) = $this->AnalyzeaKProduct($Crystal, $aKProduct); print "(nx,ny,nz)=($nx,$ny,$nz)\n"; # if($pParams->{HybridFunctional} =~ /^HSE/ and $pParams->{NKRED} > 1) { #if(0) { # $nx = int( ($nx+1) / $pParams->{NKRED}) * $pParams->{NKRED}; # $ny = int( ($ny+1) / $pParams->{NKRED}) * $pParams->{NKRED}; # $nz = int( ($nz+1) / $pParams->{NKRED}) * $pParams->{NKRED}; # $nx = 4 if($nx > 4); # $ny = 4 if($ny > 4); # $nz = 4 if($nz > 4); #} # } # if($pParams->{CalVibration}) { #if(0) { # $nx = 3 if($nx > 3); # $ny = 3 if($ny > 3); # $nz = 3 if($nz > 3); #} # } unless(open(OUT,">$OutputName")) { print "Can not write to $OutputName.$LF$LF"; return undef; } binmode(OUT); if(!$UseGammaOnly) { print OUT "Automatic mesh\n"; print OUT "0\n"; print OUT "Gamma\n"; print OUT "$nx $ny $nz\n"; print OUT "0. 0. 0.\n"; } else { print OUT "Automatic mesh\n"; print OUT "0\n"; print OUT "Gamma\n"; print OUT "1 1 1\n"; print OUT "0. 0. 0.\n"; # print OUT "Automatic mesh\n"; # print OUT "0\n"; # print OUT "Automatic\n"; # print OUT $nx*$ny*$nz, "\n"; } close(OUT); } } sub MakeKPOINTSForMass { my ($this, $OutputName, $klistFile, $pParams) = @_; #klistファイル読み込み print "*Read k points from [$klistFile]\n"; my @klist = BandStructure->ReadKListFile($klistFile, 0); my $nk = @klist; #ファイル作製開始 print "*Create [$OutputName]$LF"; my $out = JFile->new($OutputName, 'w'); if(!$out) { print "Can not write to $OutputName.$LF$LF"; return undef; } # if($pParams->{HybridFunctional} eq '') { # $out->print("k-points along high symmetry linesA\n"); # $out->printf("%d\n", $nk); # $out->print("Line-mode\n"); # $out->print("Reciprocal\n"); # for(my $i = 0 ; $i < $nk ; $i++) { # my $p0 = $klist[$i]; # $out->printf("%10.7f %10.7f %10.7f 0.0\n", $p0->{kx}, $p0->{ky}, $p0->{kz}); # } # } # else { { my $IBZKPTFile = "../DFTSCF/IBZKPT"; $IBZKPTFile = "./DFTSCF/IBZKPT" if(!-f $IBZKPTFile); $IBZKPTFile = "../SCF/IBZKPT" if(!-f $IBZKPTFile); $IBZKPTFile = "./SCF/IBZKPT" if(!-f $IBZKPTFile); print "*Read IBZKPT from [$IBZKPTFile].\n"; my ($nKIBZKPT, $pIBZKPTLines, $pIBZKPTSCFKList) = $this->ReadIBZKPT($IBZKPTFile); $out->print("Explicit k-points\n"); $out->printf("%d\n", $nKIBZKPT + $nk); $out->print("Reciprocal\n"); for(my $i = 0 ; $i < $nKIBZKPT ; $i++) { $out->print("$pIBZKPTSCFKList->[$i]\n"); } for(my $i = 0 ; $i < $nk ; $i++) { my $p0 = $klist[$i]; $out->printf("%10.7f %10.7f %10.7f 0.0\n", $p0->{kx}, $p0->{ky}, $p0->{kz}); } } $out->Close(); } sub MakeKPOINTSForBand { my ($this, $POSCAR, $Function, $OutputName, $klistFile, $nKPointDiv, $KPoints, $pParams) = @_; # $UseGammaOnly = 0 if(!defined $UseGammaOnly); $nKPointDiv = 11 if(!defined $nKPointDiv or $nKPointDiv <= 0); $KPoints = 'File' if(!defined $KPoints); # $aKProduct = 2.0 if(!defined $aKProduct); if($Function ne 'band') { print("Error in VASP.pm::MakeKPOINTSForBand: Function [$Function] is not 'band'.\n"); return; } #klistファイル読み込み my @klist; if($KPoints =~ /File/i) { print "*Read k points from [$klistFile]\n"; @klist = BandStructure->ReadKListFile($klistFile); } #ファイル作製開始 print "*Create [$OutputName]$LF"; my $out = JFile->new($OutputName, 'w'); if(!$out) { print "Can not write to $OutputName.$LF$LF"; return undef; } if($pParams->{HybridFunctional} eq '') { if(@klist == 0 and $klistFile ne 'File' and !-f $klistFile) { for(my $i = 0 ; $i < length($KPoints) ; $i++) { my $c0 = substr($KPoints, $i, 1); if($c0 =~ /G/i) { push(@klist, {name => 'GAMMA', kx => 0.0, ky => 0.0, kz => 0.0}); } elsif($c0 =~ /X/i) { push(@klist, {name => 'X', kx => 0.5, ky => 0.0, kz => 0.0}); } elsif($c0 =~ /Y/i) { push(@klist, {name => 'Y', kx => 0.0, ky => 0.5, kz => 0.0}); } elsif($c0 =~ /Z/i) { push(@klist, {name => 'Z', kx => 0.0, ky => 0.0, kz => 0.5}); } elsif($c0 =~ /R/i) { push(@klist, {name => 'R', kx => 0.5, ky => 0.5, kz => 0.5}); } elsif($c0 =~ /M/i) { push(@klist, {name => 'M', kx => 0.5, ky => 0.5, kz => 0.0}); } } } elsif(@klist == 0) { print "Can not read $klistFile.$LF"; print "Use default klist.$LF"; push(@klist, {name => 'R', kx => 0.5, ky => 0.5, kz => 0.5}); push(@klist, {name => 'GAMMA', kx => 0.0, ky => 0.0, kz => 0.0}); push(@klist, {name => 'X', kx => 0.5, ky => 0.0, kz => 0.0}); push(@klist, {name => 'M', kx => 0.5, ky => 0.5, kz => 0.0}); push(@klist, {name => 'Z', kx => 0.0, ky => 0.0, kz => 0.5}); push(@klist, {name => 'GAMMA', kx => 0.0, ky => 0.0, kz => 0.0}); } $out->print("k-points along high symmetry linesA\n"); $out->print("$nKPointDiv\n"); $out->print("Line-mode\n"); $out->print("Reciprocal\n"); for(my $i = 0 ; $i < @klist-1 ; $i++) { my $p0 = $klist[$i]; my $p1 = $klist[$i+1]; $out->printf(" %8.4f %8.4f %8.4f ! %s\n", $p0->{kx}, $p0->{ky}, $p0->{kz}, $p0->{name}); $out->printf(" %8.4f %8.4f %8.4f ! %s\n", $p1->{kx}, $p1->{ky}, $p1->{kz}, $p1->{name}); $out->printf("\n"); } } else { print "*Read Structure from [$POSCAR] etc.\n"; my $Crystal = $this->ReadStructureFromCARFiles($POSCAR, 1); #print "Crystal=$Crystal\n"; my ($nk, $pk) = BandStructure->DivideKList($Crystal, \@klist, $nKPointDiv); my $IBZKPTFile = "../DFTSCF/IBZKPT"; $IBZKPTFile = "./DFTSCF/IBZKPT" if(!-f $IBZKPTFile); $IBZKPTFile = "../SCF/IBZKPT" if(!-f $IBZKPTFile); $IBZKPTFile = "./SCF/IBZKPT" if(!-f $IBZKPTFile); print "*Read IBZKPT from [$IBZKPTFile].\n"; my ($nKIBZKPT, $pIBZKPTLines, $pIBZKPTSCFKList) = $this->ReadIBZKPT($IBZKPTFile); $out->print("Explicit k-points\n"); $out->printf("%d\n", $nKIBZKPT + $nk); $out->print("Reciprocal\n"); for(my $i = 0 ; $i < $nKIBZKPT ; $i++) { $out->print("$pIBZKPTSCFKList->[$i]\n"); } for(my $i = 0 ; $i < $nk ; $i++) { my $p0 = $pk->[$i]; $out->printf("%10.7f %10.7f %10.7f 0.0\n", $p0->{kx}, $p0->{ky}, $p0->{kz}); } } $out->Close(); } sub MakeKPOINTSFile { my ($this, $Crystal, $CellType, $Function, $fname, $UseGammaOnly, $nKPointDiv, $KPoints, $aKProduct, $pParams) = @_; $aKProduct = 2.0 if($aKProduct eq ''); $UseGammaOnly = 0 if(!defined $UseGammaOnly); $nKPointDiv = 9 if(!defined $nKPointDiv or $nKPointDiv <= 0); if( !defined $pParams->{METAGGA} ) { $pParams->{METAGGA} = ''; } print "

Make KPOINTS [$fname]

\n"; #ファイル作製開始 unless(open(OUT,">$fname")) { print "Can not write to $fname.$LF$LF"; return undef; } binmode(OUT); my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParametersByOutputMode(0); my ($nx, $ny, $nz, $NKREDX, $NKREDY, $NKREDZ) = $this->AnalyzeaKProduct($Crystal, $aKProduct); #print "(nx,ny,nz)=($nx,$ny,$nz)\n"; my $XC = new XCrySDen; my $KListDBDir = $XC->SetKListDBDir($this->KListDBDir()); print "klist DB dir: $KListDBDir$LF"; my $SPGName = $Crystal->SPGName(); my $iSPG = $Crystal->iSPG(); my ($KListFilePath, @KList) = $XC->ReadKList($iSPG, $SPGName, $CellType); my $nKList = @KList; print "KList DB file: $KListFilePath$LF\n"; if($Function =~ /(band|nscf)/i) { if($pParams->{HybridFunctional} ne '' or $pParams->{METAGGA} ne '') { return $this->MakeBandKPOINTSFileForHF($Crystal, $CellType, $Function, $fname, $UseGammaOnly, $nKPointDiv, $KPoints, $aKProduct, $pParams); } print OUT "k-points along high symmetry linesA\n"; print OUT "$nKPointDiv\n"; # print OUT "10\n"; print OUT "Line-mode\n"; print OUT "Reciprocal\n"; # print OUT "0.0 0.0 1.0\n"; # print OUT "0.0 0.0 0.0\n"; # print OUT "\n"; # print OUT "0.0 0.0 0.0\n"; # print OUT "0.0 1.0 1.0\n"; # print OUT "\n"; # print OUT "0.0 1.0 1.0\n"; # print OUT "1.0 1.0 1.0\n"; # print OUT "\n"; # print OUT "1.0 1.0 1.0\n"; # print OUT "0.0 0.0 0.0\n"; # print OUT "\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'}; printf OUT "%10.4f %10.4f %10.4f\n", $kx1, $ky1, $kz1; printf OUT "%10.4f %10.4f %10.4f\n", $kx2, $ky2, $kz2; print OUT "\n"; } } elsif($Function =~ /relax/i) { if($nx == 1 and $ny == 1 and $nz == 1) { print OUT "Gamma only\n"; print OUT "1\n"; print OUT "Cartesian\n"; print OUT "0.0 0.0 0.0 1.\n"; } else { if($UseGammaOnly) { print OUT "Automatic mesh\n"; print OUT "0\n"; print OUT "Gamma\n"; print OUT "$nx $ny $nz\n"; print OUT "0. 0. 0.\n"; } else { print OUT "Automatic mesh\n"; print OUT "0\n"; print OUT "Automatic\n"; print OUT $nx*$ny*$nz, "\n"; } } } else { if($UseGammaOnly) { print OUT "Automatic mesh\n"; print OUT "0\n"; print OUT "Gamma\n"; print OUT "$nx $ny $nz\n"; print OUT "0. 0. 0.\n"; } else { print OUT "Automatic mesh\n"; print OUT "0\n"; print OUT "Automatic\n"; print OUT $nx*$ny*$nz, "\n"; } } close(IN); return $KListFilePath; } 1;