Пример #1
0
    def initialize(self):

        self.ini = True

        BASECHI.initialize(self)

        self.txtname = self.gwtxtname
        self.output_init()

        self.printtxt('GPAW version %s' % (version))
        self.printtxt('-----------------------------------------------')
        self.printtxt('GW calculation started at:')
        self.printtxt(ctime())
        self.printtxt('-----------------------------------------------')
        self.starttime = time()

        calc = self.calc
        kd = self.kd

        # band init
        if self.gwnbands is None:
            if self.npw > calc.wfs.bd.nbands:
                self.nbands = calc.wfs.bd.nbands
            else:
                self.nbands = self.npw

        # eigenvalue init
        if self.user_skn is not None:
            self.printtxt('Use eigenvalues from user.')
            assert np.shape(
                self.user_skn
            )[0] == self.nspins, 'Eigenvalues not compatible with .gpw file!'
            assert np.shape(
                self.user_skn
            )[1] == self.kd.nibzkpts, 'Eigenvalues not compatible with .gpw file!'
            assert np.shape(
                self.user_skn)[2] >= self.nbands, 'Too few eigenvalues!'
            self.e_skn = self.user_skn
        else:
            self.printtxt('Use eigenvalues from the calculator.')

        # q point init
        self.bzq_kc = kd.get_bz_q_points()
        self.ibzq_qc = self.bzq_kc  # q point symmetry is not used at the moment.
        self.nqpt = np.shape(self.bzq_kc)[0]

        # frequency points init
        self.static = False

        if self.ppa:  # Plasmon Pole Approximation
            if self.E0 is None:
                self.E0 = Hartree
            self.E0 /= Hartree
            self.w_w = np.array([0., 1j * self.E0])
            self.hilbert_trans = False
            self.wpar = 1
        elif self.w_w is None:  # static COHSEX
            self.w_w = np.array([0.])
            self.static = True
            self.hilbert_trans = False
            self.wpar = 1
            self.eta = 0.0001 / Hartree
        else:
            # create nonlinear frequency grid
            # grid is linear from 0 to wcut with spacing dw
            # spacing is linearily increasing between wcut and wmax
            # Hilbert transforms are still carried out on linear grid
            wcut = self.w_w[0]
            wmax = self.w_w[1]
            dw = self.w_w[2]
            w_w = np.linspace(0., wcut, wcut / dw + 1)
            i = 1
            wi = wcut
            while wi < wmax:
                wi += i * dw
                w_w = np.append(w_w, wi)
                i += 1
            while len(w_w) % self.wpar != 0:
                wi += i * dw
                w_w = np.append(w_w, wi)
                i += 1

            dw_w = np.zeros(len(w_w))
            dw_w[0] = dw
            dw_w[1:] = w_w[1:] - w_w[:-1]

            self.w_w = w_w / Hartree
            self.dw_w = dw_w / Hartree
            self.eta_w = dw_w * 4 / Hartree
            self.wcut = wcut

            self.wmax = self.w_w[-1]
            self.wmin = self.w_w[0]
            self.dw = self.w_w[1] - self.w_w[0]
            self.Nw = len(self.w_w)
            #            self.wpar = int(self.Nw * self.npw**2 * 16. / 1024**2) // 1500 + 1 # estimate memory and parallelize over frequencies

            for s in range(self.nspins):
                emaxdiff = self.e_skn[s][:, self.nbands -
                                         1].max() - self.e_skn[s][:, 0].min()
                assert (self.wmax > emaxdiff
                        ), 'Maximum frequency must be larger than %f' % (
                            emaxdiff * Hartree)

        # GW kpoints init
        if self.kpoints is None:
            self.gwnkpt = self.kd.nibzkpts
            self.gwkpt_k = kd.ibz2bz_k
        else:
            self.gwnkpt = np.shape(self.kpoints)[0]
            self.gwkpt_k = self.kpoints

        # GW bands init
        if self.bands is None:
            self.gwnband = self.nbands
            self.bands = self.gwbands_n = np.arange(self.nbands)
        else:
            self.gwnband = np.shape(self.bands)[0]
            self.gwbands_n = self.bands

        self.alpha = 1j / (2 * pi * self.vol * self.kd.nbzkpts)

        # parallel init
        assert len(self.w_w) % self.wpar == 0
        self.wcommsize = self.wpar
        self.qcommsize = size // self.wpar
        assert self.qcommsize * self.wcommsize == size, 'wpar must be integer divisor of number of requested cores'
        if self.nqpt != 1:  # parallelize over q-points
            self.wcomm, self.qcomm, self.worldcomm = set_communicator(
                world, rank, size, self.wpar)
            self.ncomm = serial_comm
            self.dfcomm = self.wcomm
            self.kcommsize = 1
        else:  # parallelize over bands
            self.wcomm, self.ncomm, self.worldcomm = set_communicator(
                world, rank, size, self.wpar)
            self.qcomm = serial_comm
            if self.wpar > 1:
                self.dfcomm = self.wcomm
                self.kcommsize = 1
            else:
                self.dfcomm = self.ncomm
                self.kcommsize = self.ncomm.size
        nq, self.nq_local, self.q_start, self.q_end = parallel_partition(
            self.nqpt, self.qcomm.rank, self.qcomm.size, reshape=False)
        nb, self.nbands_local, self.m_start, self.m_end = parallel_partition(
            self.nbands, self.ncomm.rank, self.ncomm.size, reshape=False)
