#!/usr/bin/perl

BEGIN {
#use lib 'd:/Programs/Perl/lib';
#use lib '/home/tkamiya/bin/lib';
my $BaseDir = $ENV{'TkPerlDir'};
#print "\nBaseDir: $BaseDir\n";
@INC = ("$BaseDir/lib", "$BaseDir/VNL", "d:/Programs/Perl/lib", @INC);
}

use strict;
#use warnings;
use File::Path;
use File::Basename;
use File::Find;

use Math::Matrix;
use Math::MatrixReal;

use Deps;
use Utils;
use JFile;

use MyApplication;
use Sci::Algorism;
use Sci::GeneralFileFormat;

use Crystal::CIF;
use Crystal::Crystal;
use Crystal::SpaceGroup;
use Crystal::AtomType;
use Crystal::VASP;
use Crystal::VESTA;
use Crystal::XCrySDen;

#===============================================
# デバッグ関係変数
#===============================================
#$PrintLevelが大きいほど、情報が詳しくなる
my $PrintLevel = 0;

#===============================================
# 文字コード関係変数
#===============================================
# sjis, euc, jis, noconv
my $PrintCharCode      = Deps::PrintCharCode();
my $OSCharCode         = Deps::OSCharCode();
my $FileSystemCharCode = Deps::FileSystemCharCode();

my $LF        = Deps::LF();
my $DirSep    = Deps::DirSep();
my $RegDirSep = Deps::RegDirSep();

#===============================================
# Applicationオブジェクト作成
#===============================================
my $App = new MyApplication;
exit if($App->Initialize() < 0);

#$App->SetLF("<br>\n");
#$App->SetPrintCharCode("sjis");
#$App->SetDebug($Debug);
$App->SetDeleteHTMLFlag(1);

#===============================================
# スクリプト大域変数
#===============================================
my $InitialDirectory = Deps::GetWorkingDirectory();
my %ParamHash;

#==========================================
# コマンドラインオプション読み込み
#==========================================
$App->AddArgument("--Action",
		"--Action=[ModifyFiles|MakeINCAR|ModifyPOSCAR|CheckRWIGS|"
		."MakeCIF|ConvCONTCAR|MakeVESTAFile|MakeXSFFile|MakeRelaxXSFFile|MakePhononXSFFile|CheckUnitCellVariation|"
		."MakeMergeEIGENVALSH|AddEIGENVAL|RepairEIGENVAL|ChangeRWIGS|"
		."MakeDOSCSV|ChangeDensityFileNames]", '');
$App->AddArgument("--UseConventionalCell", "--UseConventionalCell=[Yes|No] (Def:No)", "No");
$App->AddArgument("--Function",      "--Function=[scf|nscf|band|edensity|relax|vc-relax|md|phonon] (Def:scf)", "scf");
$App->AddArgument("--Functional",    "--Functional=[PWA_PBE52|PAW_GGA52|PWA_PBE|PAW_GGA|GGA|US_LDA] (Def:PAW_PBE)", "PAW_PBE");
$App->AddArgument("--UseDPP",        "--UseDPP=[0|1] (Def:1)", 1);
$App->AddArgument("--SpinPolarized", "--SpinPolarized=[No|Yes] (Def:No)", "No");
$App->AddArgument("--InverseOrder",  "--InverseOrder=[No|Yes] (Def:No)",  "No");
$App->AddArgument("--EnergyRange",   "--EnergyRange=val (Def: 1.0)", 1.0);
$App->AddArgument("--AllSeparated",  "--AllSeparated=[0|1] (Def: 1)", 1);
$App->AddArgument("--MinEnergy",       "--MinEnergy=-val (Def: -0.5)", -0.5);
$App->AddArgument("--MaxEnergy",       "--MaxEnergy=val (Def: 0.0)", 0.0);
$App->AddArgument("--nMesh",           "--nMesh=val (Def: 1000)", 1000);
$App->AddArgument("--RemoveExtention", "--RemoveExtention=[0|1] (Def: 0)", 0);
$App->AddArgument("--GammaOnly",       "--GammaOnly=[0|1] (Def: 0)", 0);
$App->AddArgument("--nKPoint",         "--nKPoint=val (Def: 9)", 9);
$App->AddArgument("--aKProduct",       "--aKProduct=val (Def: 2.0)", 2.0);
$App->AddArgument("--KPoints",         "--KPoints=[File|GXYZRM] (Def: File)", 'File');
$App->AddArgument("--Precision",       "--Precision=[High|Normal|Medium|Low] (Def: Normal)", "Normal");
$App->AddArgument("--PStress",         "--PStress=val (Def: 0)", '');
$App->AddArgument("--KeepSymmetry",    "--KeepSymmetry=[0-4] (Def: 0)", "0");
$App->AddArgument("--A",               "--A=val (Def: )", '');
$App->AddArgument("--a",               "--a=val (Def: )", '');
$App->AddArgument("--b",               "--b=val (Def: )", '');
$App->AddArgument("--c",               "--c=val (Def: )", '');
$App->AddArgument("--alpha",           "--alpha=val (Def: )", '');
$App->AddArgument("--beta",            "--beta =val (Def: )", '');
$App->AddArgument("--gamma",           "--gamma=val (Def: )", '');
$App->AddArgument("--Param:.*",        "--Param:Param=val", "");
$App->AddArgument("--RWIGSDB",         "--RWIGSDB=FilePath", "");
$App->AddArgument("--DebugMode",       "--DebugMode: Set DebugMode", '');
exit 1 if($App->ReadArgs(1, "sjis", 0) != 1);
my $Args = $App->Args();
#my $form = new CGI;
#$Args->SetCGIForm($form);
#$Args->parseInput($WebCharCode);

my %ArgHash = $Args->GetArgHash();
foreach my $key (keys %ArgHash) {
#print "key: $key: $ArgHash{$key}\n";
	if($key =~ /^Param:(.*?)$/i) {
		$ParamHash{$1} = $ArgHash{$key};
#print "$1:  $ArgHash{$key}\n";
	}
}
$App->{pParamHash} = \%ParamHash;

#==========================================
# メイン関数スタート
#==========================================

#Utils::InitHTML("Research", $WebCharSet, "_self");

my $Debug = $Args->GetGetArg("DebugMode");
$App->SetDebug($Debug);
my $Action = $Args->GetGetArg("Action");

my $ret = 0;
if($Action =~ /MakeINCAR/i) {
	&MakeINCAR();
}
elsif($Action =~ /ModifyFiles/i) {
	&ModifyFiles();
}
elsif($Action =~ /ModifyPOSCAR/i) {
	&ModifyPOSCAR();
}
elsif($Action =~ /CheckRWIGS/i) {
	&CheckRWIGS();
}
elsif($Action =~ /MakeMergeEIGENVALSH/i) {
	&MakeMergeEIGENVALSH();
}
elsif($Action =~ /AddEIGENVAL/i) {
	&AddEIGENVAL();
}
elsif($Action =~ /RepairEIGENVAL/i) {
	&RepairEIGENVAL();
}
elsif($Action =~ /ChangeDensityFileNames/i) {
	&ChangeDensityFileNames();
}
elsif($Action =~ /MakeCIF/i) {
	&MakeCIFFile();
}
elsif($Action =~ /ConvCONTCAR/i) {
	&ConvCONTCARFiles();
}
elsif($Action =~ /MakeVESTAFile/i) {
	&MakeVESTAFile();
}
elsif($Action =~ /MakeXSFFile/i) {
	&MakeXSFFile();
}
elsif($Action =~ /MakeRelaxXSFFile/i) {
	&MakeRelaxXSFFile();
}
elsif($Action =~ /MakePhononXSFFile/i) {
	&MakePhononXSFFile();
}
elsif($Action =~ /CheckUnitCellVariation/i) {
	&CheckUnitCellVariation();
}
elsif($Action =~ /MakeDOSCSV/i) {
	&MakeDOSCSV();
}
elsif($Action =~ /RemoveAtom/i) {
	&RemoveAtom();
}
elsif($Action =~ /^ReadNBANDS$/i) {
	&ReadNBANDS();
}
elsif($Action =~ /^ChangeRWIGS/i) {
	&ChangeRWIGS();
}
else {
	$App->print("Error: Invalid Action: [$Action]\n");
}

#Utils::EndHTML();

exit $ret;

#===============================================
# スクリプト終了
#===============================================

#==========================================
# &Subroutines
#==========================================
sub ReadNBANDS
{
	$App->print(VASP->new()->ReadKeyValue("NBANDS\\s*=\\s*(\\S+)", 0, $Args->GetGetArg(0)) . "\n");
	$App->print(VASP->new()->ReadKeyValue("NELECT\\s*=\\s*(\\S+)", 0, $Args->GetGetArg(0)) . "\n");
	$App->print(VASP->new()->ReadKeyValue("NUPDOWN\\s*=\\s*(\\S+)", 0, $Args->GetGetArg(0)) . "\n");
}

