[a0bcf1] | 1 | #! @PERL@ -w
|
---|
| 2 | #
|
---|
| 3 | # Evaluates total energy and forces for a given bond dissection
|
---|
| 4 | #
|
---|
| 5 | # We assume to have the following, an $Inputdir with the following contents:
|
---|
| 6 | # - For each Atomic Fragment
|
---|
| 7 | # - A directory with results, especially pcp.energy.all and pcp.forces.all
|
---|
| 8 | # - Files called AtomicFragmentTE-Factors.dat and AtomicFragmentForces-Factors.dat
|
---|
| 9 | # - For Each Bond Fragment
|
---|
| 10 | # - A directory with results, especially pcp.energy.all and pcp.forces.all
|
---|
| 11 | # - Files called BondFragmentTE-Factors.dat and BondFragmentForces-Factors.dat
|
---|
| 12 |
|
---|
| 13 | use strict;
|
---|
| 14 |
|
---|
| 15 | my ($Help, $Prefix, $Inputdir);
|
---|
| 16 | my ($i, $j, $k, $l);
|
---|
| 17 | use Getopt::Long;
|
---|
| 18 | use File::Copy;
|
---|
| 19 |
|
---|
| 20 | GetOptions("help" => \$Help,
|
---|
| 21 | "prefix=s", => \$Prefix,
|
---|
| 22 | "inputdir=s" => \$Inputdir);
|
---|
| 23 |
|
---|
| 24 | if ($Help) { usage(); }
|
---|
| 25 |
|
---|
| 26 | sub usage {
|
---|
| 27 | print STDERR <<"EOF";
|
---|
| 28 | Usage: $0 [OPTIONS]
|
---|
| 29 | Evaluates the approximate expression of a many-body bond order dissection and writes pcp.energy and pcp.forces files in the inputdir
|
---|
| 30 | --prefix <prefix> prefix in front of .forces.all and .energy.all
|
---|
| 31 | --inputdir <inputdir> read data from this directory
|
---|
| 32 | --help this help
|
---|
| 33 | EOF
|
---|
| 34 | exit 1;
|
---|
| 35 | }
|
---|
| 36 |
|
---|
| 37 | if ((!defined $Inputdir) || (!defined $Prefix)) {
|
---|
| 38 | print "Inputdir and/or Prefix not specified! See --help.\n";
|
---|
| 39 | exit 1;
|
---|
| 40 | }
|
---|
| 41 |
|
---|
| 42 | # Total energy
|
---|
| 43 | my @TotalEnergy;
|
---|
| 44 | my @TotalForce;
|
---|
| 45 | my $energy;
|
---|
| 46 | my $forces;
|
---|
| 47 | my @tmp;
|
---|
| 48 |
|
---|
| 49 | # Parse in total energy factors (1d array: Fragment)
|
---|
| 50 | open(TEFactors, "<$Inputdir/BondFragmentTE-Factors.dat") or die "could not open $Inputdir/BondFragmentTE-Factors.dat: $!";
|
---|
| 51 | my $line = <TEFactors>;
|
---|
| 52 | chomp($line);
|
---|
| 53 | close(TEFactors);
|
---|
| 54 | my @Factors = split(/[ \t]+/, $line);
|
---|
| 55 | my $lasttime = 0;
|
---|
| 56 |
|
---|
| 57 | # Print parsed total energy factors
|
---|
| 58 | print "TEFactors:\n";
|
---|
| 59 | foreach $energy (@Factors) {
|
---|
| 60 | print $energy."\t";
|
---|
| 61 | }
|
---|
| 62 | print "\n";
|
---|
| 63 |
|
---|
| 64 | # Parse in Force factors (3d array: AtomPerFragment,AtomPerWholeMolecule,Fragment )
|
---|
| 65 | my @ForceFactors;
|
---|
| 66 | open(FORCEFactors, "<$Inputdir/BondFragmentForces-Factors.dat") or die "could not open $Inputdir/BondFragmentForces-Factors.dat: $!";
|
---|
| 67 | do {
|
---|
| 68 | my @FragmentFactors;
|
---|
| 69 | do {
|
---|
| 70 | $line = <FORCEFactors>;
|
---|
| 71 | chomp $line;
|
---|
| 72 | my @tmp = split(/[ \t]+/, $line);
|
---|
| 73 | if ( $#tmp ) {
|
---|
| 74 | push @FragmentFactors, [ @tmp ]; # push a copy of the parsed line
|
---|
| 75 | }
|
---|
| 76 | #foreach $forces ( @tmp ) {
|
---|
| 77 | # print "\t [ $forces ]";
|
---|
| 78 | #}
|
---|
| 79 | $energy = $#tmp;
|
---|
| 80 | #print "\t: ".$#tmp." atoms.\n";
|
---|
| 81 | } until ( $energy == -1 ); # next fragment
|
---|
| 82 | #print "Next Fragment!\n";
|
---|
| 83 | # read over next line
|
---|
| 84 | push @ForceFactors, [ @FragmentFactors ]; # push a copy of the parsed Fragment
|
---|
| 85 | $line = <FORCEFactors>;
|
---|
| 86 | } while(<FORCEFactors>);
|
---|
| 87 | close(FORCEFactors);
|
---|
| 88 |
|
---|
| 89 | # Print parsed Force Factors
|
---|
| 90 | print "\nForce Factors:\n";
|
---|
| 91 | for $i ( 0 .. $#ForceFactors ) {
|
---|
| 92 | print "Fragment $i\n";
|
---|
| 93 | for $j ( 0 .. $#{$ForceFactors[$i]} ) {
|
---|
| 94 | for $k ( 0 .. $#{${$ForceFactors[$i]}[$j]} ) {
|
---|
| 95 | print $ForceFactors[$i][$j][$k]."\t";
|
---|
| 96 | }
|
---|
| 97 | print "\n";
|
---|
| 98 | }
|
---|
| 99 | print "\n";
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 | # check on the number of digits
|
---|
| 103 | my $format = "-1";
|
---|
| 104 | for($i=1;$i<10;$i++)
|
---|
| 105 | {
|
---|
| 106 | my $test = "%0".$i."s";
|
---|
| 107 | my $filename = sprintf($test,$i);
|
---|
| 108 | if ( -e "$Inputdir/BondFragment$filename" )
|
---|
| 109 | {
|
---|
| 110 | $format = $test;
|
---|
| 111 | }
|
---|
| 112 | }
|
---|
| 113 | print "Recognized format for BondFragment filename is: $format\n";
|
---|
| 114 |
|
---|
| 115 |
|
---|
| 116 | # Parse local energy and forces from the various FragmentDirs
|
---|
| 117 | for ($i=0;$i<=$#Factors;$i++)
|
---|
| 118 | {
|
---|
| 119 | my $filename = sprintf($format, $i);
|
---|
| 120 | my @LocalEnergy;
|
---|
| 121 | open(TE, "<$Inputdir/BondFragment".$filename."/$Prefix.energy.all") or die "could not open $Inputdir/BondFragment".$filename."/$Prefix.energy.all: $!";
|
---|
| 122 | # skip first line containing the header
|
---|
| 123 | $line = <TE>;
|
---|
| 124 | # ($Time, $Total, $Kinetic, $NonLocal, $Correlation, $Exchange, $Pseudo, $Hartree, $Gauss, $Ewald, $ETotal)
|
---|
| 125 | while ($line = <TE>) {
|
---|
| 126 | chomp($line);
|
---|
| 127 | my @tmp = split(/[ \t]+/, $line);
|
---|
| 128 | for $k ( 0 .. $#tmp) {
|
---|
| 129 | $tmp[$k] *= $Factors[$i];
|
---|
| 130 | }
|
---|
| 131 | push @LocalEnergy, [ @tmp ];
|
---|
| 132 | }
|
---|
| 133 | close(TE);
|
---|
| 134 |
|
---|
| 135 | # sum up energy
|
---|
| 136 | for $j ( 0 .. $#LocalEnergy )
|
---|
| 137 | {
|
---|
| 138 | #print " @{$LocalEnergy[$j]} \n";
|
---|
| 139 | if ( $i == 0) {
|
---|
| 140 | push @TotalEnergy, [ @{$LocalEnergy[$j]} ];
|
---|
| 141 | } else {
|
---|
| 142 | for $k ( 0 .. $#{$LocalEnergy[$j]} ) {
|
---|
| 143 | $TotalEnergy[$j][$k] += $LocalEnergy[$j][$k];
|
---|
| 144 | }
|
---|
| 145 | }
|
---|
| 146 | }
|
---|
| 147 |
|
---|
| 148 | my @LocalForce;
|
---|
| 149 | open(FORCE, "<$Inputdir/BondFragment".$filename."/$Prefix.forces.all") or die "could not open $Inputdir/BondFragment".$filename."/$Prefix.forces.all: $!";
|
---|
| 150 | # skip first line containing the header
|
---|
| 151 | $line = <FORCE>;
|
---|
| 152 | while (<FORCE>) {
|
---|
| 153 | next if /MeanForce:/;
|
---|
| 154 | chomp;
|
---|
| 155 | my @tmp = split(/[ \t]/);
|
---|
| 156 | push @LocalForce, [ @tmp ];
|
---|
| 157 | }
|
---|
| 158 | close(FORCE);
|
---|
| 159 |
|
---|
| 160 | # sum up forces
|
---|
| 161 | for $j ( 0 .. $#LocalForce) { # atom in fragment
|
---|
| 162 | # Add local forces times their factor
|
---|
| 163 | for $k ( 0 .. $#{$LocalForce[$j]} ) { # force type
|
---|
| 164 | for $l ( 0 .. $#{$ForceFactors[$i]} ) { # whole molecule atom
|
---|
| 165 | #print "fragment $i\tfragment atom $j\t force type $k\t molecule atom $l\n";
|
---|
| 166 | if (0) { # ($j == 0) && ($i == 0)) {
|
---|
| 167 | if ($k >= 5) { # forces start at column 5
|
---|
| 168 | $TotalForce[$l][$k] = $LocalForce[$j][$k] * $ForceFactors[$i][$l][$j];
|
---|
| 169 | } else { # take correct position only if local fragment atom relates to whole molecule atom
|
---|
| 170 | if ($ForceFactors[$i][$l][$j] != 0) {
|
---|
| 171 | $TotalForce[$l][$k] = $LocalForce[$j][$k];
|
---|
| 172 | }
|
---|
| 173 | }
|
---|
| 174 | } else {
|
---|
| 175 | if ($k >= 5) { # forces start at column 5
|
---|
| 176 | $TotalForce[$l][$k] += $LocalForce[$j][$k] * $ForceFactors[$i][$l][$j];
|
---|
| 177 | } else { # take correct position only if local fragment atom relates to whole molecule atom
|
---|
| 178 | if ($ForceFactors[$i][$l][$j] != 0) {
|
---|
| 179 | $TotalForce[$l][$k] = $LocalForce[$j][$k];
|
---|
| 180 | }
|
---|
| 181 | }
|
---|
| 182 | }
|
---|
| 183 | }
|
---|
| 184 | }
|
---|
| 185 | }
|
---|
| 186 | }
|
---|
| 187 |
|
---|
| 188 | # output summed up approximate total energy
|
---|
| 189 | open(TE, ">$Inputdir/$Prefix.energy.all") or die "could not open $Inputdir/$Prefix.energy.all: $!";
|
---|
| 190 | printf(TE "#Level\t%s\t\t%s\t\t%s\t\t%s\t%s\t%s\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\n",
|
---|
| 191 | "Time",
|
---|
| 192 | "Total",
|
---|
| 193 | "Kinetic", "NonLocal",
|
---|
| 194 | "Correlation", "Exchange",
|
---|
| 195 | "Pseudo", "Hartree",
|
---|
| 196 | "-Gauss",
|
---|
| 197 | "Ewald",
|
---|
| 198 | "IonKin",
|
---|
| 199 | "ETotal");
|
---|
| 200 | for $j ( 0 .. $#TotalEnergy )
|
---|
| 201 | {
|
---|
| 202 | print TE ($j+1)."\t";
|
---|
| 203 | for $k ( 0 .. $#{$TotalEnergy[$j]} ) {
|
---|
| 204 | print TE "$TotalEnergy[$j][$k]\t";
|
---|
| 205 | }
|
---|
| 206 | print TE "\n";
|
---|
| 207 | }
|
---|
| 208 | print TE "\n";
|
---|
| 209 | close(TE);
|
---|
| 210 |
|
---|
| 211 | # output summed up approximate total forces
|
---|
| 212 | open(FORCE, ">$Inputdir/$Prefix.forces.all") or die "could not open $Inputdir/$Prefix.forces.all: $!";
|
---|
| 213 | printf(FORCE "#%s\t%s\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t\t%s\t%s\t%s\t%s\t\t%s\t\t%s\n",
|
---|
| 214 | "Type", "No",
|
---|
| 215 | "Pos0", "Pos1", "Pos2",
|
---|
| 216 | "Total0", "Total1", "Total2",
|
---|
| 217 | "Local0", "Local1", "Local2",
|
---|
| 218 | "NLocal0", "NLocal1", "NLocal2",
|
---|
| 219 | "Magnetic0", "Magnetic1", "Magnetic2",
|
---|
| 220 | "Ewald0", "Ewald1", "Ewald2");
|
---|
| 221 | for $i ( 0 .. $#TotalForce ) {
|
---|
| 222 | for $j ( 0 .. $#{$TotalForce[$i]} ) {
|
---|
| 223 | print FORCE "$TotalForce[$i][$j]\t";
|
---|
| 224 | }
|
---|
| 225 | print FORCE "\n";
|
---|
| 226 | }
|
---|
| 227 | print FORCE "\n";
|
---|
| 228 | close(FORCE);
|
---|
| 229 |
|
---|
| 230 |
|
---|
| 231 | exit 0;
|
---|