Пример #2
0
    def parallel_init(self):
        """Parallel initialization. By default, only use kcomm and wcomm.

        Parameters:

            kcomm:
                 kpoint communicator
            wScomm:
                 spectral function communicator
            wcomm:
                 frequency communicator
        """

        if extra_parameters.get("df_dry_run"):
            from gpaw.mpi import DryRunCommunicator

            size = extra_parameters["df_dry_run"]
            world = DryRunCommunicator(size)
            rank = world.rank
            self.comm = world
        else:
            world = self.comm
            rank = self.comm.rank
            size = self.comm.size

        wcommsize = int(self.NwS * self.npw ** 2 * 16.0 / 1024 ** 2) // 1500  # megabyte
        wcommsize += 1
        if size < wcommsize:
            raise ValueError("Number of cpus are not enough ! ")
        if self.kcommsize is None:
            self.kcommsize = world.size
        if wcommsize > size // self.kcommsize:  # if matrix too large, overwrite kcommsize and distribute matrix
            self.printtxt("kcommsize is over written ! ")
            while size % wcommsize != 0:
                wcommsize += 1
            self.kcommsize = size // wcommsize
            assert self.kcommsize * wcommsize == size
            if self.kcommsize < 1:
                raise ValueError("Number of cpus are not enough ! ")

        self.kcomm, self.wScomm, self.wcomm = set_communicator(world, rank, size, self.kcommsize)

        if self.kd.nbzkpts >= world.size:
            self.nkpt_reshape = self.kd.nbzkpts
            self.nkpt_reshape, self.nkpt_local, self.kstart, self.kend = parallel_partition(
                self.nkpt_reshape, self.kcomm.rank, self.kcomm.size, reshape=True, positive=True
            )
            self.mband_local = self.nvalbands
            self.mlist = np.arange(self.nbands)
        else:
            # if number of kpoints == 1, use band parallelization
            self.nkpt_local = self.kd.nbzkpts
            self.kstart = 0
            self.kend = self.kd.nbzkpts
            self.nkpt_reshape = self.kd.nbzkpts

            self.nbands, self.mband_local, self.mlist = parallel_partition_list(
                self.nbands, self.kcomm.rank, self.kcomm.size
            )

        if self.NwS % size != 0:
            self.NwS -= self.NwS % size

        self.NwS, self.NwS_local, self.wS1, self.wS2 = parallel_partition(
            self.NwS, self.wScomm.rank, self.wScomm.size, reshape=False
        )

        if self.hilbert_trans:
            self.Nw, self.Nw_local, self.wstart, self.wend = parallel_partition(
                self.Nw, self.wcomm.rank, self.wcomm.size, reshape=True
            )
        else:
            if self.Nw > 1:
                #                assert self.Nw % (self.comm.size / self.kcomm.size) == 0
                self.wcomm = self.wScomm
                self.Nw, self.Nw_local, self.wstart, self.wend = parallel_partition(
                    self.Nw, self.wcomm.rank, self.wcomm.size, reshape=False
                )
            else:
                # if frequency point is too few, then dont parallelize
                self.wcomm = serial_comm
                self.wstart = 0
                self.wend = self.Nw
                self.Nw_local = self.Nw

        return
