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 Sci::ChemicalReaction;

#===============================================
# スクリプト大域変数
#===============================================
my $LF = "<br>\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 $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 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";
	}
	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 :");
	my $EF;
	($EF) = ($line =~ /E-fermi\s*:\s*(\S+)/) if($line);
	$in->Close();
	$EF = 0.0 unless(defined $EF);
#print "***EF=$EF eV\n";
	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 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, $EF, $w) = Utils::Split("\\s+", $line);
print "nData=$nData\n";

	my (@TE, %DOS);
	for(my $i = 0 ; $i < $nData ; $i++) {
		$line = $in->ReadLine();
		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();
		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();
			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) = @_;

	my $POSCAR = $this->GetPOSCARFileName($path);
print "VASP::ReadDOSCAR: 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";

	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 ($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 $cc = 0;
	while(1) {
$cc++;
		$in->ReadLine();
		my @PDOStup;
		my @PDOSsup;
		my @PDOSpup;
		my @PDOSdup;
		my @PDOSfup;
		my @PDOStdn;
		my @PDOSsdn;
		my @PDOSpdn;
		my @PDOSddn;
		my @PDOSfdn;
		for(my $i = 0 ; $i < $nData ; $i++) {
			$line = $in->ReadLine();
			last if(not defined $line);
			my ($e, $dsu, $dsd,$dpu, $dpd, $ddu, $ddd, $dfu, $dfd) = Utils::Split("\\s+", $line);
			last if(not defined $e);
			$dfu = 0.0 if(!defined $dfu);
			$dfd = 0.0 if(!defined $dfd);
			if(!$this->IsSpinPolarized()) {
				($dsu, $dpu, $ddu) = ($dsu, $dsd, $dpu);
			}
			$PDOStup[$i] = $dsu + $dpu + $ddu + $dfu;
			$PDOSsup[$i] = $dsu + 0.0;
			$PDOSpup[$i] = $dpu + 0.0;
			$PDOSdup[$i] = $ddu + 0.0;
			$PDOSfup[$i] = $dfu + 0.0;
			$IntDOSup[$i] -= $PDOStup[$i];
			if($this->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];
			}
			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+//;
		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();

print "nAtomKinds = $nAtomKinds\n";

	$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 ReadEIGENVAL
{
	my ($this, $path) = @_;
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 "VASP::ReadEIGENVAL: IsHF=$IsHF.\n";

	my $POSCAR = $this->GetPOSCARFileName($path);
print "VASP::ReadEIGENVAL: Read [$POSCAR].\n";
	my $Crystal = $this->ReadStructureFromCARFiles($POSCAR, 1);

	my $OUTCAR = $this->GetOUTCARFileName($path);
	my $EF = $this->ReadFermiEnergy($OUTCAR);
print "EF: $EF eV\n";

	my $KPOINTS = $this->GetKPOINTSFileName($path);
print "Read KPOINTS from [$KPOINTS]\n";
	my ($nKPoints, $pKPOINTSLines, $pKPOINTSList, $iK0) = $this->ReadKListFromKPOINTS($KPOINTS);
	$iK0 = 0 if(!$IsHF);
	$this->{iKPoint0} = $iK0;
	$this->{iKPoint1} = $nKPoints;
print "KPOINTS: iK = $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);
	}
	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();

	$CARDir = $this->GetCARDir($CARDir);
	my $POSCARPath = ($hash{POSCARPath})? $hash{POSCARPath} : Deps::MakePath($CARDir, "POSCAR", 0);
	my $POTCARPath = Deps::MakePath($CARDir, "POTCAR", 0);

	my $crystal = new Crystal();

#print "VASP::ReadStructureFromCARFiles: Read [$POTCARPath]\n" if($IsPrint);
	my @Atomtypes = $this->ReadAtomTypesFromPOTCAR($POTCARPath, 1, 1);
	return -1 if(@Atomtypes == 0 or $Atomtypes[0] eq "-1");

	for(my $i = 0 ; $i < @Atomtypes ; $i++) {
		$crystal->AddAtomType($Atomtypes[$i], 0);
#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);
	$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];
		for(my $j = 0 ; $j < $nAtomTypes[$i] ; $j++) {
			$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, 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($VASPProgOldDir, "pot_GGA", 0);
	}
	elsif($lcF eq 'paw') {
		$PotDir = Deps::MakePath($VASPProgOldDir, "potpaw", 0);
	}
	elsif($lcF eq 'paw_gga') {
		$PotDir = Deps::MakePath($VASPProgOldDir, "potpaw_GGA", 0);
	}
	elsif($lcF eq 'paw_pbe') {
		$PotDir = Deps::MakePath($VASPProgOldDir, "potpaw_PBE", 0);
	}
	elsif($lcF eq 'paw_lda52') {
		$PotDir = Deps::MakePath($VASPProgOldDir, "potpaw_LDA52", 0);
	}
	elsif($lcF eq 'paw_pbe52') {
		$PotDir = Deps::MakePath($VASPProgOldDir, "potpaw_PBE52", 0);
	}
	else { #us
		$PotDir = Deps::MakePath($VASPProgOldDir, "pot", 0);
	}
	$PotDir = Deps::MakePath($PotDir, "elements", 0);
#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]<br>\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->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";
			exit;
		}
		my $PotcarFile = $POTRecommendations[0];
		push(@POTFiles, $PotcarFile);
#print "  [$PotcarFile] is used for [$name]\n";
		if(defined $fname) {
			unless(open(IN, "<$PotcarFile")) {
				print "<H2>Error: Can not read [$PotcarFile]!!</H2>\n";
				return -1;
			}
			print "<b>Use $PotcarFile for [$name].</b><br>\n";
			while(<IN>) {
				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 @lines = $in->ReadFileToLines($POSCARPath);
#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) = @_;

	unlink($OutputFile);

	my @lines = JFile->new()->ReadFileToLines($InputFile);
	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');
	}
#	$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 $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 = <IN>;
		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);

	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;
			}
		}

		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($NBANDS ne '' and ($a,$b,$c) = ($line =~ /^([\s#]*NBANDS\s*=\s*)(\S*)(.*)$/) ) {
			my $v = $this->ReadKeyValue("NBANDS\\s*=\\s*(\\S+)", undef, $OUTCAR);
			if($NBANDS =~ /^\-(.*)$/) {
				$NBANDS = $v - $1;
			}
			elsif($NBANDS =~ /^\+(.*)$/) {
				$NBANDS = $v + $1;
			}
			elsif($NBANDS =~ /^x(.*)$/) {
				$NBANDS = $v * $1;
			}
			elsif($NBANDS =~ /^\/(.*)$/) {
				$NBANDS = $v / $1;
			}
print "NBANDS changed from $v to $NBANDS\n";
			$a =~ s/^(\s*)#/$1/;
			print OUT "$a$NBANDS$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;
		}

		if($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+)(.*)$/) ) {
				$a =~ s/^(\s*)#/$1/;
				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#]*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/#//;
				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#]*SIGMA\s*=\s*)(\S+)(.*)$/) ) {
				$a =~ s/#//;
				print OUT "$a$b$c\n";
			}
			elsif( ($a,$b,$c) = ($line =~ /^([\s#]*ICHARGE\s*=\s*)(\S+)(.*)$/) ) {
				$a =~ s/#//;
				print OUT "${a}10$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/#//;
				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#]*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#]*ICHARGE\s*=\s*)(\S+)(.*)$/) ) {
				$a =~ s/#//;
				print OUT "${a}11$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|IBNAD|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 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);

	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 ReadElementFromPOT
{
	my ($this, $potfile) = @_;
	unless(open(IN,"<$potfile")) {
		print "ReadElementFromPOT: Can not read [$potfile].$LF$LF";
		return -1;
	}
	binmode(IN);
	my $line = <IN>;
	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 = <IN>;
		($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);
	}

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();
	$line = $in->ReadLine() if($line !~ /^(\d\s)$/);
	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/#.*$//;
		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();
	return \%hash;
}

sub ReadKPOINTStoHash
{
	my ($this, $infile) = @_;

	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;

	$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;
			}
		}
		my $line = $in->SkipTo("\\s*End of Dataset");
		last if(!defined $line);

		$count++;
	}
	$in->Close();
	return \%hash;
}

sub GetTotalValenceElectrons
{
	my ($this, $infile) = @_;

	my $pPOT = $this->ReadPOTCARtoHash($infile);
	my $pPOS = $this->ReadPOSCARtoHash($infile);
	my $pn = $pPOS->{pnAtomsForEachSite};
	my $nVEL = 0;
	for(my $i = 0 ; $i < @$pn ; $i++) {
		my $key = "PseudoPotential$i";
		my $p = $pPOT->{"${key}Hash"};
print "$i: $pn->[$i]: $p->{AtomName}: nVEL = $p->{ZVAL}\n";
		$nVEL += $pn->[$i] * $p->{ZVAL};
	}
	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);
	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};
			$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);
}