sub RemoveAtom
{
	$App->print("\n\n<b>Remove atom from POSCAR:</b>\n");
	my $DirSep    = Deps::DirectorySeparator();
	my $RegDirSep = Utils::RegExpQuote($DirSep);
	my $Dir        = $Args->GetGetArg(0);
	my $POTCARPATH       = Deps::MakePath($Dir, "POTCAR", 0);
	my $POSCARPATH       = Deps::MakePath($Dir, "POSCAR", 0);
	my $POSCARBackupPATH = Deps::MakePath($Dir, "POSCAR.RemoveAtom.original", 0);
	my $RemoveAtom = $Args->GetGetArg("iRemoveAtom");
	my ($RemoveAtomName, $iRemoveAtom) = ($RemoveAtom =~ /^(\D+)(\d+)$/);
	if($RemoveAtomName eq '') {
		$App->print("Error in VASP.pl::RemoveAtom: Null RemoveAtomName [$RemoveAtomName]\n");
		exit;
	}
	$App->print("POTCAR: $POTCARPATH\n");

	my $VASP = new VASP;
	my @AtomTypes = $VASP->ReadAtomTypesFromPOTCAR($POTCARPATH, 1);
	my $iRemoveAtomType = -1;
	for(my $i = 0 ; $i < @AtomTypes ; $i++) {
		$App->print("$i: $AtomTypes[$i]\n");
		$iRemoveAtomType = $i if($AtomTypes[$i] =~ /$RemoveAtomName/i);
	}
	if($iRemoveAtomType < 0) {
		$App->print("Error: Can not find the AtomType [$RemoveAtomName] from POTCAR.\n");
		exit;
	}
	$App->print("RemoveAtom: $RemoveAtomName [#$iRemoveAtomType]: Remove #$iRemoveAtom $RemoveAtomName atom\n");
	
	if(Utils::CopyFile($POSCARPATH, $POSCARBackupPATH)) {
		$App->print("[$POSCARPATH] is backuped to [$POSCARBackupPATH].\n");
	}
	else {
		$App->print("Error: [$POSCARPATH] could not be copied to [$POSCARBackupPATH].\n");
		exit;
	}
	
	my $in  = new JFile($POSCARBackupPATH, "r") or die "$!: Can not read [$POSCARBackupPATH].\n";
	my $out = new JFile($POSCARPATH, "w") or die "$!: Can not read [$POSCARPATH].\n";
	for(my $i = 0 ; $i < 5 ; $i++) {
		my $line = $in->ReadLine();
		$out->print($line);
	}
	my $line = $in->ReadLine();
	my @nAtoms = Utils::Split("\\s+", $line);
	my @nAtomsOriginal = @nAtoms;
	$nAtoms[$iRemoveAtomType]--;
	for(my $i = 0 ; $i < @nAtoms ; $i++) {
		$out->printf(" %4d", $nAtoms[$i]);
	}
	$out->print("\n");
	for(my $i = 0 ; $i < 2 ; $i++) {
		my $line = $in->ReadLine();
		$out->print($line);
	}

	for(my $i = 0 ; $i < @nAtomsOriginal ; $i++) {
		for(my $j = 0 ; $j < $nAtomsOriginal[$i] ; $j++) {
			my $line = $in->ReadLine();
			if($i == $iRemoveAtomType and $j+1 == $iRemoveAtom) {
print "$i,$j: Skip\n";
			}
			else {
print "$i,$j: write\n";
				$out->print($line);
			}
		}
	}

	my $line = $in->ReadLine();
	$out->print($line);
	for(my $i = 0 ; $i < @nAtomsOriginal ; $i++) {
		for(my $j = 0 ; $j < $nAtomsOriginal[$i] ; $j++) {
			my $line = $in->ReadLine();
			if($i == $iRemoveAtomType and $j == $RemoveAtomName) {
			}
			else {
				$out->print($line);
			}
		}
	}

	while(!$in->eof()) {
		my $line = $in->ReadLine();
		last if(!defined $line);
		$out->print($line);
	}
	$in->Close();
	$out->Close();
	
	$App->print("[$POSCARPATH] has been updated.\n\n");
}