Пример #3
0
    def initialize(self):

        self.ini = True

        BASECHI.initialize(self)

        self.txtname = self.gwtxtname
        self.output_init()

        self.printtxt('GPAW version %s' %(version))
        self.printtxt('-----------------------------------------------')
        self.printtxt('GW calculation started at:')
        self.printtxt(ctime())
        self.printtxt('-----------------------------------------------')
        self.starttime = time()

        calc = self.calc
        kd = self.kd

        # band init
        if self.gwnbands is None:
            if self.npw > calc.wfs.bd.nbands:
                self.nbands = calc.wfs.bd.nbands
            else:
                self.nbands = self.npw

        # eigenvalue init
        if self.user_skn is not None:
            self.printtxt('Use eigenvalues from user.')
            assert np.shape(self.user_skn)[0] == self.nspins, 'Eigenvalues not compatible with .gpw file!'
            assert np.shape(self.user_skn)[1] == self.kd.nibzkpts, 'Eigenvalues not compatible with .gpw file!'
            assert np.shape(self.user_skn)[2] >= self.nbands, 'Too few eigenvalues!'
            self.e_skn = self.user_skn
        else:
            self.printtxt('Use eigenvalues from the calculator.')

        # q point init
        self.bzq_kc = kd.get_bz_q_points()
        self.ibzq_qc = self.bzq_kc # q point symmetry is not used at the moment.
        self.nqpt = np.shape(self.bzq_kc)[0]
        
        # frequency points init
        self.static=False

        if self.ppa: # Plasmon Pole Approximation
            if self.E0 is None:
                self.E0 = Hartree
            self.E0 /= Hartree
            self.w_w = np.array([0., 1j*self.E0])
            self.hilbert_trans=False
            self.wpar=1
        elif self.w_w is None: # static COHSEX
            self.w_w = np.array([0.])
            self.static=True
            self.hilbert_trans=False
            self.wpar=1
            self.eta = 0.0001 / Hartree
        else:
            # create nonlinear frequency grid
            # grid is linear from 0 to wcut with spacing dw
            # spacing is linearily increasing between wcut and wmax
            # Hilbert transforms are still carried out on linear grid
            wcut = self.w_w[0]
            wmax = self.w_w[1]
            dw = self.w_w[2]
            w_w = np.linspace(0., wcut, wcut/dw+1)
            i=1
            wi=wcut
            while wi < wmax:
                wi += i*dw
                w_w = np.append(w_w, wi)
                i+=1
            while len(w_w) % self.wpar != 0:
                wi += i*dw
                w_w = np.append(w_w, wi)
                i+=1

            dw_w = np.zeros(len(w_w))
            dw_w[0] = dw
            dw_w[1:] = w_w[1:] - w_w[:-1]

            self.w_w = w_w / Hartree
            self.dw_w = dw_w / Hartree
            self.eta_w = dw_w * 4 / Hartree
            self.wcut = wcut

            self.wmax = self.w_w[-1]
            self.wmin = self.w_w[0]
            self.dw = self.w_w[1] - self.w_w[0]
            self.Nw = len(self.w_w)
#            self.wpar = int(self.Nw * self.npw**2 * 16. / 1024**2) // 1500 + 1 # estimate memory and parallelize over frequencies

            for s in range(self.nspins):
                emaxdiff = self.e_skn[s][:,self.nbands-1].max() - self.e_skn[s][:,0].min()
                assert (self.wmax > emaxdiff), 'Maximum frequency must be larger than %f' %(emaxdiff*Hartree)

        # GW kpoints init
        if self.kpoints is None:
            self.gwnkpt = self.kd.nibzkpts
            self.gwkpt_k = kd.ibz2bz_k
        else:
            self.gwnkpt = np.shape(self.kpoints)[0]
            self.gwkpt_k = self.kpoints

        # GW bands init
        if self.bands is None:
            self.gwnband = self.nbands
            self.bands = self.gwbands_n = np.arange(self.nbands)
        else:
            self.gwnband = np.shape(self.bands)[0]
            self.gwbands_n = self.bands

        self.alpha = 1j/(2*pi * self.vol * self.kd.nbzkpts)
        
        # parallel init
        assert len(self.w_w) % self.wpar == 0
        self.wcommsize = self.wpar
        self.qcommsize = size // self.wpar
        assert self.qcommsize * self.wcommsize == size, 'wpar must be integer divisor of number of requested cores'
        if self.nqpt != 1: # parallelize over q-points
            self.wcomm, self.qcomm, self.worldcomm = set_communicator(world, rank, size, self.wpar)
            self.ncomm = serial_comm
            self.dfcomm = self.wcomm
            self.kcommsize = 1
        else: # parallelize over bands
            self.wcomm, self.ncomm, self.worldcomm = set_communicator(world, rank, size, self.wpar)
            self.qcomm = serial_comm
            if self.wpar > 1:
                self.dfcomm = self.wcomm
                self.kcommsize = 1
            else:
                self.dfcomm = self.ncomm
                self.kcommsize = self.ncomm.size
        nq, self.nq_local, self.q_start, self.q_end = parallel_partition(
                                  self.nqpt, self.qcomm.rank, self.qcomm.size, reshape=False)
        nb, self.nbands_local, self.m_start, self.m_end = parallel_partition(
                                  self.nbands, self.ncomm.rank, self.ncomm.size, reshape=False)
