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) 2017, 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"""Building the density matrix from data parsed by cclib.""" 

9 

10import logging 

11import random 

12 

13import numpy 

14 

15from cclib.method.calculationmethod import Method 

16 

17 

18class Density(Method): 

19 """Calculate the density matrix""" 

20 def __init__(self, data, progress=None, loglevel=logging.INFO, 

21 logname="Density"): 

22 

23 # Call the __init__ method of the superclass. 

24 super(Density, self).__init__(data, progress, loglevel, logname) 

25 

26 def __str__(self): 

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

28 return "Density matrix of %s" % (self.data) 

29 

30 def __repr__(self): 

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

32 return 'Density matrix("%s")' % (self.data) 

33 

34 def calculate(self, fupdate=0.05): 

35 """Calculate the density matrix.""" 

36 

37 # Do we have the needed info in the data object? 

38 if not hasattr(self.data, "mocoeffs"): 

39 self.logger.error("Missing mocoeffs") 

40 return False 

41 if not hasattr(self.data,"nbasis"): 

42 self.logger.error("Missing nbasis") 

43 return False 

44 if not hasattr(self.data,"homos"): 

45 self.logger.error("Missing homos") 

46 return False 

47 

48 self.logger.info("Creating attribute density: array[3]") 

49 size = self.data.nbasis 

50 unrestricted = (len(self.data.mocoeffs) == 2) 

51 

52 #determine number of steps, and whether process involves beta orbitals 

53 nstep = self.data.homos[0] + 1 

54 if unrestricted: 

55 self.density = numpy.zeros([2, size, size], "d") 

56 nstep += self.data.homos[1] + 1 

57 else: 

58 self.density = numpy.zeros([1, size, size], "d") 

59 

60 #intialize progress if available 

61 if self.progress: 

62 self.progress.initialize(nstep) 

63 

64 step = 0 

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

66 

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

68 

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

70 self.progress.update(step, "Density Matrix") 

71 

72 col = numpy.reshape(self.data.mocoeffs[spin][i], (size, 1)) 

73 colt = numpy.reshape(col, (1, size)) 

74 

75 tempdensity = numpy.dot(col, colt) 

76 self.density[spin] = numpy.add(self.density[spin], 

77 tempdensity) 

78 

79 step += 1 

80 

81 if not unrestricted: #multiply by two to account for second electron 

82 self.density[0] = numpy.add(self.density[0], self.density[0]) 

83 

84 if self.progress: 

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

86 

87 return True #let caller know we finished density