sub ChangeRWIGS
{
	$App->print("\n<b>Change RWIGS:</b>\n");

	my $VASP     = new VASP();
	my $CARDir   = $Args->GetGetArg(0);
	my $INCARNew = $Args->GetGetArg(1);
	my $INCAR    = $VASP->GetINCARFileName($CARDir);
	my $POTCAR   = $VASP->GetPOTCARFileName($CARDir);
	my $RWIGSDB  = $Args->GetGetArg("RWIGSDB");
	return if(!$RWIGSDB);

	my $pPOT   = $VASP->ReadPOTCARtoHash($POTCAR);
	my $pINCAR = $VASP->ReadINCARtoHash($INCAR);
	my $ini = new IniFile($RWIGSDB);

	my @RINCAR = Utils::Split("\\s+", $pINCAR->{RWIGS});
	my @R;
	for(my $i = 0 ;  ; $i++) {
		my $s = $pPOT->{"PseudoPotential$i"};
		last if(!$s);

		my ($pp, $atom, $date) = Utils::Split("\\s+", $s);
		$atom =~ s/_.*//;

		$R[$i] = $ini->GetString("RWIGS", $atom, "");
		if($R[$i]) {
			print "Use R=$R[$i] for $atom from [$RWIGSDB]\n";
		}
		else {
			$R[$i] = $RINCAR[$i];
			print "Use R=$R[$i] for $atom from [$INCAR]\n";
		}
	}

print "Write new RWIGS to [$INCARNew].\n";
	my $in  = JFile->new($INCAR, "r") or die "$!: Can not read [$INCAR].\n";
	my $out = JFile->new($INCARNew, "w") or die "$!: Can not write to [$INCARNew].\n";
	while(1) {
		my $line = $in->ReadLine();
		last if(!defined $line);

		my ($head, $comm, $sp, $key, $eq, $val) = ($line =~ /^(\s*?)(#?)(\s*)([a-zA-Z0-9]*)(\s*=\s*)(\S.*)$/);
#print "($comm) [$key] = [$val]\n" if($key);
		if($key eq 'RWIGS' and $comm eq '') {
#print "$comm $key = $val\n" if($key);
			$out->print("$head$comm$sp$key$eq");
print("$head$comm$sp$key$eq");
			for(my $i = 0 ; $i < @R ; $i++) {
				$out->print(" $R[$i]");
print(" $R[$i]");
			}
			$out->print("\n");
print("\n");
		}
		else {
			$out->print($line);
		}
	}
	$out->Close();
	$in->Close();

	$App->print("\n<b>Change RWIGS: fisnished</b>\n");
}


sub ChangeDensityFileNames
{
	$App->print("\n\n<b>Change names of density files:</b>\n");
	my $DirSep = Deps::DirectorySeparator();
	my $RegDirSep = Utils::RegExpQuote($DirSep);
#	my $OS = Deps::OS();
#	$App->print("  OS: $OS\n");
#	my $VASPDir = $ENV{'VASPDir'};
	my $EnergyRange = $Args->GetGetArg("EnergyRange");
	$App->print("  Energy range: $EnergyRange eV\n");
	my $RemoveExtention = $Args->GetGetArg("RemoveExtention");
	$App->print("  Remove .vasp extention: $RemoveExtention\n");
	my $Dir = $Args->GetGetArg(0);
	$Dir =~ s/$RegDirSep$//;
	$App->print("  Dir: $Dir\n");
	my ($ParentDir) = ($Dir =~ /^(.*)$RegDirSep.*?$/);
	$App->print("  Parent Dir: $ParentDir\n");
	
	my $SCFDir = Deps::MakePath($Dir, "SCF", 0);
	if(!-d $SCFDir) {
		$SCFDir = Deps::MakePath($Dir, "VCRelax", 0);
	}
	if(!-d $SCFDir) {
		$SCFDir = Deps::MakePath($Dir, "DOS", 0);
	}
	if(!-d $SCFDir) {
		$SCFDir = Deps::MakePath($ParentDir, "SCF", 0);
	}
	if(!-d $SCFDir) {
		$SCFDir = Deps::MakePath($ParentDir, "VCRelax", 0);
	}
	if(!-d $SCFDir) {
		$SCFDir = Deps::MakePath($ParentDir, "DOS", 0);
	}
	if(!-d $SCFDir) {
		$SCFDir = $ParentDir;
	}

	my $OUTCAR = Deps::MakePath($SCFDir, "OUTCAR", 0);
	$App->print("  SCF OUTCAR: $OUTCAR\n");
	
	$App->print("  Read [$OUTCAR]\n");
	my $in = new JFile($OUTCAR, "r");
	if(!$in) {
		$App->print("  Error!!: Can not read [$OUTCAR].\n");
		return -1;
	}
	my $line = $in->SkipTo("number of bands ");
	my ($nBands) = ($line =~ /NBANDS=\s*([\d]+)/);
	$App->print("  nBands: $nBands\n");
	$line = $in->SkipTo("number of ions ");
	my ($nIons) = ($line =~ /NIONS\s*=\s*([\d]+)/);
	$App->print("  nIons: $nIons\n");
	$line = $in->SkipTo("NELECT\\s+=\\s");
	my ($nElectrons) = ($line =~ /NELECT\s*=\s*([\d\.]+)/);
	$App->print("  nElectrons: $nElectrons\n");
	$in->rewind();
	$line = $in->SkipTo("ENCUT  = ");
	my ($ENCUT) = ($line =~ /ENCUT\s*=\s*([\d\.eEdD]+)/);
	$App->print("  Cutoff energy: $ENCUT eV\n");
	$line = $in->SkipTo("E-fermi : ");
	my ($EF) = ($line =~ /E-fermi :\s+([\d+-\.eEdD]+)/);
	$App->print("  Fermi energy: $EF eV\n");
	$in->Close();

	$App->print("\n");
	$App->print("  Read [$OUTCAR]\n");
	$in = new JFile($OUTCAR, "r");
	if(!$in) {
		$App->print("  Error!!: Can not read [$OUTCAR].\n");
		return -1;
	}
	$line = $in->SkipTo("E-fermi : ");
	$in->SkipTo("k-point ");
	$in->ReadLine();
	my $EHOMO;
	my $ELUMO;
	my $IsFoundHOMO = 0;
	my (@idx, @eng, @occ);
	my ($iHOMO, $iLUMO);
	for(my $i = 0 ; $i < $nBands ; $i++) {
		$line = $in->ReadLine();
		($idx[$i], $eng[$i], $occ[$i]) = Utils::Split("\\s+", $line);
		if($IsFoundHOMO == 0) {
			if($eng[$i] > $EF) {
				$ELUMO = $eng[$i];
				$iLUMO = $i+1;
				$IsFoundHOMO = 1;
			}
			else {
				$EHOMO = $eng[$i];
				$iHOMO = $i+1;
			}
		}
	}
	$App->print("  E(HOMO) : $EHOMO eV [$iHOMO]\n");
	$App->print("  E(Fermi): $EF eV\n");
	$App->print("  E(LUMO) : $ELUMO eV [$iLUMO]\n");
	my $emin = $EHOMO - $EnergyRange;
	my $emax = $ELUMO + $EnergyRange;
	my $imin = -1;
	my $imax = -1;
	$App->print("  Energy range: $emin - $emax eV\n");
	for(my $i = 0 ; $i < $nBands ; $i++) {
#print "$idx e=$e $emin\n";
		if($emin <= $eng[$i] and $eng[$i] <= $emax) {
			$App->print("  $idx[$i] $eng[$i] $occ[$i]\n");
			$imin = $idx[$i] if($imin < 0);
			$imax = $idx[$i];
		}
	}
	$App->print("  Band index range: $imin - $imax\n");
	$in->Close();

	if($RemoveExtention) {
		my $vasp = Deps::MakePath($Dir, "*.vasp", 0);
#print "mask: $vasp\n";
		my @files = glob($vasp);
#print "files: @files\n";
		foreach my $f (@files) {
			if(-f $f) {
				my $newf = $f;
				$newf =~ s/(\.HOMO|\.LUMO)?\.vasp$//i;
				if(rename($f, $newf)) {
					$App->print("  Change [$f] to [$newf].\n");
				}
				else {
					$App->print("  Could not change name from [$f] to [$newf].\n");
				}
			}
		}
	}

	$App->print("\n");
	my $CHGCAR = Deps::MakePath($Dir, "CHGCAR", 0);
	if(-f $CHGCAR) {
		my $NewCHGCAR = Deps::MakePath($Dir, "CHGCAR.vasp", 0);
		if(rename($CHGCAR, $NewCHGCAR)) {
			$App->print("  Change [$CHGCAR] to [$NewCHGCAR].\n");
		}
		else {
			$App->print("  Could not change name from [$CHGCAR] to [$NewCHGCAR].\n");
		}
	}

	for(my $i = $imin ; $i <= $imax ; $i++) {
		my $s = sprintf("%04d", $i);
		my $fmask = Deps::MakePath($Dir, "PARCHG.$s.*", 0);
#print "fmask: $fmask\n";
		my @files = glob($fmask);
#print "files: @files\n";
		foreach my $f (@files) {
#print "try $f\n";
			next if(!-f $f or $f =~ /\.vasp$/i);

			my $NewF = "$f.vasp";
			if($i == $iLUMO) {
				$NewF = "$f.LUMO.vasp";
			}
			if($i == $iHOMO) {
				$NewF = "$f.HOMO.vasp";
			}
			if(rename($f, $NewF)) {
				$App->print("  Change [$f] to [$NewF].\n");
			}
			else {
				$App->print("  Could not change name from [$f] to [$NewF].\n");
			}
		}
	}


	$App->print("\n\n<b>Change names of density files: Finished</b>\n");

}

sub MakeMergeEIGENVALSH
{
	$App->print("\n\n<b>Make MergeEIGENVAL.sh:</b>\n");
	my $OS = Deps::OS();
	$App->print("  OS: $OS\n");
	my $VASPDir = $ENV{'VASPDir'};
	if(!defined $VASPDir) {
		my $PerlDir = $ENV{'PerlDir'};
		if(defined $PerlDir) {
			$VASPDir = Deps::MakePath($PerlDir, 'VASP', 0);
		}
	}
	$VASPDir = '' unless(defined $VASPDir);
	$App->print("  VASPDir: $VASPDir\n");
	my $VASPPL = Deps::MakePath($VASPDir, "VASP.pl", 0);
	$App->print("  VASP.pl: $VASPPL\n");

	my $InputFile = $Args->GetGetArg(0);
	$App->print("  Input file : $InputFile\n");
	my $OutputFile = $Args->GetGetArg(1);
	if(Utils::IsWindows()) {
		$OutputFile = "MergeEIGENVAL.bat" unless(defined $OutputFile);
	}
	else {
		$OutputFile = "MergeEIGENVAL.sh" unless(defined $OutputFile);
	}
	$App->print("  Output file: $OutputFile\n");

	if(-e $OutputFile) {
		$App->print("  Delete [$OutputFile]\n");
		if(!unlink($OutputFile)) {
			$App->print("Error!: Can not delete [$OutputFile]\n\n");
			return -2;
		}
	}

	my $out = new JFile($OutputFile, "w");
	if(!$out) {
		$App->print("Error!: Can not write to [$OutputFile]\n\n");
		return -1;
	}

	if($OS eq 'MSWin32') {
		$out->print("set VASPDir=$VASPDir\n");
		$out->print("set VASPPL=$VASPPL\n");
		$out->print("del EIGENVAL\n");
	}
	else {
		$out->print("#!/usr/bin/perl\n");
		$out->print("VASPDir=$VASPDir\n");
		$out->print("VASPPL=$VASPPL\n");
		$out->print("rm EIGENVAL\n");
	}
	my @dirs = glob("Band*");
	for(my $i = 0 ; $i < @dirs ; $i++) {
		next if(!-d $dirs[$i]);
		my $path = Deps::MakePath($dirs[$i], "EIGENVAL", 0);
		next if(!-e $path);
		$App->print("  Dir$i: $dirs[$i]\n");
		if($OS eq 'MSWin32') {
			$out->print("perl.exe %VASPPL% --Action=AddEIGENVAL --InverseOrder=No $dirs[$i]\\EIGENVAL EIGENVAL\n");
		}
		else {
			$out->print("$(VASPPL) --Action=AddEIGENVAL --InverseOrder=No $dirs[$i]\\EIGENVAL EIGENVAL\n");
		}
	}
	if($OS eq 'MSWin32') {
		$out->print("perl.exe %VASPPL% --Action=RepairEIGENVAL EIGENVAL\n");
		$out->print("copy $dirs[0]\\INCAR .\n");
		$out->print("copy $dirs[0]\\KPOINTS .\n");
		$out->print("copy $dirs[0]\\POSCAR .\n");
		$out->print("copy $dirs[0]\\POTCAR .\n");
		$out->print("copy DOS\\OUTCAR .\n");
	}
	else {
		$out->print("$(VASPPL) --Action=RepairEIGENVAL EIGENVAL\n");
		$out->print("cp $dirs[0]/INCAR .\n");
		$out->print("cp $dirs[0]/KPOINTS .\n");
		$out->print("cp $dirs[0]/POSCAR .\n");
		$out->print("cp $dirs[0]/POTCAR .\n");
		$out->print("cp DOS/OUTCAR .\n");
	}

	$out->Close();

	$App->print("\n\n<b>Make MergeEIGENVAL.sh: Finished</b>\n");
}

sub AddEIGENVAL
{
	$App->print("\n\n<b>Add EIGENVAL:</b>\n");

	my $InputFile = $Args->GetGetArg(0);
	$App->print("  Input file: $InputFile\n");
	my $OutputFile = $Args->GetGetArg(1);
	$OutputFile = "EIGENVAL" unless(defined $OutputFile);
	$App->print("  Output file: $OutputFile\n");
	my $InverseOrder = $Args->GetGetArg('InverseOrder');
	$App->print("  Inverse Order: $InverseOrder\n");

	my $IsFirst = 1;
	$IsFirst = 0 if(-e $OutputFile);

	my $in = new JFile($InputFile, "r");
	if(!$in) {
		$App->print("Error!: Can not read [$InputFile]\n\n");
		return -1;
	}
	my $out = new JFile($OutputFile, "a");
	if(!$out) {
		$App->print("Error!: Can not write to [$OutputFile]\n\n");
		return -2;
	}

	my $line;
	for(my $i = 0 ; $i < 6 ; $i++) {
		$line = $in->ReadLine();
		if($IsFirst) {
			$out->print($line);
		}
	}

	my ($nn, $nK, $nLevels) = Utils::Split("\\s+", $line);
	$App->print("  nKPoints: $nK\n");
	$App->print("  nLvels  : $nLevels\n");
	my @Heading;
	my @LevelLines;
	my $count = 0;
	while(!$in->eof()) {
		$line = $in->ReadLine();
		chomp($line);
		next if($line =~ /^\s*$/);

#print "Head: $line\n";
		$Heading[$count] = "$line\n";
		$LevelLines[$count] = '';
		for(my $i = 0 ; $i < $nLevels ; $i++) {
			$line = $in->ReadLine();
#print "  $i: $line";
			$LevelLines[$count] .= $line;
		}
		$count++;
	}

#	for(my $i = 0 ; $i < 1 ; $i++) {
	for(my $i = 0 ; $i < $nK ; $i++) {
		my $c = $i;
		$c = $nK - $i - 1 if($InverseOrder == 1 or $InverseOrder =~ /y/i);
		$out->print("\n");
		$out->print($Heading[$c]);
		$out->print($LevelLines[$c]);
	}

	$in->Close();
	$out->Close();

	$App->print("\n\n<b>Add EIGENVAL: Finished</b>\n");
}

sub RepairEIGENVAL
{
	$App->print("\n\n<b>Repair EIGENVAL:</b>\n");

	my $InputFile = $Args->GetGetArg(0);
	$App->print("  Input file: $InputFile\n");

	my $in = new JFile($InputFile, "r");
	if(!$in) {
		$App->print("Error!: Can not read [$InputFile]\n\n");
		return -1;
	}

	my $line;
	my @header;
	for(my $i = 0 ; $i < 6 ; $i++) {
		$header[$i] = $in->ReadLine();
	}
	my ($nn, $nK, $nLevels) = Utils::Split("\\s+", $header[5]);
	$App->print("  nKPoints: $nK\n");
	$App->print("  nLvels  : $nLevels\n");
	my @Heading;
	my @LevelLines;
	my $count = 0;
	while(!$in->eof()) {
		$line = $in->ReadLine();
		chomp($line);
		next if($line =~ /^\s*$/);

#print "Head: $line\n";
		$Heading[$count] = "$line\n";
		$LevelLines[$count] = '';
		for(my $i = 0 ; $i < $nLevels ; $i++) {
			$line = $in->ReadLine();
#print "  $i: $line";
			$LevelLines[$count] .= $line;
		}
		$count++;
	}
	
	$in->Close();

	$nK = $count;
	$App->print("  nKPoints: $nK\n");

	my $out = new JFile($InputFile, "w");
	if(!$out) {
		$App->print("Error!: Can not write to [$InputFile]\n\n");
		return -1;
	}

	for(my $i = 0 ; $i < 5 ; $i++) {
		$out->print($header[$i]);
	}
	$out->print("  $nn  $nK  $nLevels\n");
	for(my $i = 0 ; $i < $nK ; $i++) {
		$out->print("\n");
		$out->print($Heading[$i]);
		$out->print($LevelLines[$i]);
	}

	$in->Close();

	$App->print("\n\n<b>Add KPOINT: Finished</b>\n");
}

sub CheckRWIGS
{
	$App->print("\n<b>Check RWIGS parameters in VASP INCAR file:</b>\n");

	my $VASP = new VASP();

	my $InputFile = $Args->GetGetArg(0);
	$App->print("  Input file: $InputFile\n");
	my $INCAR = $VASP->GetINCARFileName($InputFile);
	$App->print("  INCAR     : $INCAR\n");
#$App->print("VASP.pl::CheckRWIGS: Read [$INCAR].\n");
	my @RWIGS  = $VASP->RWIGSFromINCAR($INCAR);
	my $POSCAR = $VASP->GetPOSCARFileName($InputFile);
	$App->print("  POSCAR    : $POSCAR\n");
#$App->print("VASP.pl::CheckRWIGS: Read [$POSCAR].\n");
	my $Crystal = $VASP->ReadStructureFromCARFiles($POSCAR, 1);

	my @AtomTypeList = $Crystal->GetCAtomTypeList();
	my $nAtomType = @AtomTypeList;
	my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode();
	my $nTotalExpandedAtomSite = @ExpandedAtomSiteList;
	my @AtomNames;
	my %nAtoms;
	for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
		my $atomsite = $ExpandedAtomSiteList[$i];
		$AtomNames[$i] = $atomsite->AtomNameOnly();
		$nAtoms{$AtomNames[$i]}++;
	}

	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $atomtype = $AtomTypeList[$i];
		my $atomname = $atomtype->AtomNameOnly();
		$App->printf("%2s: %f A\n", $atomname, $RWIGS[$i]);
#		$App->print("RWIGS[$i] for $atomname: $RWIGS[$i] A\n");
	}

	my %NNDistances;
	for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
		my $atomsite0 = $ExpandedAtomSiteList[$i];
		my $atomname0 = $atomsite0->AtomNameOnly();
		my ($x0,$y0,$z0) = $atomsite0->Position(1);
		for(my $j = 0 ; $j < $nTotalExpandedAtomSite ; $j++) {
#		for(my $j = $i+1 ; $j < $nTotalExpandedAtomSite ; $j++) {
			my $atomsite1 = $ExpandedAtomSiteList[$j];
			my $atomname1 = $atomsite1->AtomNameOnly();
			my ($x1,$y1,$z1) = $atomsite1->Position(1);
#print "a: $atomname0 - $atomname1:\n";
			my $d = $Crystal->GetNearestInterAtomicDistance(
					$x0, $y0, $z0, $x1, $y1, $z1, 0);
#print "a: $atomname0 - $atomname1 d=$d\n";

			my $s = "$atomname0 - $atomname1";
			if(defined $NNDistances{$s}) {
				$NNDistances{$s} = $d if($NNDistances{$s} > $d);
			}
			else {
				$NNDistances{$s} = $d;
			}
#print "atoms[$i,$j]: $atomname0 - $atomname1: $d A: Min: $NNDistances{$s} A\n";
		}
	}

	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $atomtype0 = $AtomTypeList[$i];
		my $atomname0 = $atomtype0->AtomNameOnly();
		my $RWIG0 = $RWIGS[$i];
		for(my $j = $i ; $j < $nAtomType ; $j++) {
			my $atomtype1 = $AtomTypeList[$j];
			my $atomname1 = $atomtype1->AtomNameOnly();
			my $s = "$atomname0 - $atomname1";
			my $RWIG1 = $RWIGS[$j];
			my $RWIGSUM = $RWIG0 + $RWIG1;
$App->printf("Min d: %7s: %8.4f A (RWIGS: %8.4f = %8.4f + %8.4f)\n",
	$s, $NNDistances{$s}, $RWIG0+$RWIG1, $RWIG0, $RWIG1);
		}
	}

	$App->print("\n");
	my $Volume = $Crystal->Volume();
	$App->print("Unit cell volume: $Volume A^3\n");
	my $WIGSVolumeSum = 0.0;
	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $atomtype0 = $AtomTypeList[$i];
		my $atomname0 = $atomtype0->AtomNameOnly();
		my $RWIG0 = $RWIGS[$i];
		my $n = $nAtoms{$atomname0};
		my $v = 4.0/3.0 * Sci::pi() * $RWIG0*$RWIG0*$RWIG0;
		$WIGSVolumeSum += $v * $n;
