Perl 语言在 Material Studio 中的应用

解晟
2023-12-01

Material Studio 是一款材料处理的软件,支持 perl 语言,可以进行批量作业提交和处理。这里我提供几个处理场景和脚本。

进行Si/Al 比的调整

对原来的 SubstitutionalDisorder.pl 文件进行调整,将主函数用循环来写,具体操作如下

# list the file name in the current dictionary
my @files =();
find(\&search,'./');
sub search {
	if (-f and /\.xsd$/) {
		my $file = $File::Find::name;
		my $file_name = (split /\//,$file)[-1];
		print $file_name."\n";
		push(@files,$file_name);
	}
}


# SLR Si/Al ratio
my @SLR = (2,3,4,5,10);


foreach my $doc (@files) {
	my $xsd = $Documents{$doc};# Structure name
	foreach my $SLR (@SLR) {
	
		my $percentChange = 1/(1+$SLR)*100;  # Percentage of atoms of original element to change
		my $doc_name = (split /\./, $doc)[0];
		my $doc_SLR = Documents -> New("$doc_name"."_"."$SLR".".xsd");	
		my $originalElement = "Si";	# Original element to change to new element
		my $newElement = "Al";		# New element
		my $obeyLowenstein = "Yes";	# Whether to obey Lowenstein's for zeolites
		my $xsd_treatment = Documents -> New("xsd_treatment.xsd");
		$xsd_treatment -> CopyFrom($xsd);
		my $substitute = SubstituteAtoms($xsd_treatment, $percentChange,$originalElement, $newElement, $obeyLowenstein);
		$doc_SLR -> CopyFrom($substitute);
		$xsd_treatment -> Delete;
		
	}
}

然后将原来 lowenstein 规则中的第 148 行改成

return $doc_treatment;

批量用 sorption 模块导入分子

天呐,这里 “Use current” 的 “current” 居然是小写! 谨记!

#!perl
use File::Find;
use File::Path;
use strict;
use Getopt::Long;
use MaterialsScript qw(:all);

# Specify the files that require to treat

my @files =();

find(\&search,'./');
sub search {

	if (-f and /\.xsd$/ and /\_/) {
	
		my $file = $File::Find::name;
		
		my $file_name = (split /\//,$file)[-1];
		
		push(@files,$file_name);
		
	}
	
}



# excute sorption instruction

my $xsd = $Documents{$files[0]};# Structure name

# Grab the collection of atoms in the unit cell

my $atoms = $xsd->UnitCell->Atoms;

# Store the original atoms in an array

my $Al_number = 0;

foreach my $atom (@$atoms) {
	if ($atom -> ElementSymbol eq "Al") {$Al_number = $Al_number + 1};}

my $index_file = (split /\./, $files[0])[0];

print $index_file;

my $index_file = Modules->Sorption->Locate;

my $component1 = $Documents{"Na.xsd"};

$index_file ->AddComponent($component1);


$index_file ->Loading($component1) = $Al_number;



my $results = $index_file ->Run($xsd, Settings(
	CurrentForcefield => "cvff", 
	AssignForcefieldTypes => "Yes", 
	ChargeAssignment => "Use current", 
	"3DPeriodicElectrostaticSummationMethod" => "Ewald", 
	MetropolisExchangeRatio => 1, 
	MetropolisRegrowthRatio => 1, 
	OptimizationAlgorithm => "Steepest descent"));
	
my $outLowestEnergyStructure = $results->LowestEnergyStructure;

my $doc_name = (split /\./, $files[0])[0];
$xsd -> Export("$doc_name.cif");

$Documents{"$doc_name Convergence.xcd"} -> Delete;
$Documents{"$doc_name Energies.xcd"} -> Delete;
$Documents{"Status.txt"} -> Delete;
$Documents{"$doc_name.txt"} -> Delete;
$Documents{"$doc_name Etotal.xcd"} -> Delete;

# treat other files. Since the addsorption instruction should only appears onece, so we need to specifically write the first instruction

shift(@files);

foreach my $doc (@files) {

	my $xsd = $Documents{$doc};# Structure name
	
	# Grab the collection of atoms in the unit cell
	
	my $atoms = $xsd->UnitCell->Atoms;
	
	# Store the original atoms in an array
	
	my $Al_number = 0;
	
	foreach my $atom (@$atoms) {
		if ($atom -> ElementSymbol eq "Al") {$Al_number = $Al_number + 1};}
	
	
	my $index_file = (split /\./, $doc)[0];
	
	print $index_file;
	
	my $index_file = Modules->Sorption->Locate;
	
	my $component1 = $Documents{"Na.xsd"};
	
	

	$index_file ->Loading($component1) = $Al_number;

	
	
	my $results = $index_file ->Run($xsd, Settings(
		CurrentForcefield => "cvff", 
		AssignForcefieldTypes => "Yes", 
		ChargeAssignment => "Use current", 
		"3DPeriodicElectrostaticSummationMethod" => "Ewald", 
		MetropolisExchangeRatio => 1, 
		MetropolisRegrowthRatio => 1, 
		OptimizationAlgorithm => "Steepest descent"));

		
	my $outLowestEnergyStructure = $results->LowestEnergyStructure;
	
	
	
	my $doc_name = (split /\./, $doc)[0];
	$xsd -> Export("$doc_name.cif");
	
	$Documents{"$doc_name Convergence.xcd"} -> Delete;
	$Documents{"$doc_name Energies.xcd"} -> Delete;
	$Documents{"Status.txt"} -> Delete;
	$Documents{"$doc_name.txt"} -> Delete;
	$Documents{"$doc_name Etotal.xcd"} -> Delete;

}




修改同一个元素的原子电荷

在这里需要注意两点

  1. 在 if 中 等于判断应该写 eq
  2. if 后面用 {} 引起来
$doc = $Documents{"A.xsd"};
$atoms = $doc -> UnitCell -> Atom;
foreach $atom (@$atoms) {
	if ($atom -> ElementSymbol eq "Al") {$atom -> Charge = 1.4;}
 类似资料: