Coverage for cclib/method/cspa.py : 87%
Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2#
3# Copyright (c) 2018, the cclib development team
4#
5# This file is part of cclib (http://cclib.github.io) and is distributed under
6# the terms of the BSD 3-Clause License.
8"""C-squared population analysis."""
10import random
12import numpy
14from cclib.method.population import Population
17class CSPA(Population):
18 """The C-squared population analysis."""
20 # Overlaps are not required for CSPA.
21 overlap_attributes = ()
23 def __init__(self, *args):
25 # Call the __init__ method of the superclass.
26 super(CSPA, self).__init__(logname="CSPA", *args)
28 def __str__(self):
29 """Return a string representation of the object."""
30 return "CSPA of %s" % (self.data)
32 def __repr__(self):
33 """Return a representation of the object."""
34 return 'CSPA("%s")' % (self.data)
36 def calculate(self, indices=None, fupdate=0.05):
37 """Perform the C squared population analysis.
39 Inputs:
40 indices - list of lists containing atomic orbital indices of fragments
41 """
42 self.logger.info("Creating attribute aoresults: array[3]")
44 # Determine number of steps, and whether process involves beta orbitals.
45 unrestricted = (len(self.data.mocoeffs)==2)
46 nbasis = self.data.nbasis
47 self.aoresults = []
48 alpha = len(self.data.mocoeffs[0])
49 self.aoresults.append(numpy.zeros([alpha, nbasis], "d"))
50 nstep = alpha
51 if unrestricted:
52 beta = len(self.data.mocoeffs[1])
53 self.aoresults.append(numpy.zeros([beta, nbasis], "d"))
54 nstep += beta
56 # Intialize progress if available.
57 if self.progress:
58 self.progress.initialize(nstep)
60 step = 0
61 for spin in range(len(self.data.mocoeffs)):
63 for i in range(len(self.data.mocoeffs[spin])):
65 if self.progress and random.random() < fupdate:
66 self.progress.update(step, "C^2 Population Analysis")
68 submocoeffs = self.data.mocoeffs[spin][i]
69 scale = numpy.inner(submocoeffs, submocoeffs)
70 tempcoeffs = numpy.multiply(submocoeffs, submocoeffs)
71 tempvec = tempcoeffs/scale
72 self.aoresults[spin][i] = numpy.divide(tempcoeffs, scale).astype("d")
74 step += 1
76 if self.progress:
77 self.progress.update(nstep, "Done")
79 retval = super(CSPA, self).partition(indices)
81 if not retval:
82 self.logger.error("Error in partitioning results")
83 return False
85 self.logger.info("Creating fragcharges: array[1]")
86 size = len(self.fragresults[0][0])
87 self.fragcharges = numpy.zeros([size], "d")
88 alpha = numpy.zeros([size], "d")
89 if unrestricted:
90 beta = numpy.zeros([size], "d")
92 for spin in range(len(self.fragresults)):
94 for i in range(self.data.homos[spin] + 1):
96 temp = numpy.reshape(self.fragresults[spin][i], (size,))
97 self.fragcharges = numpy.add(self.fragcharges, temp)
98 if spin == 0:
99 alpha = numpy.add(alpha, temp)
100 elif spin == 1:
101 beta = numpy.add(beta, temp)
103 if not unrestricted:
104 self.fragcharges = numpy.multiply(self.fragcharges, 2)
105 else:
106 self.logger.info("Creating fragspins: array[1]")
107 self.fragspins = numpy.subtract(alpha, beta)
109 return True