$App->printf("%2s: %10.4f x %d = %10.4f A^3\n",
		$atomname0, $v, $n, $v*$n);
	}
	my $fcur = $WIGSVolumeSum / $Volume * 100.0;
	$App->printf("WIGS Volume sum: %10.4f A^3", $WIGSVolumeSum);
	$App->printf(" (%6.2f %% of the Unit cell)\n", $fcur);

$App->print("\n");	
	for(my $f = 80.0 ; $f <= 100.1 ; $f += 5.0) {
		my $k = ($f / $fcur)**(1.0/3.0);
		$App->printf("Recommened RWIGS for Vf = %6.2f %%\n", $f);

		my @RW2;
		for(my $i = 0 ; $i < $nAtomType ; $i++) {
			my $atomtype0 = $AtomTypeList[$i];
			my $atomname0 = $atomtype0->AtomNameOnly();
			$RW2[$i] = $RWIGS[$i] * $k;
$App->printf("  %2s: %f A\n", $atomname0, $RW2[$i]);
		}

if(0) {
		$WIGSVolumeSum = 0.0;
		for(my $i = 0 ; $i < $nAtomType ; $i++) {
			my $atomtype0 = $AtomTypeList[$i];
			my $atomname0 = $atomtype0->AtomNameOnly();
			my $RWIG0 = $RW2[$i];
			my $n = $nAtoms{$atomname0};
			my $v = 4.0/3.0 * Sci::pi() * $RWIG0*$RWIG0*$RWIG0;
			$WIGSVolumeSum += $v * $n;
$App->printf("  %2s: %f A\n", $atomname0, $RW2[$i]);
		}
		my $f2 = $WIGSVolumeSum / $Volume * 100.0;
		$App->printf("  WIGS Volume sum: %10.4f A^3", $WIGSVolumeSum);
		$App->printf(" (%6.2f %% of the Unit cell)\n", $f2);
}
	}

	$App->print("\n\n<b>Check RWIGS parameters in VASP INCAR file: Finished</b>\n");
}

