之前写过一篇关于计算分子间作用能的文章,那如何计算轨迹的分子间相互作用能呢?此时,需要利用perl脚本进行计算。
MS的help已经给出了计算单个xsd文件相互作用能的脚本,我们需要做的就是将它进一步优化,用于轨迹文件分子间作用能的计算。主要思想包括以下几个部分:(1)提取各个Layer,用于后面的计算(2)计算各个Layer能量及总能量(3)采用循环语句,循环(1)(2)步
1 创建列表 这是所有工作之前的准备工作,需要创建一个列表存储layer和计算数据
my $doc = $Documents{"Layer.xtd"};
my $newStudyTable = Documents->New("InteractionEnergy.std");
my $calcSheet = $newStudyTable->ActiveSheet;
# 创建列表抬头
$calcSheet->ColumnHeading(0) = "Cell";
$calcSheet->ColumnHeading(1) = "Total Energy of Cell";
$calcSheet->ColumnHeading(2) = "layer1";
$calcSheet->ColumnHeading(3) = "Energy of layer1";
$calcSheet->ColumnHeading(4) = "layer2";
$calcSheet->ColumnHeading(5) = "Energy of layer2";
2 提取各个Layer
my $layer1Doc = Documents->New("bottom.xsd");
my $layer2Doc = Documents->New("top.xsd");
$allDoc->CopyFrom($doc);
$layer1Doc->CopyFrom($doc);
$layer1Doc->UnitCell->Sets("Layer 2")->Atoms->Delete;
$layer2Doc->CopyFrom($doc);
$layer2Doc->UnitCell->Sets("Layer 1")->Atoms->Delete;
#取消所有原子的固定
my $atoms = $allDoc->UnitCell->Atoms;
$atoms->Unfix("XYZ");
my $atoms = $layer1Doc->UnitCell->Atoms;
$atoms->Unfix("XYZ");
#将结构放到表格对应的位置
$calcSheet->Cell($counter-1,0) = $allDoc;
$calcSheet->Cell($counter-1,2) = $layer1Doc;
$calcSheet->Cell($counter-1,4) = $layer2Doc;
3 能量计算 首先是基本参数设置,然后进行计算。其中,由于有一步是删除计算后的.xsd文件,这是因为计算过程中会产生大量的过程文件,这样可以防止内存不够。
#首先是forcite的设置,这一步你可以直接打开forcite,设置完所有选项后粘贴过来
my $forcite = Modules->Forcite;
$forcite->ChangeSettings(Settings(Quality => "Fine",
CurrentForcefield => "COMPASS"));
#计算每个layer的能量及总能量
$forcite->Energy->Run($allDoc);
$calcSheet->Cell($counter-1, 1) = $allDoc->PotentialEnergy;
$forcite->Energy->Run($layer1Doc);
$calcSheet->Cell($counter-1, 3) = $layer1Doc->PotentialEnergy;
$forcite->Energy->Run($layer2Doc);
$calcSheet->Cell($counter-1, 5) = $layer2Doc->PotentialEnergy;
$calcSheet->Cell($counter-1,0) = $allDoc-> UnitCell->Atoms->Delete;
$calcSheet->Cell($counter-1,2) = $layer1Doc-> UnitCell->Atoms->Delete;
$calcSheet->Cell($counter-1,4) = $layer2Doc-> UnitCell->Atoms->Delete;
my $interactionEnergy = $totalEnergy - ($layer1Energy + $layer2Energy);
$calcSheet->Cell($counter-1, 6) = $interactionEnergy;
#删除过程文件
my $totalEnergy = $calcSheet->Cell($counter-1, 1);
my $layer1Energy = $calcSheet->Cell($counter-1, 3);
my $layer2Energy = $calcSheet->Cell($counter-1, 5);
4循环计算 以轨迹的帧数为循环次数,设定自己的循环步长,然后将计算主体塞入循环即可
my $numFrames = $doc->Trajectory->NumFrames;
for (my $counter = 1; $counter <= $numFrames ; ++$counter) {
#sets the current frame to the value of counter
$doc->Trajectory->CurrentFrame = $counter;
...循环主体...
}
最后提醒大家,help文件是学习每个软件最好的教程。对于这类程序的编写,基本上都可以通过help文件进行改编,整合为自己所用。也希望大家多多贡献自己的代码,互相学习!