Пример #4
0
    def parallel_init(self):
        """Parallel initialization. By default, only use kcomm and wcomm.

        Parameters:

            kcomm:
                 kpoint communicator
            wScomm:
                 spectral function communicator
            wcomm:
                 frequency communicator
        """

        if extra_parameters.get('df_dry_run'):
            from gpaw.mpi import DryRunCommunicator
            size = extra_parameters['df_dry_run']
            world = DryRunCommunicator(size)
            rank = world.rank
            self.comm = world
        else:
            world = self.comm
            rank = self.comm.rank
            size = self.comm.size

        wcommsize = int(self.NwS * self.npw**2 * 16. / 1024**2) // 1500 # megabyte
        wcommsize += 1
        if size < wcommsize:
            raise ValueError('Number of cpus are not enough ! ')
        if self.kcommsize is None:
            self.kcommsize = world.size
        if wcommsize > size // self.kcommsize: # if matrix too large, overwrite kcommsize and distribute matrix
            self.printtxt('kcommsize is over written ! ')
            while size % wcommsize != 0:
                wcommsize += 1
            self.kcommsize = size // wcommsize
            assert self.kcommsize * wcommsize == size
            if self.kcommsize < 1:
                raise ValueError('Number of cpus are not enough ! ')

        self.kcomm, self.wScomm, self.wcomm = set_communicator(world, rank, size, self.kcommsize)

        if self.kd.nbzkpts >= world.size:
            self.nkpt_reshape = self.kd.nbzkpts
            self.nkpt_reshape, self.nkpt_local, self.kstart, self.kend = parallel_partition(
                               self.nkpt_reshape, self.kcomm.rank, self.kcomm.size, reshape=True, positive=True)
            self.mband_local = self.nvalbands
            self.mlist = np.arange(self.nbands)
        else:
            # if number of kpoints == 1, use band parallelization
            self.nkpt_local = self.kd.nbzkpts
            self.kstart = 0
            self.kend = self.kd.nbzkpts
            self.nkpt_reshape = self.kd.nbzkpts

            self.nbands, self.mband_local, self.mlist = parallel_partition_list(
                               self.nbands, self.kcomm.rank, self.kcomm.size)

        if self.NwS % size != 0:
            self.NwS -= self.NwS % size
            
        self.NwS, self.NwS_local, self.wS1, self.wS2 = parallel_partition(
                               self.NwS, self.wScomm.rank, self.wScomm.size, reshape=False)

        if self.hilbert_trans:
            self.Nw, self.Nw_local, self.wstart, self.wend =  parallel_partition(
                               self.Nw, self.wcomm.rank, self.wcomm.size, reshape=True)
        else:
            if self.Nw > 1:
#                assert self.Nw % (self.comm.size / self.kcomm.size) == 0
                self.wcomm = self.wScomm
                self.Nw, self.Nw_local, self.wstart, self.wend =  parallel_partition(
                               self.Nw, self.wcomm.rank, self.wcomm.size, reshape=False)
            else:
                # if frequency point is too few, then dont parallelize
                self.wcomm = serial_comm
                self.wstart = 0
                self.wend = self.Nw
                self.Nw_local = self.Nw

        return