sub MakeDOSCSVwithPROCAR
{
	$App->print("\n<b>Make DOS CSV file with PROCAR:</b>\n");

	my $VASP = new VASP();
	my $PROCARPath  = $Args->GetGetArg(0);
	my $OutputPath1 = $Args->GetGetArg(1);
	my $OutputPath2 = $Args->GetGetArg(2);
	$App->print("PROCAR        : $PROCARPath\n");
	$App->print("OutputPath(up): $OutputPath1\n");
	$App->print("OutputPath(dn): $OutputPath2\n");
	my $Width = $Args->GetGetArg("Width");
	$Width = 0 if(!defined $Width);
	$App->print("Width: $Width eV\n");
	my $IgnoreZero = $Args->GetGetArg("IgnoreZero");
	$IgnoreZero = 0 if(!defined $IgnoreZero);
	$App->print("$IgnoreZero: $IgnoreZero\n");

	my ($pAtomTypeList, $pExpandedAtomSiteList, $pOrbitals, $EF, $nData, $pTE, $pDOS) = $VASP->ReadDOSCARwithPROCAR($PROCARPath);
	if($nData == 0) {
		$App->print("Error in MakeDOSCSVwithPROCAR: Can not read [$PROCARPath]\n");
		return;
	}

	my $IsSpinPolarized = $VASP->IsSpinPolarized();
	$App->print("IsSpinPolarized: $IsSpinPolarized\n");
	my $pDataArray = $VASP->DataArray();

	my $nAtomType = @$pAtomTypeList;

	if($Width > 0) {
		$pDOS->{Total}        = Algorism::Convolution($pTE, $pDOS->{Total},        $Width, "Gaussian", $IgnoreZero);
		$pDOS->{Interstitial} = Algorism::Convolution($pTE, $pDOS->{Interstitial}, $Width, "Gaussian", $IgnoreZero);
		$pDOS->{NE}           = Algorism::Convolution($pTE, $pDOS->{NE},           $Width, "Gaussian", $IgnoreZero);
		for(my $it = 0 ; $it < $nAtomType ; $it++) {
			my $atom     = $pAtomTypeList->[$it];
			my $atomname = $atom->AtomNameOnly();
			$pDOS->{$atomname}{Total}    = Algorism::Convolution($pTE, $pDOS->{$atomname}{Total},$Width, "Gaussian", $IgnoreZero);
			for(my $j = 0 ; $j < @$pOrbitals ; $j++) {
				my $orb = $pOrbitals->[$j];
				$pDOS->{$atomname}{$orb} = Algorism::Convolution($pTE, $pDOS->{$atomname}{$orb}, $Width, "Gaussian", $IgnoreZero);
			}
		}
	}

print "MakeDOSCSVwithPROCAR: Write to [$OutputPath1].\n";
	my $csv = new JFile($OutputPath1, 'w');
	if(!$csv) {
		print "Error in MakeDOSCSVwithPROCAR:: $!: Can not write to [$OutputPath1].\n";
		return -2;
	}

	$csv->print("E(eV),Total,Interstitial,NE");
	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $atom     = $pAtomTypeList->[$i];
		my $atomname = $atom->AtomNameOnly();
		$csv->print(",$atomname(Total)");
		for(my $j = 0 ; $j < @$pOrbitals ; $j++) {
			my $orb = $pOrbitals->[$j];
			$csv->print(",$atomname($orb)");
		}
	}
	$csv->print("\n");
	
	for(my $i = 0 ; $i < $nData ; $i++) {
		my $E = $pTE->[$i] - $EF;
		$csv->print("$E,$pDOS->{Total}[$i],$pDOS->{Interstitial}[$i],$pDOS->{NE}[$i]");
		for(my $it = 0 ; $it < $nAtomType ; $it++) {
			my $atom     = $pAtomTypeList->[$it];
			my $atomname = $atom->AtomNameOnly();
			$csv->print(",$pDOS->{$atomname}{Total}[$i]");
			for(my $j = 0 ; $j < @$pOrbitals ; $j++) {
				my $orb = $pOrbitals->[$j];
				$csv->print(",$pDOS->{$atomname}{$orb}[$i]");
			}
		}
		$csv->print("\n");
	}

	$csv->Close();


}

sub MakeDOSCSV
{
	my $DOSCARPath  = $Args->GetGetArg(0);
	return &MakeDOSCSVwithPROCAR() if(uc Deps::ExtractFileBody($DOSCARPath) eq 'PROCAR');

	$App->print("\n<b>Make DOS CSV file from DOSCAR:</b>\n");

	my $VASP = new VASP();
	my $OutputPath1 = $Args->GetGetArg(1);
	my $OutputPath2 = $Args->GetGetArg(2);
	$App->print("DOS/PROCAR    : $DOSCARPath\n");
	$App->print("OutputPath(up): $OutputPath1\n");
	$App->print("OutputPath(dn): $OutputPath2\n");
	my $Width = $Args->GetGetArg("Width");
	$Width = 0 if(!defined $Width);
	$App->print("Width: $Width eV\n");
	my $IgnoreZero = $Args->GetGetArg("IgnoreZero");
	$IgnoreZero = 0 if(!defined $IgnoreZero);
	$App->print("$IgnoreZero: $IgnoreZero\n");

	if(!$VASP->ReadDOSCAR($DOSCARPath)) {
		$App->print("Error in MakeDOSCSV: Can not read [$DOSCARPath]\n");
		return;
	}
	my $IsSpinPolarized = $VASP->IsSpinPolarized();
	$App->print("IsSpinPolarized: $IsSpinPolarized\n");
	my $pDataArray = $VASP->DataArray();

	my $out1 = new JFile($OutputPath1, "w");
	if(!$OutputPath1 or !$out1) {
		$App->print("Error in MakeDOSCSV: Can not write to [$OutputPath1]\n");
		return;
	}
	my $out2;
	if($IsSpinPolarized) {
		$out2 = new JFile($OutputPath2, "w");
		if(!$OutputPath2 or !$out2) {
			$App->print("Error in MakeDOSCSV: Can not write to [$OutputPath2]\n");
			return;
		}
	}
	my $Data0  = $pDataArray->GetGraphData(0);
	my $Data1  = $pDataArray->GetGraphData(1);
	my $Data2  = $pDataArray->GetGraphData(2);
	my $Data3  = $pDataArray->GetGraphData(3);
	if($Data2) {
		$Data1  = $Data2;
	}
	return unless($Data1);

	my $nData = $Data0->nData();
	my $title = $Data0->Title();
	my $pX0 = $Data0->GetDataArray("x0");
	last if(not defined $pX0);
	my $nData = @$pX0;
print "nData (up): $nData\n";
	my $xlabel = $Data0->{"x0_Name"};
	$out1->print("$xlabel");
	for(my $id = 0 ; ; $id++) {
		my $pY0 = $Data0->GetDataArray("y$id");
		last if(not defined $pY0);
		my $label0 = $Data0->{"y${id}_Name"};
		$out1->print(",$label0");
		if($Width > 0) {
			$Data0->{"y$id"} = Algorism::Convolution($pX0, $pY0, $Width, "Gaussian", $IgnoreZero);
		}
	}
	$out1->print("\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");
	}

	if($IsSpinPolarized) {
		$out2->print("$xlabel");
		for(my $id = 0 ; ; $id++) {
			my $pY0 = $Data1->GetDataArray("y$id");
			last if(not defined $pY0);
			my $label0 = $Data1->{"y${id}_Name"};
			$out2->print(",$label0");
			if($Width > 0) {
				$Data1->{"y$id"} = Algorism::Convolution($pX0, $pY0, $Width, "Gaussian", $IgnoreZero);
			}
		}
		$out2->print("\n");
		my $nData = @$pX0;
print "nData (dn): $nData\n";
		for(my $i = 0 ; $i < $nData ; $i++) {
			my $x = $pX0->[$i];
			$out2->print("$x");
			for(my $id = 0 ; ; $id++) {
				my $pY0 = $Data1->GetDataArray("y$id");
				last if(!defined $pY0);
				my $y = $pY0->[$i];
				$out2->print(",$y");
			}
			$out2->print("\n");
		}
	}

	$out1->Close();
	$out2->Close() if($out2);
	$App->print("\n<b>Make DOS CSV file from DOSCAR: Finished</b>\n");
}

sub ModifyPOSCAR
{
	$App->print("\n<b>Modify VASP POSCAR:</b>\n");

	my $VASP = new VASP();
	my $InputFile = $Args->GetGetArg(0);
	$App->print("Input: $InputFile\n");
	my $POSCAR  = $VASP->GetPOSCARFileName($InputFile);
	$App->print("  POSCAR : $POSCAR\n");
	my $A     = $Args->GetGetArg("A");
	$App->print("  A = $A\n");
	my $a     = $Args->GetGetArg("a");
	my $b     = $Args->GetGetArg("b");
	my $c     = $Args->GetGetArg("c");
	my $alpha = $Args->GetGetArg("alpha");
	my $beta  = $Args->GetGetArg("beta");
	my $gamma = $Args->GetGetArg("gamma");
	$App->print("  a,b,c,alpha,beta,gamma = $a, $b, $c, $alpha, $beta, $gamma\n");
#Command="$CMD --Action=ModifyPOSCAR --Positions=16:x:0.$x;16:y:0.$y POSCAR"
	my $Positions = $Args->GetGetArg("Positions");
#	$App->print("  Positions=$Positions\n");

	$VASP->ModifyPOSCARFile($POSCAR, $A, $a, $b, $c, $alpha, $beta, $gamma,
			Positions => $Positions, \%ArgHash);

	$App->print("\n<b>Modify VASP POSCAR: Finished</b>\n");
}

