1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
#!/usr/bin/perl -w
######################################################################
## This program is copyright (c) 2001 Bruce Ravel
## <ravel@phys.washington.edu>
## http://feff.phys.washington.edu/~ravel/
##
## -------------------------------------------------------------------
## All rights reserved. This program is free software; you can
## redistribute it and/or modify it under the same terms as Perl
## itself.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## Artistic License for more details.
## -------------------------------------------------------------------
######################################################################
use Xray::Absorption;
Xray::Absorption -> load("elam");
use Chemistry::Formula qw(parse_formula formula_data);
use strict;
(@ARGV) or &usage;
($ARGV[0] =~ /-{1,2}h(elp)?/i) and &usage;
use Getopt::Std;
use vars qw(%opt);
$opt{o} = "";
getopts('ld:e:f:', \%opt);
my (%count, $string);
my $energy = $opt{e} || 0;
my $density = $opt{d} || 0;
if ($opt{f}||$opt{l}) {
my (%formula, %density);
&formula_data(\%formula, \%density);
if ($opt{l}) {
print "Known formulas:\n\n";
printf " %-15s %-30s %-s\n", 'name', 'formula', 'density';
print '-' x 70, $/;
foreach my $f (sort (keys %formula)) {
printf " %-15s %-30s %-s\n", $f, $formula{$f}, $density{$f};
};
exit;
};
($formula{$opt{f}}) or die "\"$opt{f}\" is not a known material\n";
$string = $formula{$opt{f}};
$density = $density{$opt{f}};
} else {
$string = $ARGV[0];
};
($energy > 0) or $density = 0;
my $ok = parse_formula($string, \%count);
my $dens = ($density =~ /^(\d+\.?\d*|\.\d+)$/) ? $density : 0;
($ok) or do {
print "Input error:\n\t$count{error}";
die "\n";
};
print <<EOH;
Input string: "$string"
element number
--------- --------
EOH
my ($weight, $xsec) = (0,0);
my ($barns_per_formula_unit, $amu_per_formula_unit) = (0,0);
foreach my $k (sort (keys(%count))) {
$barns_per_formula_unit += Xray::Absorption -> cross_section($k, $energy) * $count{$k};
$amu_per_formula_unit += Xray::Absorption -> get_atomic_weight($k) * $count{$k};
if ($count{$k} > 0.001) {
printf(" %-2s %.3f\n", $k, $count{$k});
} else {
printf(" %-2s %g\n", $k, $count{$k});
};
};
## 1 amu = 1.6607143 x 10^-24 gm
$xsec = $barns_per_formula_unit / $amu_per_formula_unit / 1.6607143;
printf "\nThis weighs %.3f amu.\n", $amu_per_formula_unit;
if ($xsec == 0) {
print "(Energy too low or not provided. Absorption calculation skipped.)\n";
} else {
$xsec *= $dens;
if ($xsec > 0) {
if (10000/$xsec > 500) {
printf("Absorbtion length = %.3f cm at %.2f eV.\n", 1/$xsec, $energy);
} else {
printf("Absorbtion length = %.1f microns at %.2f eV.\n", 10000/$xsec, $energy);
};
} else {
print "(The absorption length calculation requires a value for density.)";
};
};
sub usage {
print <<EOH;
Enumerate chemical formulas and compute absorption length
usage:
formula -e # -d # <string> // formula, energy, and density supplied
formula -e # -f <string> // use a known formula
formula -l // list of known materials
formula -h // this message
EOH
exit;
};
|