Пример #5
0
    def get_rpa_correlation_energy(self,
                                   kcommsize=None,
                                   dfcommsize=world.size,
                                   directions=None,
                                   skip_gamma=False,
                                   ecut=10,
                                   nbands=None,
                                   gauss_legendre=None,
                                   frequency_cut=None,
                                   frequency_scale=None,
                                   w=None,
                                   restart=None):
            
        self.initialize_calculation(w,
                                    ecut,
                                    nbands,
                                    kcommsize,
                                    gauss_legendre,
                                    frequency_cut,
                                    frequency_scale)

        if dfcommsize == world.size:
            self.dfcomm = world
            E_q = []
            if restart is not None:
                assert type(restart) is str
                try:
                    f = paropen(restart, 'r')
                    lines = f.readlines()
                    for line in lines:
                        E_q.append(eval(line))
                    f.close()
                    print >> self.txt, 'Correlation energy obtained ' \
                          +'from %s q-points obtained from restart file: ' \
                          % len(E_q), restart
                    print >> self.txt
                except:
                    IOError
    
            for index, q in zip(range(len(E_q), len(self.ibz_q_points)),
                                self.ibz_q_points[len(E_q):]):
                if abs(np.dot(q, q))**0.5 < 1.e-5:
                    E_q0 = 0.
                    if skip_gamma:
                        print >> self.txt, \
                              'Not calculating q at the Gamma point'
                        print >> self.txt
                    else:
                        if directions is None:
                            directions = [[0, 1/3.], [1, 1/3.], [2, 1/3.]]
                        for d in directions:                                   
                            E_q0 += self.E_q(q,
                                             index=index,
                                             direction=d[0]) * d[1]
                    E_q.append(E_q0)
                else:
                    E_q.append(self.E_q(q, index=index))
                    
                if restart is not None:
                    f = paropen(restart, 'a')
                    print >> f, E_q[-1]
                    f.close()
    
            E = np.dot(np.array(self.q_weights), np.array(E_q).real)

        else: # parallelzation over q points
            print >> self.txt, 'parallelization over q point ! '
            # creates q list
            qlist = []
            qweight = []
            id = 0
            for iq, q in enumerate(self.ibz_q_points):
                if abs(np.dot(q, q))**0.5 < 1.e-5:
                    if skip_gamma:
                        continue
                    else:
                        if directions is None:
                            directions = [[0, 1/3.], [1, 1/3.], [2, 1/3.]]
                        for d in directions:
                            qlist.append((id, q, d[0], d[1]))
                            qweight.append(self.q_weights[iq])
                            id += 1
                        continue
                qlist.append((id, q, 0, 1))
                qweight.append(self.q_weights[iq])
                id += 1
            nq = len(qlist)
    
            # distribute q list
            self.dfcomm, qcomm = set_communicator(world,
                                                  world.rank,
                                                  world.size,
                                                  kcommsize=dfcommsize)[:2]
            nq, nq_local, qlist_local = parallel_partition_list(nq,
                                                              qcomm.rank,
                                                              qcomm.size)
    
            E_q = np.zeros(nq)
            
            for iq in qlist_local:
                try:
                    ff = open('E_q_%s_%s.dat' %(self.tag,iq), 'r')
                    E_q[iq] = ff.readline().split()[-2]
                    print >> self.txt, 'Reading E_q[%s] '%(iq), E_q[iq] 
                except:
                    E_q[iq] = self.E_q(qlist[iq][1],
                                   index=iq,
                                   direction=qlist[iq][2]) * qlist[iq][3]

                    if self.tag is not None and self.dfcomm.rank == 0:
                        ff = open('E_q_%s_%s.dat' %(self.tag,iq), 'a')
                        print >> ff, qlist[iq][1:4], E_q[iq], qweight[iq]
                        ff.close()
                    
            qcomm.sum(E_q)

            print >> self.txt, '(q, direction, weight), E_q, qweight'
            for iq in range(nq):
                print >> self.txt, qlist[iq][1:4], E_q[iq], qweight[iq]
                
            E = np.dot(np.array(qweight), np.array(E_q))

        print >> self.txt, 'RPA correlation energy:'
        print >> self.txt, 'E_c = %s eV' % E
        print >> self.txt
        print >> self.txt, 'Calculation completed at:  ', ctime()
        print >> self.txt
        print >> self.txt, \
              '------------------------------------------------------'
        print >> self.txt
        return E