sub ModifyFiles
{
	$App->print("\n<b>Modify VASP *CAR Files:</b>\n");

	my $InputFile = $Args->GetGetArg(0);
print "Input File: $InputFile\n";
	if($InputFile eq '') {
		print "Error: Input file [$InputFile] does not exist.\n";
		exit;
	}

	my $Function    = $Args->GetGetArg("Function");
	$Function = 'scf' if($Function eq '');
	$App->print("  Target Function  : $Function\n");
	my $FromScratch = $Args->GetGetArg("FromScratch");
	if(!defined $FromScratch or $FromScratch eq '') {
		if(lc $Function eq 'scf') {
			$FromScratch = 1;
		}
		else {
			$FromScratch = 0;
		}
	}
	$App->print("  FromScratch      : $FromScratch\n");

	my $HybridFunctional = $Args->GetGetArg("HybridFunctional");
	$App->print("  HybridFunctional : $HybridFunctional\n");

	my $Precision = $Args->GetGetArg("Precision");
	$Precision = "Accurate" if($Precision =~ /^A/i);
	$Precision = "High"     if($Precision =~ /^H/i);
	$Precision = "Normal"   if($Precision =~ /^N/i);
	$Precision = "Medium"   if($Precision =~ /^M/i);
	$Precision = "Low"      if($Precision =~ /^L/i);
	$Precision = "Normal"   if($Precision eq '');
	$App->print("  Precision: $Precision\n");

	my $PrecFock = $Args->GetGetArg("Param:PRECFOCK");
	$App->print("  PrecFock : $PrecFock\n");

	my $KeepSymmetry = $Args->GetGetArg("KeepSymmetry");
	$App->print("  KeepSymmetry: $KeepSymmetry\n");

	my $aKProduct = $Args->GetGetArg("aKProduct");
	$aKProduct = 2.0 if($aKProduct eq '');
	$App->print("  a*K to determine K points: $aKProduct\n");

	my $SpinPolarized = $Args->GetGetArg("SpinPolarized");
	if($SpinPolarized ne '' and $SpinPolarized >= 2 or $SpinPolarized =~ /yes/i) {
		$SpinPolarized = 'Yes';
	}
	elsif($SpinPolarized ne '' and $SpinPolarized <= 1 or $SpinPolarized =~ /no/i) {
		$SpinPolarized = 'No';
	}
	$App->print("  SpinPolarized: $SpinPolarized\n");

	my $PStress = $Args->GetGetArg("PStress");
	$App->print("  PStress: $PStress\n");

	my $AllSeparated = $Args->GetGetArg("--AllSeparated");
	$AllSeparated = 1 if(!defined $AllSeparated);
	my $DOSMeasuredFromEF = $Args->GetGetArg("--DOSMeasreudFromEF");
	my $MinEnergy    = $Args->GetGetArg("--MinEnergy");
#	$MinEnergy = -5.0 if(!defined $MinEnergy);
	my $MaxEnergy    = $Args->GetGetArg("--MaxEnergy");
#	$MaxEnergy =  5.0 if(!defined $MaxEnergy);
	my $nMesh        = $Args->GetGetArg("--nMesh");
	if($Function =~ /eDensity/i) {
		$App->print("  AllSeparated: $AllSeparated\n");
		$App->print("  Energy range: $MinEnergy - $MaxEnergy eV from EF\n");
	}
	if($Function =~ /DOS/i) {
		$App->print("  Energy range: $MinEnergy - $MaxEnergy eV from EF, nMesh=$nMesh\n");
		$App->print("     measured from EF: $DOSMeasuredFromEF\n");
	}
	my $UseGammaOnly = $Args->GetGetArg("GammaOnly");
	$App->print("  GammaOnly: $UseGammaOnly\n");
	my $nKPointDiv = $Args->GetGetArg("nKPoint");
	$App->print("  nKPoint  : $nKPointDiv\n");
	my $KPoints = $Args->GetGetArg("KPoints");
	$App->print("  KPoints  : $KPoints\n");
	my $NBANDS = $Args->GetGetArg("NBANDS");
	$App->print("  NBANDS   : $NBANDS\n");
	my $NELECT = $Args->GetGetArg("NELECT");
	$App->print("  NELECT   : $NELECT\n");
	my $InitializeVelocity = $Args->GetGetArg("InitializeVelocity");
	$InitializeVelocity = 1 if(!defined $InitializeVelocity);
	$App->print("  InitializeVelocity: $InitializeVelocity\n");

	my $pParamHash = $App->{pParamHash};
	foreach my $key (keys %$pParamHash) {
#print "key: $key\n";
		$App->print("  Param:$key: $pParamHash->{$key}\n");
	}

	my ($drive, $dir, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($InputFile);
	my $VASP = new VASP();
	my $INCAR   = $VASP->GetINCARFileName($InputFile);
#print "In: $INCAR\n";
	my $POSCAR  = $VASP->GetPOSCARFileName($InputFile);
	my $POTCAR  = $VASP->GetPOTCARFileName($InputFile);
	my $KPOINTS = $VASP->GetKPOINTSFileName($InputFile);
	$App->print("  INCAR  : $INCAR\n");
	$App->print("  POSCAR : $POSCAR\n");
	$App->print("  POTCAR : $POTCAR\n");
	$App->print("  KPOINTS: $KPOINTS\n");

	if(Utils::CopyFile($INCAR, "${INCAR}.prev")) {
		$App->print("[$INCAR] was backuped to [${INCAR}.prev].\n");
	}
	else {
		$App->print("[$INCAR] could not be copied to [${INCAR}.prev].\n");
	}
	if(Utils::CopyFile($KPOINTS, "${KPOINTS}.prev")) {
		$App->print("[$KPOINTS] was backuped to [${KPOINTS}.prev].\n");
	}
	else {
		$App->print("[$KPOINTS] could not be copied to [${KPOINTS}.prev].\n");
	}
	if(Utils::CopyFile($POSCAR, "${POSCAR}.prev")) {
		$App->print("[$POSCAR] was backuped to [${POSCAR}.prev].\n");
	}
	else {
		$App->print("[$POSCAR] could not be copied to [${POSCAR}.prev].\n");
	}

	my $klistmask = $VASP->GetFileName($InputFile, "*.KPOINTS");
	my @klists = glob($klistmask);
	my $klist = (@klists > 0)? $klists[0] : '';
	if($klist eq '') {
		$klistmask = $VASP->GetFileName($InputFile, "*.klist");
		@klists = glob($klistmask);
		$klist = $klists[0];
	}
	if($klist) {
		$App->print("  klist: $klist\n");
	}
	else {
		$App->print("  klist file is not found. Use default.\n");
	}

	$ArgHash{aKProduct} = $aKProduct if(!defined $ArgHash{aKProduct});
	$VASP->ModifyINCARFile($Function, $INCAR, "${INCAR}.$Function", 
							$AllSeparated, $MinEnergy, $MaxEnergy, $DOSMeasuredFromEF,
							$FromScratch, $Precision, $KeepSymmetry, $nMesh, 
							$SpinPolarized, $PStress, $pParamHash, $NBANDS, $NELECT, \%ArgHash);
	$VASP->MakeKPOINTSFileFromKLIST($Function, "${KPOINTS}.$Function", 
							$klist, $UseGammaOnly, $nKPointDiv, $KPoints, $aKProduct, \%ArgHash);
	$VASP->ModifyPOSCARFile2($Function, $POSCAR, "${POSCAR}.$Function",
							InitializeVelocity => $InitializeVelocity);

	if(Utils::CopyFile("${INCAR}.$Function", $INCAR)) {
		$App->print("[${INCAR}.$Function] was copied to [$INCAR].\n");
	}
	else {
		$App->print("[${INCAR}.$Function] could not be copied to [$INCAR].\n");
	}
	if(Utils::CopyFile("${KPOINTS}.$Function", $KPOINTS)) {
		$App->print("[${KPOINTS}.$Function] was copied to [$KPOINTS].\n");
	}
	else {
		$App->print("[${KPOINTS}.$Function] could not be copied to [$KPOINTS].\n");
	}
	if(Utils::CopyFile("${POSCAR}.$Function", $POSCAR)) {
		$App->print("[${POSCAR}.$Function] was copied to [$POSCAR].\n");
	}
	else {
		$App->print("[${KPOINTS}.$Function] could not be copied to [$KPOINTS].\n");
	}

	$App->print("\n<b>Modify VASP *CAR Files: Finished</b>\n");
}

sub MakeINCAR
{
	$App->print("\n<b>Make VASP *CAR Files from CIF File:</b>\n");

	my $UseConventionalCell = $Args->GetGetArg("UseConventionalCell");
	if($UseConventionalCell eq '' or $UseConventionalCell eq 'No') {
		$UseConventionalCell = 'No';
	}
	else {
		$UseConventionalCell = 'Yes';
	}
	print "UseConventionalCell: $UseConventionalCell\n";
	my $Function         = $Args->GetGetArg("Function");
	my $Functional       = $Args->GetGetArg("Functional");
	my $UseDPP           = $Args->GetGetArg("UseDPP");
	my $HybridFunctional = $Args->GetGetArg("HybridFunctional");
	my $SpinPolarized    = $Args->GetGetArg("SpinPolarized");
	if($SpinPolarized and $SpinPolarized ne 'No') {
		$SpinPolarized = 'Yes';
	}
	else {
		$SpinPolarized = 'No';
	}
	my $CIFFile = $Args->GetGetArg(0);
	if($CIFFile eq 'auto') {
		my @files = glob("*.cif");
		@files = glob("*.CIF") if(@files == 0);
		for(my $i = 0 ; $i < @files ; $i++) {
			next if($files[$i] =~ /-initial\.cif$/i or $files[$i] =~ /-final\.cif$/i);
			$CIFFile = $files[$i];
			last;
		}
		if($CIFFile eq 'auto') {
			for(my $i = 0 ; $i < @files ; $i++) {
				if($files[$i] =~ /-final\.cif$/i) {
					$CIFFile = $files[$i];
					last;
				}
			}
		}
		if($CIFFile eq 'auto') {
			$CIFFile = $files[0];
		}
	}

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $WriteDir = $Args->GetGetArg(1);
	unless($WriteDir) {
		$App->print("File / Directory names should be specified.\n");
		$App->print("   Usage: VASP.pl --Action=MakeINCAR CIFFile CAR_Dir\n");
		return 0;
	}

	$App->print("  Function         : $Function\n");
	$App->print("  Functional       : $Functional\n");
	$App->print("  UseDPP           : $UseDPP\n");
	$App->print("  Hybrid Functional: $HybridFunctional\n");
	$App->print("  SpinPolarized    : $SpinPolarized\n");
	$App->print("  Read $CIFFile.\n");
	$App->print("  Save files in $WriteDir.\n");

	my ($drive, $dir, $filename, $ext, $lastdir, $filebody)
		= Deps::SplitFilePath($CIFFile);

	my $CIF = new CIF();
	unless($CIF->Read($CIFFile)) {
		$App->print("  Error: Can not read [$CIFFile].\n\n");
		return -1;
	}
	my $Crystal = $CIF->GetCCrystal();
	$Crystal->ExpandCoordinates();
	$Crystal->SetOutputMode('expanded');

#Primitive Cellをつくる
	my $SPG     = $Crystal->GetCSpaceGroup();
	my $SPGName = $SPG->SPGName();
	my ($CellType) = ($SPGName =~ /^\s*(.)/);
#print "UCC: $UseConventionalCell [SPG $SPGName]\n";
	if($UseConventionalCell ne 'Yes' and $SPGName =~ /^\s*[FIABC]/i) {
		my $PrimCIFFile = Deps::MakePath($WriteDir, "${filenames[0]}-Primitive.cif");
		print "<H2>Convert to Primitive Cell.</H2>\n";
		print "  CIF File: $PrimCIFFile$LF";

		print "  SpaceGroup: $SPGName$LF";
		
		my $T = new Math::MatrixReal(3, 3);
		if($SPGName =~ /^\s*F/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [ 0.5, 0.5,   0], 
				  [ 0,   0.5, 0.5],
				  [ 0.5,   0, 0.5] ] );
			$T->transpose($T);
		}
		elsif($SPGName =~ /^\s*I/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [-0.5, 0.5, 0.5], 
				  [ 0.5,-0.5, 0.5],
				  [ 0.5, 0.5,-0.5] ] );
			$T->transpose($T);
		}
		elsif($SPGName =~ /^\s*A/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [ 1.0, 0.0, 0.0], 
				  [ 0.0, 0.5, 0.5],
				  [ 0.0,-0.5, 0.5] ] );
			$T->transpose($T);
		}
		elsif($SPGName =~ /^\s*B/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [ 0.5, 0.0, 0.5], 
				  [ 0.0, 1.0, 0.0],
				  [-0.5, 0.0, 0.5] ] );
			$T->transpose($T);
		}
		elsif($SPGName =~ /^\s*C/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [ 0.5, 0.5, 0.0], 
				  [-0.5, 0.5, 0.0],
				  [ 0.0, 0.0, 1.0] ] );
			$T->transpose($T);
		}

