File Coverage

blib/lib/Chemistry/ESPT/ADFout.pm
Criterion Covered Total %
statement 32 109 29.3
branch 0 38 0.0
condition 1 6 16.6
subroutine 4 6 66.6
pod 2 2 100.0
total 39 161 24.2


line stmt bran cond sub pod time code
1             package Chemistry::ESPT::ADFout;
2              
3 1     1   24952 use base qw(Chemistry::ESPT::ESSfile);
  1         1  
  1         504  
4 1     1   5 use strict;
  1         2  
  1         22  
5 1     1   8 use warnings;
  1         1  
  1         1111  
6              
7             =head1 NAME
8              
9             Chemistry::ESPT::ADFout - Amsterdam Density Functional (ADF) output file object.
10              
11             =head1 SYNOPSIS
12              
13             use Chemistry::ESPT::ADFout;
14              
15             my $out = Chemistry::ESPT::ADFout->new();
16              
17             =head1 DESCRIPTION
18              
19             This module provides methods to quickly access data contianed in an ADF output file.
20             ADF output files can only be read currently.
21              
22             =begin comment
23              
24             ### Version History ###
25             0.01 digest open & closed shell DFT output files,
26             0.02 unified get method, Debug options, ,
27             switched to ESPT namespace
28              
29             ### To Do ###
30             -Convert functionals to simpler syntax when appropriate
31             -Report non-mixed ADF basis sets
32             -Non-GGG functionals & energetics
33             -Electronic state & multiplicity
34              
35             =end comment
36              
37             =cut
38              
39             our $VERSION = '0.02';
40              
41             =head1 ATTRIBUTES
42              
43             All attributes are currently read-only and get populated by reading the assigned ESS file. Attribute values
44             are accessible through the B<$ADFout-Eget()> method.
45              
46             =over 15
47              
48             =item COMPILE
49              
50             String containing the compile architechture.
51              
52             =item EELEC
53              
54             Electronic energy.
55              
56             =item EIGEN
57              
58             A rank two tensor containing the eigenvalues. The eigenvalues correspond to Alpha or
59             Beta depending upon what spin was passesd to B<$ADFout-Eanalyze()>.
60              
61             =item FUNCTIONAL
62              
63             String containing the DFT functional utlized in this job.
64              
65             =item HOMO
66              
67             Number corresponding to the highest occupied molecular orbital. The value corresponds
68             to either Alpha or Beta electrons depending upon what spin was passesd to
69             B<$ADFout-Eanalyze()>.
70              
71             =item MOSYMM
72              
73             A rank two tensor containing the molecular orbital symmetry labels.
74              
75             =item OCC
76              
77             A rank two tensor containing the molecular orbital occupations.
78              
79             =item PG
80              
81             Array of molecular point group values.
82              
83             =item REVISION
84              
85             ADF revision label.
86              
87             =item RUNTIME
88              
89             Date when the calculation was run.
90              
91             =item VERSION
92              
93             ADF version.
94              
95             =back
96              
97             =head1 METHODS
98              
99             Method parameters denoted in [] are optional.
100              
101             =over 15
102              
103             =item B<$out-Enew()>
104              
105             Creates a new ADFout object
106              
107             =cut
108              
109             ## the object constructor **
110              
111             sub new {
112 1     1 1 10 my $invocant = shift;
113 1   33     8 my $class = ref($invocant) || $invocant;
114 1         153 my $out = Chemistry::ESPT::ESSfile->new();
115            
116 1         7 $out->{TYPE} = "out";
117            
118             # program info
119 1         2 $out->{PROGRAM} = "ADF";
120 1         2 $out->{VERSION} = undef;
121 1         3 $out->{REVISION} = undef;
122 1         3 $out->{COMPILE} = undef;
123            
124             # calc info
125 1         2 $out->{RUNTIME} = undef;
126 1         2 $out->{THEORY} = "DFT";
127 1         2 $out->{FUNCTIONAL} = undef;
128 1         2 $out->{BASIS} = "Mixed";
129 1         2 $out->{NBASIS} = 0; # Core-orthogonalized Symmetrized Fragment Orbitals
130            
131             # molecular info
132 1         3 $out->{EIGEN} = [];
133 1         3 $out->{EELEC} = undef; # SCF electronic bonding energy
134 1         1 $out->{ENERGY} = undef; # total bonding energy
135 1         3 $out->{EINFO} = "Bonding E(elec)"; # total bonding energy description
136 1         3 $out->{HOMO} = undef;
137 1         3 $out->{MOSYMM} = [];
138 1         2 $out->{OCC} = [];
139 1         2 $out->{PG} = undef;
140              
141 1         2 bless($out, $class);
142 1         4 return $out;
143             }
144              
145              
146             ## methods ##
147              
148             =item B<$out-Eanalyze(filename [spin])>
149            
150             Analyze the spin results in file called filename. Spin defaults to Alpha.
151              
152             =cut
153              
154             # set filename & spin then digest the file
155             sub analyze: method {
156 0     0 1   my $out = shift;
157 0           $out->prepare(@_);
158 0           $out->_digest();
159 0           return;
160             }
161              
162             ## subroutines ##
163              
164             sub _digest {
165             # Files larger than 1Mb should be converted to binary and then
166             # processed to ensure maximum speed. -D. Ennis, OSC
167              
168             # For items with multiple occurances, the last value is reported
169              
170 0     0     my $out = shift;
171              
172             # flags & counters
173 0           my $Ccount = 0;
174 0           my $Cflag = 0;
175 0           my $eigcount = 0;
176 0           my $MOcount = 0;
177 0           my $orbcount = -1;
178 0           my $PGcount = 0;
179 0           my $rparsed = 0;
180 0           my $Sflag = 0;
181 0           my $symmflag = 0;
182              
183             # open filename for reading or display error
184 0 0         open(LOGFILE,$out->{FILENAME}) || die "Could not read $out->{FILENAME}\n$!\n";
185              
186             # grab everything which may be useful
187 0           while (){
188             # skip blank lines
189 0 0         next if /^$/;
190              
191             # version info & run time (multiple occurances & values)
192 0 0         if ( /^\sADF\s+(\d+).(\d+)\s+RunTime:\s+([a-zA-Z]+)(\d{1,2})-(\d{4})\s\d{2}:\d{2}:\d{2}/ ) {
193 0           $out->{VERSION} = $1;
194 0           $out->{REVISION} = $2;
195 0           $out->{RUNTIME} = "$4-$3-$5";
196 0           next;
197             }
198             # compile architecture (multiple occurances)
199 0 0         if ( /^\s\*+\s+([a-z_A-Z]+)\s+\*+/ ) {
200 0           $out->{COMPILE} = $1;
201 0           next;
202             }
203             # functional (multiple occurances)
204 0 0         if ( /^\s+Gradient Corrections:\s+([a-zA-Z0-9]+)\s+([a-zA-Z0-9]+)/ ) {
205 0           $out->{FUNCTIONAL} = "$1$2";
206 0           next;
207             }
208             # full point group
209 0 0         if ( /^\s+Symmetry:\s+([CDSIOT])\(([0-9DHILNV]+)\)/ ) {
210 0           $out->{PG} [$PGcount] = "$1($2)";
211 0           $PGcount++;
212 0           next;
213             }
214             # electrons
215             # figure HOMO & LUMO, alphas fill first
216             # restricted
217 0 0         if ( /^\s+Total:\s+(\d+)\s+\z/ ) {
218 0           $out->{ALPHA} = $out->{BETA} = $out->{HOMO} = $1/2;
219 0           next;
220             }
221             # unrestricted
222 0 0         if ( /^\s+Total:\s+(\d+)\s+(?:\(Spin-A\)\s+\+\s+)*(\d+)\s+(?:\(Spin-B\))*/ ) {
223 0           $out->{ALPHA} = $1;
224 0           $out->{BETA} = $2;
225 0           $out->{HOMO} = $out->{uc($out->{SPIN})};
226 0           next;
227             }
228             # charge (multiple values and occurances)
229 0 0         if ( /^\s+Net Charge:\s+(-*\d+)/ ) {
230 0           $out->{CHARGE} = $1;
231 0           next;
232             }
233             # Multiplicity (multiple occurrences)
234 0 0         if ( /^\s+Spin polar:\s+(\d+)/ ) {
235 0           $out->{MULTIPLICITY} = $1+1;
236 0           next;
237             }
238             # Core-orthogonalized Symmetrized Fragment Orbitals (molecular calculations)
239 0 0         if (/^\s+Total nr. of \(C\)SFOs \(summation over all irreps\)\s+:\s+(\d+)/) {
240 0           $out->{NBASIS} = $1;
241 0           next;
242             }
243             # orbital symmetries, energies, occupations (multiple occurrences)
244 0 0         if ( /^\s+Orbital\s+Energies,\s+all\s+Irreps/ ) {
245 0           $symmflag = 1;
246 0           $MOcount = 0;
247 0           $orbcount++;
248 0           next;
249             }
250 0 0 0       if ( $symmflag == 1 && /^\s+([123ABDEGHILMPST\.gu]+)\s+\d+\s+[$out->{SPIN}]*\s+(\d+\.\d+)\s+(\-*\d\.\d+E\-*\+*\d+)\s+(\-*\d+\.\d+)\s+/ ) {
251 0           my $symm = $1;
252 0           my $txt = $2;
253 0           my $eigen = $3;
254 0           my $degen = 1;
255 0 0         if ( $symm =~ /E[E123\.ug]/ ) {
    0          
256 0           $degen = 2;
257             } elsif ( $symm =~ /T[123\.ug]/ ) {
258 0           $degen = 3;
259             }
260 0 0         $orbcount++ if $orbcount == -1; # temporary hack
261 0           for (my $i=1; $i<=$degen; $i++ ) {
262 0           $out->{MOSYMM} [$orbcount] [$MOcount] = lc($symm);
263 0           $out->{EIGEN} [$orbcount] [$MOcount] = $eigen;
264 0           $out->{OCC} [$orbcount] [$MOcount] = $txt/$degen;
265 0           $MOcount++;
266             }
267 0 0         $MOcount = $symmflag = 0 if $MOcount == $out->{NBASIS};
268 0           next;
269             }
270             # SCF bonding electronic energy
271             # Grab from logfile. Occurs earlier but harder to pick out.
272 0 0         if ( /^\s+.*\s+GGA-XC\s+(-*\d+\.\d+)\s+a\.u\./ ) {
273 0           $out->{EELEC} = $1;
274 0           $out->{ENERGY} = $1;
275 0           next;
276             }
277             # value
278 0 0         if ( /^\s+Total\s+S2\s+\(S\s+squared\)\s+\d\.\d+\s+(\d\.\d+)/ ) {
279 0           $out->{SSQUARED} = $1;
280 0           next;
281             }
282              
283             }
284             }
285              
286              
287             1;
288             __END__