Hide keyboard shortcuts

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. 

7 

8"""C-squared population analysis.""" 

9 

10import random 

11 

12import numpy 

13 

14from cclib.method.population import Population 

15 

16 

17class CSPA(Population): 

18 """The C-squared population analysis.""" 

19 

20 # Overlaps are not required for CSPA. 

21 overlap_attributes = () 

22 

23 def __init__(self, *args): 

24 

25 # Call the __init__ method of the superclass. 

26 super(CSPA, self).__init__(logname="CSPA", *args) 

27 

28 def __str__(self): 

29 """Return a string representation of the object.""" 

30 return "CSPA of %s" % (self.data) 

31 

32 def __repr__(self): 

33 """Return a representation of the object.""" 

34 return 'CSPA("%s")' % (self.data) 

35 

36 def calculate(self, indices=None, fupdate=0.05): 

37 """Perform the C squared population analysis. 

38 

39 Inputs: 

40 indices - list of lists containing atomic orbital indices of fragments 

41 """ 

42 self.logger.info("Creating attribute aoresults: array[3]") 

43 

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 

55 

56 # Intialize progress if available. 

57 if self.progress: 

58 self.progress.initialize(nstep) 

59 

60 step = 0 

61 for spin in range(len(self.data.mocoeffs)): 

62 

63 for i in range(len(self.data.mocoeffs[spin])): 

64 

65 if self.progress and random.random() < fupdate: 

66 self.progress.update(step, "C^2 Population Analysis") 

67 

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") 

73 

74 step += 1 

75 

76 if self.progress: 

77 self.progress.update(nstep, "Done") 

78 

79 retval = super(CSPA, self).partition(indices) 

80 

81 if not retval: 

82 self.logger.error("Error in partitioning results") 

83 return False 

84 

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") 

91 

92 for spin in range(len(self.fragresults)): 

93 

94 for i in range(self.data.homos[spin] + 1): 

95 

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) 

102 

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) 

108 

109 return True