#実空間べクトル(ai)の変換行列
		print "Conversion matrix for real space vector: (<b>a'<sub>i</sub></b>) = "
			."(T<sub>ij</sub>)(<b>a<sub>i</sub></b>)$LF";
		print "<pre>\n";
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
			$T->element(1,1), $T->element(1,2), $T->element(1,3);
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
			$T->element(2,1), $T->element(2,2), $T->element(2,3);
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
			$T->element(3,1), $T->element(3,2), $T->element(3,3);
		print "</pre>\n";

		my ($a, $b, $c, $alpha, $beta, $gamma) = $Crystal->LatticeParameters();
		my $PrimCrystal = $Crystal->ConvertLattice($T, 0, 1);
#		$PrimCrystal->{ConventionalSPGName}           = $SPGName;
#		$PrimCrystal->{ConventionalLatticeParameters} = [$a, $b, $c, $alpha, $beta, $gamma];
		my $PrimCIF = new CIF;
		$PrimCIF->CreateCIFFileFromCCrystal($PrimCrystal, $PrimCIFFile, 0, "unix");

		$Crystal = $PrimCrystal;
		$CellType = "$CellType-Primitive";

		print "$LF";
	}
	else {
		print "<H2>Use Convensinal cell</H2>\n";
	}

	print "<H2>Make VASP files.</H2>\n";
	print "  Cell type: $CellType$LF";
	my $VASP = new VASP();
	$VASP->SetSampleName($filebody);
	unless($VASP->SaveVASPFiles($Crystal, $CellType, $UseConventionalCell, 
				$Function, $Functional, 
				$UseDPP, $SpinPolarized, $WriteDir, 0, \%ArgHash) ) {
		$App->print("  Error: Can not write to [$WriteDir].\n\n");
		return -1;
	}

	$App->print("\n<b>Make VASP *CAR Files from CIF File: Finished</b>\n");
}

sub MakeVESTAFile
{
	$App->print("\n\n<b>Make VESTA File from VASP *CAR Files:</b>\n");

	my $VASP = new VASP;

	my $CARDir    = $Args->GetGetArg(0);
	my $VESTAFile = $Args->GetGetArg(1);
	$VESTAFile = $VASP->GetFileNameFromSystemName($CARDir, ".vest") if(!defined $VESTAFile);
	unless($VESTAFile) {
		$App->print("File names should be specified.\n");
		$App->print("   Usage: VASP.pl --Action=MakeVESTAFile CAR_Dir VESTAFile\n");
		return 0;
	}
	my $kMagnetization = $Args->GetGetArg('kMagnetization');
	$kMagnetization = 1.0 if(!defined $kMagnetization);
	$App->print("kMagnetization: $kMagnetization\n");
	my $ArrowColor = $Args->GetGetArg('ArrowColor');
	$ArrowColor = "128:128:128" if(!defined $ArrowColor);
	$App->print("ArrowColor: $ArrowColor\n");
	my $ArrowRadius = $Args->GetGetArg('ArrowRadius');
	$ArrowRadius = 0.2 if(!defined $ArrowRadius);
	$App->print("ArrowRadius: $ArrowRadius\n");
	my $PenetrateAtoms = $Args->GetGetArg('PenetrateAtoms');
	$PenetrateAtoms = 1 if(!defined $PenetrateAtoms);
	$App->print("PenetrateAtoms: $PenetrateAtoms\n");

	$App->print("  Read from [$CARDir].\n");
	$App->print("  Save to $VESTAFile.\n");

	my $Crystal = $VASP->ReadStructureFromCARFiles($CARDir);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir].\n");
		return 0;
	}

	my $OUTCar = $VASP->GetOUTCARFileName($CARDir);
#print "OUTCar: $OUTCar\n";
	my $pHash = $VASP->ReadOUTCARtoHash($OUTCar);
#print "TotalMagnetizationLine: $pHash->{TotalMagnetizationLine}\n";
	if($pHash and $pHash->{pMagnetizationLines}) {
		my $pM = $pHash->{pMagnetizationLines};

		my @AtomSiteList = $Crystal->GetCExpandedAtomSiteList();
		for(my $i = 0 ; $i < @AtomSiteList ; $i++) {
			my $site = $Crystal->GetCExpandedAtomSite($i);
			next if(!$site);
			my $atomname = $site->AtomName();
#print "$i: $atomname\n";

			my $line = $pM->[$i];
			next if(!$line);

			my ($iIon, $s, $p, $d, $tot) = Utils::Split("\\s+", $line);
			$site->SetVelocity(0, 0, $tot);
$App->print("mag[$i]: ", $tot * $kMagnetization, "\n");
		}
	}

	my $VESTA = new VESTA;
	$VESTA->WriteVESTAFileFromCrystal($Crystal, undef, $VESTAFile,
					undef, 0, 0, undef, undef, undef,
					kVector        => $kMagnetization,
					ArrowColor     => $ArrowColor,
					ArrowRadius    => $ArrowRadius,
					PenetrateAtoms => $PenetrateAtoms,
					);

	$App->print("\nMake VESTA File from VASP *CAR Files: Finished\n");

	return 1;
}

sub MakeXSFFile
{
	$App->print("\n\n<b>Make XSF File from VASP *CAR Files:</b>\n");

	my $VASP = new VASP;

	my $CARDir  = $Args->GetGetArg(0);
	my $XSFFile = $Args->GetGetArg(1);
	$XSFFile = $VASP->GetFileNameFromSystemName($CARDir, ".xsf") if(!defined $XSFFile);
	unless($XSFFile) {
		$App->print("File names should be specified.\n");
		$App->print("   Usage: VASP.pl --Action=MakeXSFFile CAR_Dir XSFFile\n");
		return 0;
	}

	$App->print("  Read from [$CARDir].\n");
	$App->print("  Save to [$XSFFile].\n");

	my $Crystal = $VASP->ReadStructureFromCARFiles($CARDir);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir].\n");
		return 0;
	}

	my $OUTCar = $VASP->GetOUTCARFileName($CARDir);
	my $pHash  = $VASP->ReadOUTCARtoHash($OUTCar);
	if($pHash and $pHash->{pMagnetizationLines}) {
		my $pM = $pHash->{pMagnetizationLines};

		my @AtomSiteList = $Crystal->GetCExpandedAtomSiteList();
		for(my $i = 0 ; $i < @AtomSiteList ; $i++) {
			my $site = $Crystal->GetCExpandedAtomSite($i);
			next if(!$site);
			my $atomname = $site->AtomName();

			my $line = $pM->[$i];
			next if(!$line);

			my ($iIon, $s, $p, $d, $tot) = Utils::Split("\\s+", $line);
			$site->SetVelocity(0, 0, $tot);
#			$site->SetForce(0, 0, $tot);
$App->print("mag[$i]: $tot\n");
		}
	}

	unlink($XSFFile);
	my $xc = new XCrySDen;
	$xc->WriteXSFFileHeader($XSFFile);
	$xc->WriteXSFFileFromCrystal($XSFFile, '', $Crystal);

	$App->print("\nMake XSF File from VASP *CAR Files: Finished\n");

	return 1;
}

sub MakePhononXSFFile
{
	$App->print("\n\n<b>Make Phonon XSF File from VASP *CAR Files:</b>\n");

	my $VASP = new VASP;

	my $CARDir  = $Args->GetGetArg(0);
	my $XSFFile = $Args->GetGetArg(1);
	$XSFFile = $VASP->GetFileNameFromSystemName($CARDir, ".xsf") if(!defined $XSFFile);
	unless($XSFFile) {
		$App->print("File names should be specified.\n");
		$App->print("   Usage: VASP.pl --Action=MakeXSFFile CAR_Dir XSFFile\n");
		return 0;
	}

	$App->print("  Read from [$CARDir].\n");
	$App->print("  Save to $XSFFile.\n");

	my $Crystal = $VASP->ReadStructureFromCARFiles($CARDir);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir].\n");
		return 0;
	}

	my $OUTCar = $VASP->GetOUTCARFileName($CARDir);
	my $pHash  = $VASP->ReadOUTCARtoHash($OUTCar);
	if(!$pHash or $pHash->{nPhononMode} == 0) {
		$App->print("Error: Phonon data is not found in [$OUTCar].\n");
		return 0;
	}

	my $nPhonon = $pHash->{nPhononMode};
$App->print("nPhonon: $nPhonon\n");
	my $pM      = $pHash->{pPhononModeLines};
$App->print("nPhononLines: ", scalar @$pM, "\n");
	my @AtomSiteList = $Crystal->GetCExpandedAtomSiteList();
	my $nAtomSite    = @AtomSiteList;
	unlink($XSFFile);
	my $xc = new XCrySDen;
	$xc->WriteXSFAnimationFileHeader($XSFFile, $nPhonon);
	my $iline = 0;
	for(my $ip = 0 ; $ip < $nPhonon ; $ip++) {
		my $line = $pM->[$iline++];
		$iline++;
		my ($THz) = ($line =~ /=\s*([\d\+\-\.eE]+)/);

		for(my $i = 0 ; $i < $nAtomSite ; $i++) {
			my $site = $Crystal->GetCExpandedAtomSite($i);
			next if(!$site);
			my $atomname = $site->AtomName();

			my $line = $pM->[$iline++];
			last if(!$line);

			my ($x, $y, $z, $dx, $dy, $dz) = Utils::Split("\\s+", $line);
			$site->SetVelocity($dx, $dy, $dz);
#			$site->SetForce(0, 0, $tot);
$App->print("Mode[$ip] Ion[$i]: f=$THz THz dr=($dx, $dy, $dz)\n");
		}
		$xc->WriteXSFFileFromCrystal($XSFFile, $ip+1, $Crystal);
	}

	$App->print("\nMake Phonon XSF File from VASP *CAR Files: Finished\n");

	return 1;
}

sub CheckUnitCellVariation
{
	$App->print("\n\n<b>Make Lattice parameters - step File from VASP *CAR Files:</b>\n");

	my $VASP = new VASP;

	my $outfile = "Vstep.csv";
	my $CARDir  = $Args->GetGetArg(0);
	my $OUTCar  = $VASP->GetOUTCARFileName($CARDir);

	unlink($outfile);
	$App->print("  Read from [$CARDir].\n");
	$App->print("  Read from [$OUTCar].\n");
	$App->print("  Save to [$outfile].\n");

	my $Crystal = $VASP->ReadStructureFromCARFiles($CARDir);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir].\n");
		return 0;
	}

	my @Crystals = $VASP->ReadStructuresFromOUTCAR($OUTCar, 0);
	if(@Crystals == 0) {
		$App->print("Error: Structure relax data is not found in [$OUTCar].\n");
		return 0;
	}

	my $nCrystal = @Crystals;
$App->print("nCrystal: $nCrystal\n");
#	my @AtomSiteList = $Crystals[0]->GetCExpandedAtomSiteList();
#	my $nAtomSite    = @AtomSiteList;

	my $out = JFile->new($outfile, "w");
	if(!$out) {
		$App->print("Error: Can not write to [$outfile].\n");
		return 0;
	}
	$out->print("step,T(K),a(nm),b(nm),c(nm),alpha,beta,gamma,V(nm^2)\n");
	for(my $i = 0 ; $i < @Crystals ; $i++) {
		my $crystal = $Crystals[$i];
		if(!$crystal) {
			$App->print("Error for step $i: Can not get Crystal Object\n");
			next;
		}

		my ($a, $b, $c, $alpha, $beta, $gamma) = $crystal->LatticeParameters();
		my $V = $crystal->Volume();
		my $T = $crystal->Temperature();
		$out->print("$i,$T,$a,$b,$c,$alpha,$beta,$gamma,$V\n");
	}
	$out->Close();

	$App->print("\n<b>Make Lattice parameters - step File from VASP *CAR Files: finished</b>\n");

	return 1;
}

sub MakeRelaxXSFFile
{
	$App->print("\n\n<b>Make Relax XSF File from VASP *CAR Files:</b>\n");

	my $VASP = new VASP;

	my $CARDir  = $Args->GetGetArg(0);
	my $XSFFile = $Args->GetGetArg(1);
	$XSFFile = $VASP->GetFileNameFromSystemName($CARDir, ".xsf") if(!defined $XSFFile);
	unless($XSFFile) {
		$App->print("File names should be specified.\n");
		$App->print("   Usage: VASP.pl --Action=MakeXSFFile CAR_Dir XSFFile\n");
		return 0;
	}

	$App->print("  Read from [$CARDir].\n");
	$App->print("  Save to $XSFFile.\n");

	my $OUTCar = $VASP->GetOUTCARFileName($CARDir);
	$App->print("  Read from [$OUTCar].\n");
	my @Crystals = $VASP->ReadStructuresFromOUTCAR($OUTCar, 0);
	if(@Crystals == 0) {
		$App->print("Error: Structure relax data is not found in [$OUTCar].\n");
		return 0;
	}

	my $nCrystal = @Crystals;
$App->print("nCrystal: $nCrystal\n");
	my @AtomSiteList = $Crystals[0]->GetCExpandedAtomSiteList();
	my $nAtomSite    = @AtomSiteList;
	unlink($XSFFile);
	my $xc = new XCrySDen;
	$xc->WriteXSFAnimationFileHeader($XSFFile, $nCrystal);
	my $iline = 0;
	for(my $i = 0 ; $i < $nCrystal ; $i++) {
		$xc->WriteXSFFileFromCrystal($XSFFile, $i+1, $Crystals[$i]);
	}

	$App->print("\nMake Relax XSF File from VASP *CAR Files: Finished\n");

	return 1;
}

sub MakeCIFFile
{
	$App->print("\n\n<b>Make CIF File from VASP *CAR Files:</b>\n");

	my $VASP = new VASP;

	my $CARDir  = $Args->GetGetArg(0);
	my $CIFFile = $Args->GetGetArg(1);
	$CIFFile = $VASP->GetFileNameFromSystemName($CARDir, ".cif") if(!defined $CIFFile);
	unless($CIFFile) {
		$App->print("File names should be specified.\n");
		$App->print("   Usage: VASP.pl --Action=MakeCIF CAR_Dir CIFFile\n");
		return 0;
	}

	$App->print("  Read from [$CARDir].\n");
	$App->print("  Save to $CIFFile.\n");

	my $Crystal = $VASP->ReadStructureFromCARFiles($CARDir);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir].\n");
		return 0;
	}

	my $CIF = new CIF;
	$CIF->CreateCIFFileFromCCrystal($Crystal, $CIFFile, 0, 'unix');

	$App->print("\nMake CIF File from VASP *CAR Files: Finished\n");

	return 1;
}

sub ConvCONTCARFiles
{
	$App->print("\n\n<b>Make CIF Files from VASP POSCAR.initial/POSCAR Files:</b>\n");

	my $VASP = new VASP;

	my $CARDir  = $Args->GetGetArg(0);
	unless($CARDir) {
		$App->print("Directory should be specified.\n");
		$App->print("   Usage: VASP.pl --Action=ConvCONTCARFiles CAR_Dir\n");
		return 0;
	}
	my $POSCAR  = $VASP->GetPOSCARFileName($CARDir) . ".initial";
	if(!-f $POSCAR) {
		$POSCAR  = $VASP->GetPOSCARFileName($CARDir);
	}
	my $CONTCAR  = $VASP->GetCONTCARFileName($CARDir);
	my $CIFFile = $VASP->GetFileNameFromSystemName($CARDir, ".cif");
	my ($drive, $directory, $filename, $ext1, $lastdir, $filebody) = Deps::SplitFilePath($CIFFile);
	my $InitialCIFFile = Deps::MakePath("$drive$directory", "${filebody}-initial.cif", 0);
	my $FinalCIFFile   = Deps::MakePath("$drive$directory", "${filebody}-final.cif", 0);

	$App->print("  Read from [$CARDir].\n");
	$App->print("  Initial strcuture from [$POSCAR].\n");
	$App->print("    Save to [$InitialCIFFile].\n");
	$App->print("  Final strcuture from [$CONTCAR].\n");
	$App->print("    Save to [$FinalCIFFile].\n");

	my $Crystal = $VASP->ReadStructureFromCARFiles($CARDir, 1, POSCARPath => $POSCAR);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir, $POSCAR].\n");
		return 0;
	}
	my $CIF = new CIF;
	if($CIF->CreateCIFFileFromCCrystal($Crystal, $InitialCIFFile, 0, 'unix')) {
		$App->print("CIF File [$InitialCIFFile] was created.\n");
	}
	else {
		$App->print("Error: Could not create [$InitialCIFFile].\n");
	}

	$Crystal = $VASP->ReadStructureFromCARFiles($CARDir, 1, POSCARPath => $CONTCAR);
	unless($Crystal) {
		$App->print("Error: Can not read from [$CARDir, $CONTCAR].\n");
		return 0;
	}
	if($CIF->CreateCIFFileFromCCrystal($Crystal, $FinalCIFFile, 0, 'unix')) {
		$App->print("CIF File [$FinalCIFFile] was created.\n");
	}
	else {
		$App->print("Error: Could not create [$FinalCIFFile].\n");
	}

	$App->print("\nMake CIF Files from VASP POSCAR.initial/POSCAR Files: Finished\n");

	return 1;
}