sub ReadPOSCARtoHash
{
	my ($this, $dir) = @_;
	$dir = Deps::ExtractDirectory($dir) if(-f $dir);

	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{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();
	}

	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 =~ /!!!/) {
			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 =~ /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+)/) {
			$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 =~ /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 =~ /LDIPOL\s*=\s*(\S+)/) {
			$hash{LDIPOL} = $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, $NVBup, $DEFup);
	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, $NVBdn, $DEFdn);
	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) = @_;

	if($pParams->{HybridFunctional}) {
		$pParams->{IBRION} = 5 if($pParams->{IBRION} == 7);
		$pParams->{IBRION} = 6 if($pParams->{IBRION} == 8);
	}

	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 "  <b>Element</b> from @POTFiles[$i]: $s$LF";
		push(@Element, $s);
	}
	my @RWIGS;
	for(my $i = 0 ; $i < @POTFiles ; $i++) {
		my $s = $this->ReadRWIGSFromPOT($POTFiles[$i]);
#print "  <b>RWIGS</b> 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 wavef 1: CHGCAR 2:Atomic charge\n";
	print OUT "  #       +10: Non-selfconsistent\n";

	if($Function =~ /band|dos/i) {
		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|Normal|Medium|Low\n";
	if($Function =~ /vc-relax/i) {
		print OUT "    PREC = High\n";
	}
	else {
		print OUT "    PREC = Normal\n";
	}
	print OUT "  #NBANDS: Set NBANDS to double for collinear calculation\n";
	print OUT "  #NBANDS = 24\n";
	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\n";
	print OUT "  #IALGO = 48\n";
	my $HFALGO = '53';
#	my $HFALGO = ($Function =~ /(dos|band|eDensity)/i)? '53' : 'Auto';
	if($pParams->{HybridFunctional} eq 'HF') {
#		print OUT "  ALGO      = Damped\n";
		print OUT "  ALGO      = $HFALGO\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\n";
		print OUT "  #NKRED     = 2\n";
		print OUT "  #NKREDX    =\n";
		print OUT "  #NKREDY    =\n";
		print OUT "  #NKREDZ    =\n";
		print OUT "  #TIME      = 0.4\n";
		print OUT "  #IMIX      = 1\n";
		print OUT "  #AMIX      = a\n";
		print OUT "  #BMIX      = 2.0\n";
	}
	elsif($pParams->{HybridFunctional} =~ /^HSE/) {
#		print OUT "  ALGO      = Damped\n";
		print OUT "  ALGO      = $HFALGO\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\n";
		print OUT "  #NKRED     = 2\n";
		print OUT "  #NKREDX    =\n";
		print OUT "  #NKREDY    =\n";
		print OUT "  #NKREDZ    =\n";
		print OUT "  #TIME      = 0.5\n";
		print OUT "  #IMIX      = 1\n";
		print OUT "  #AMIX      = a\n";
		print OUT "  #BMIX      = 2.0\n";
	}
	elsif($pParams->{HybridFunctional} eq 'PBE0') {
#		print OUT "  ALGO      = All\n";
		print OUT "  ALGO      = $HFALGO\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\n";
		print OUT "  #NKRED     = 2\n";
		print OUT "  #NKREDX    =\n";
		print OUT "  #NKREDY    =\n";
		print OUT "  #NKREDZ    =\n";
		print OUT "  TIME      = 0.5\n";
		print OUT "  #IMIX      = 1\n";
		print OUT "  #AMIX      = a\n";
		print OUT "  #BMIX      = 2.0\n";
	}
	else {
#		print OUT "  #ALGO      = All\n";
		print OUT "  ALGO      = $HFALGO\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 "  #NKRED     = 2\n";
		print OUT "  #NKREDX    =\n";
		print OUT "  #NKREDY    =\n";
		print OUT "  #NKREDZ    =\n";
		print OUT "  #TIME      = 0.5\n";
		print OUT "  #IMIX      = 1\n";
		print OUT "  #AMIX      = a\n";
		print OUT "  #BMIX      = 2.0\n";
	}

	print OUT "  #NSIM = 4\n";
	print OUT "  #NELM: Number of electronic steps\n";
	if($Function =~ /band/i) {
		print OUT "    NELM = 0\n";
		print OUT "    NELMIN = 0\n";
		print OUT "    NELMDL = 3 # of ELM steps\n";
	}
	else {
		print OUT "    #NELM = 60\n";
		print OUT "    #NELMIN = 0\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";
	print OUT "    #LSORBIT = .TRUE.\n";
	print OUT "    #SAXIS = 0 0 1\n";
#	print OUT "    #MAGMOM = 0 0 1\n";
	print OUT "  #Non-collinear setup\n";
	print OUT "    #LNONCOLLINEAR = .TRUE.\n";
#	print OUT "    #MAGMOM = 0 0 1   0 0 1   0 0 1\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 "      #NBANDS = 24\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 "  #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 "  #PAW Control:\n";
	print OUT "  #  These are very important also for L(S)DA+U calculations\n";
	print OUT "  #LMAXMIX: Default: 2\n";
	print OUT "  #      Use 4 and 6 for d and f orbitals in L(S)DA+U calculations\n";
	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 "  # 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 "  #GGA = RE\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 "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 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 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 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";
	}

	if($Functional =~ /gga/i) {
		print OUT "\n";
		print OUT "Functional\n";
		print OUT "  #Only for LDA-based pseudopotentials\n";
		print OUT "  #GGA = PE\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 "  LCHARGE = .TRUE.\n";
	print OUT "  LVTOT   = .TRUE. # Write TOTAL local potential in vasp.5.x\n";
	print OUT "  #LVHAR   = .TRUE.\n";
	print OUT "  #LORBIT  = 2\n";
	print OUT "  LELF    = .TRUE.\n";
	print OUT "  LAECHG  = .TRUE.\n"; # Write core charge to AECCAR0, valance charge to AECCAR2
	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";
	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";
	if($Function =~ /relax/i) {
		if($pParams->{HybridFunctional} ne '') {
			print OUT "  ISMEAR = 1\n";
			print OUT "  SIGMA = 0.2 broad. in eV\n";
		}
		else {
			print OUT "  ISMEAR = -5\n";
			print OUT "  SIGMA = 0.02 broad. in eV\n";
		}
	}
	else {
		if($pParams->{HybridFunctional} ne '') {
			print OUT "  ISMEAR = 1\n";
			print OUT "  SIGMA = 0.2 broad. in eV\n";
		}
		else {
			print OUT "  ISMEAR = -5\n";
			print OUT "  SIGMA = 0.02 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 "  #IBNAD = 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 "<H1>Make POSCAR</H1>\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);
	if(defined $Crystal->{ConventionalSPGName} and $Crystal->{ConventionalSPGName} =~ /^\s*[FIABC]/i) {
		my $pl = $Crystal->{ConventionalLatticeParameters};
		($a, $b, $c, $alpha, $beta, $gamma) = @$pl;
	}
	else {
		($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParametersByOutputMode(0);
	}
#print "***L [$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";
#}

	my %nAtomTypes;
	for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) {
		my $atom = $ExpandedAtomSiteList[$i];
		my $name = $atom->AtomNameOnly();
		$nAtomTypes{$name}++;
	}
	my %Done;
	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $atom = $AtomTypeList[$i];
		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->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();
			my $atomname  = $atom->AtomNameOnly();
#print "  i=$i atom=$atomname$LF";
			next if(uc $typename ne uc $atomname);
			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 "PAtom%d   %14.9f %14.9f %14.9f T T T\n", $i1, $x, $y, $z;
				}
				else {
					printf OUT "PAtom%d   %14.9f %14.9f %14.9f T T T\n", $i1, $x, $y, $z;
				}
			}
			$iCount++;
		}
	}
	close(OUT);

	return 1;
}

