首页 >> 专栏博客 >>其他未分类 >> MS脚本-调节分子筛硅铝比的脚本
详细内容

MS脚本-调节分子筛硅铝比的脚本

#!perl

#

# Purpose: Introduces substitutional disorder by replacing a percentage of atoms with another element. 

#          If this is a zeolite, Lowenstein's rule can be used to avoid too many substitutions.

#          Note. When calculating the number of atoms to change, this number is rounded up. This can

#          be changed by modifing the line containing $numToChange.


use strict;

use warnings;

use List::Util qw(shuffle); # Allows randomizing of the atoms in an array

use POSIX; # Allows use of ceil to round-up numbers

use MaterialsScript qw(:all);


# Lowenstein's rule applies to substitution of Aluminium in zeolite and states that no two

# Al atoms can share a common oxygen.


sub CheckLowenstein {

my ($atom) = @_;

#Rule states that Al-O-Al linkages are forbidden

my $attached = $atom->AttachedAtoms;

foreach my $firstAtom (@$attached) {

#Only care about oxygens

if($firstAtom->ElementSymbol eq "O") {

my $oxyAttached = $firstAtom->AttachedAtoms;

foreach my $secondAtom (@$oxyAttached) {

if($secondAtom->ElementSymbol eq "Al") {

return 0; #Lowenstein broken

}

}

}

}

return 1; #Lowenstein satisfied

}


# Main routine to substitute atoms


sub SubstituteAtoms {


my ($doc, $pcChange, $original, $new, $lowenstein)= @_;

# Change the symmetry to P1

$doc->MakeP1;

srand;

# Grab the collection of atoms in the unit cell

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

# Store the original atoms in an array

my @originalAtoms;

foreach my $atom (@$atoms) {

if($atom->ElementSymbol eq "$original") {push(@originalAtoms, $atom);}

}


# Check to see if there are any atoms to modify

if (scalar @originalAtoms == 0) {die "There are no atoms of element $original to modify\n";}


# Randomize the atom positions in the array

my @shuffledOriginalAtoms = shuffle(@originalAtoms);

# calculate the number of atoms to change. The ceil commanound rounds up. If you wish to

# round down, use int instead of ceil.

my $numToChange = ceil (($pcChange/100) * scalar @shuffledOriginalAtoms);

# Iterate through a counter and search for an atom to change

for(my $i=0; $i<$numToChange; ++$i) {

# Check to see if there are any atoms to modify

if (scalar @shuffledOriginalAtoms == 0) {die "Modified $i atoms. There are no atoms of element $original to modify\n";}


my $attempts = 0;

# Look for an atom to modify

my $atom=undef;

while(!$atom && scalar @shuffledOriginalAtoms > 0) {

my $index = int rand( scalar @shuffledOriginalAtoms);

$atom = $shuffledOriginalAtoms[$index];

# Check we haven't already changed it and it satisfies Lowenstein rule (optionally)

if($atom->ElementSymbol eq "$new") {

splice @shuffledOriginalAtoms, $index, 1; $atom = undef;

} elsif ($lowenstein eq "Yes") { 

if (!CheckLowenstein($atom)) {

splice @shuffledOriginalAtoms, $index, 1; $atom = undef;

}

}

++$attempts;

}

# Stop if atom is still undefined as this means Lowensteins rule has been broken

if(!$atom) {

print "Unable to satisfy Lowenstein's rule\n";

# Count the number of atoms changed and report this.

my $modAtoms = 0;

foreach my $at (@{$doc->UnitCell->Atoms}) {

if ($at->ElementSymbol eq "$new") { ++$modAtoms;}

}

print "$modAtoms atoms have been modified to $new element\n";

return;

} else {

#Change the element and display style

$atom->ElementSymbol = "$new";

$atom->Style         = "Ball and Stick";

}

}


}


# Specify the input document and percentage number of silicons to change


my $xsd = $Documents{"TON.xsd"};# Structure name

my $percentChange = 15; # Percentage of atoms of original element to change

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


SubstituteAtoms($xsd, $percentChange,$originalElement, $newElement, $obeyLowenstein);


感谢王正同学的分享




最新评论
请先登录才能进行回复登录
技术支持: CLOUD | 管理登录
seo seo