Пример #6
0
    def get_rpa_correlation_energy(self,
                                   kcommsize=None,
                                   dfcommsize=world.size,
                                   directions=None,
                                   skip_gamma=False,
                                   ecut=10,
                                   nbands=None,
                                   gauss_legendre=None,
                                   frequency_cut=None,
                                   frequency_scale=None,
                                   w=None,
                                   restart=None):

        self.initialize_calculation(w, ecut, nbands, kcommsize, gauss_legendre,
                                    frequency_cut, frequency_scale)

        if dfcommsize == world.size:
            self.dfcomm = world
            E_q = []
            if restart is not None:
                assert type(restart) is str
                try:
                    f = paropen(restart, 'r')
                    lines = f.readlines()
                    for line in lines:
                        E_q.append(eval(line))
                    f.close()
                    print('Correlation energy obtained ' \
                          +'from %s q-points obtained from restart file: ' \
                          % len(E_q), restart, file=self.txt)
                    print(file=self.txt)
                except:
                    IOError

            for index, q in zip(range(len(E_q), len(self.ibz_q_points)),
                                self.ibz_q_points[len(E_q):]):
                if abs(np.dot(q, q))**0.5 < 1.e-5:
                    E_q0 = 0.
                    if skip_gamma:
                        print('Not calculating q at the Gamma point',
                              file=self.txt)
                        print(file=self.txt)
                    else:
                        if directions is None:
                            directions = [[0, 1 / 3.], [1, 1 / 3.],
                                          [2, 1 / 3.]]
                        for d in directions:
                            E_q0 += self.E_q(q, index=index,
                                             direction=d[0]) * d[1]
                    E_q.append(E_q0)
                else:
                    E_q.append(self.E_q(q, index=index))

                if restart is not None:
                    f = paropen(restart, 'a')
                    print(E_q[-1], file=f)
                    f.close()

            E = np.dot(np.array(self.q_weights), np.array(E_q).real)

        else:  # parallelzation over q points
            print('parallelization over q point ! ', file=self.txt)
            # creates q list
            qlist = []
            qweight = []
            id = 0
            for iq, q in enumerate(self.ibz_q_points):
                if abs(np.dot(q, q))**0.5 < 1.e-5:
                    if skip_gamma:
                        continue
                    else:
                        if directions is None:
                            directions = [[0, 1 / 3.], [1, 1 / 3.],
                                          [2, 1 / 3.]]
                        for d in directions:
                            qlist.append((id, q, d[0], d[1]))
                            qweight.append(self.q_weights[iq])
                            id += 1
                        continue
                qlist.append((id, q, 0, 1))
                qweight.append(self.q_weights[iq])
                id += 1
            nq = len(qlist)

            # distribute q list
            self.dfcomm, qcomm = set_communicator(world,
                                                  world.rank,
                                                  world.size,
                                                  kcommsize=dfcommsize)[:2]
            nq, nq_local, qlist_local = parallel_partition_list(
                nq, qcomm.rank, qcomm.size)

            E_q = np.zeros(nq)

            for iq in qlist_local:
                try:
                    ff = open('E_q_%s_%s.dat' % (self.tag, iq), 'r')
                    E_q[iq] = ff.readline().split()[-2]
                    print('Reading E_q[%s] ' % (iq), E_q[iq], file=self.txt)
                except:
                    E_q[iq] = self.E_q(qlist[iq][1],
                                       index=iq,
                                       direction=qlist[iq][2]) * qlist[iq][3]

                    if self.tag is not None and self.dfcomm.rank == 0:
                        ff = open('E_q_%s_%s.dat' % (self.tag, iq), 'a')
                        print(qlist[iq][1:4], E_q[iq], qweight[iq], file=ff)
                        ff.close()

            qcomm.sum(E_q)

            print('(q, direction, weight), E_q, qweight', file=self.txt)
            for iq in range(nq):
                print(qlist[iq][1:4], E_q[iq], qweight[iq], file=self.txt)

            E = np.dot(np.array(qweight), np.array(E_q))

        print('RPA correlation energy:', file=self.txt)
        print('E_c = %s eV' % E, file=self.txt)
        print(file=self.txt)
        print('Calculation completed at:  ', ctime(), file=self.txt)
        print(file=self.txt)
        print('------------------------------------------------------',
              file=self.txt)
        print(file=self.txt)
        return E