sub AnalyzeaKProduct
{
	my ($this, $Crystal, $aKProduct) = @_;

	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 ReadIBZKPT
{
	my ($this, $IBZKPTFile) = @_;

	open(IN, $IBZKPTFile) or die "$!: Can not read [$IBZKPTFile].\n";
	my (@lines, @SCFKList);
	my $c = 0;
	$lines[$c++] = <IN>; #Automatically generated mesh
	my $nK = $lines[$c++] = <IN>; #       6
	$lines[$c++] = <IN>; #Reciprocal lattice
	for(my $i = 0 ; $i < $nK ; $i++) {
		my $line = <IN>;
		
		$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) = @_;

	my @klists;
	my @lines;
	my $c = 0;

	open(IN, $klistFile) or die "$!: Can not read [$klistFile].\n";
	my $line0 = $lines[$c++] = <IN>; #kpoints along high symmetry linesA
	my $nK   = $lines[$c++] = <IN>; #       11
	$nK += 0;
	my @lines;
	my $c = 0;
	my $mode;
	if($line0 =~ /^Explicit/i) {
		$mode = $line0;
	}
	else {
		$mode = $lines[$c++] = <IN>; #       Line-mode or Reciprocal
	}
	my $Space;
	my $iK0 = 0;

print "mode: $mode\n";
	if($mode =~ /^Line-mode/i) {
		$Space = $lines[$c++] = <IN>; # Reciprocal
		while(1) {
			my $line1 = <IN>;
#print "line1(1): $line1\n";
			while(1) {
				last if(eof(IN));
				Utils::DelSpace($line1);
				last if($line1 ne '');
				$line1 = <IN>;
			}
			last if(eof(IN));
			my $line2 = <IN>;
			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++] = <IN>; # Reciprocal
		for(my $i = 0 ; $i < $nK ; $i++) {
			my $line1 = <IN>;
			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 = <IN>;
			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;

	return ($nKPoints, \@lines, \@klists, $iK0);
}

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, $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($Function =~ /band/) {
#klistファイル読み込み
print "*Read [$klistFile]$LF";
		if($pParams->{HybridFunctional} ne '') {
			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 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);

#ファイル作製開始
	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 '') {
			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;
}

sub SaveVASPFiles
{
	my ($this, $Crystal, $CellType, $UseConventionalCell, $Function, $Functional, 
		$UseDPP, $SpinPolarized,
		$Dir, $IsChooseRandomly, $pParams) = @_;
	my $LF = "<br>\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<br>\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);
	my $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);
}

1;