def __init__(self, psi):
        self.__Base.__init__(self, psi)
        self.Rank = psi.GetRank()
        self.PotentialList = []
        self.CutOff = 0.0

        #Need a wavefunction for later
        self.Psi = self.psi.Copy()

        self.Logger = GetClassLogger(self)
Esempio n. 2
0
	def __init__(self, psi):
		self.__Base.__init__(self, psi)
		self.Rank = psi.GetRank()
		self.PotentialList = []
		self.CutOff = 0.0

		#Need a wavefunction for later
		self.Psi = self.psi.Copy()

		self.Logger = GetClassLogger(self)
Esempio n. 3
0
	def __init__(self, conf, propagationTasks, numberOfCallbacks):
		self.Logger = GetClassLogger(self)
		self.PropagationTasks = propagationTasks
		self.Config = conf
		self.NumberOfCallbacks = numberOfCallbacks

		#setup Pyprop problem from config
		self.Problem = pyprop.Problem(self.Config)
		self.Problem.SetupStep()

		self.PreProcessed = False
Esempio n. 4
0
class BasisPropagatorEpetra(BasisPropagator):
	"""
	EpetraPropagator uses Trilinos::Epetra matrices to store potential matrices in
	a basis representation, and perform matrix-vector (potential-wavefunction) 
	multiplications with these. 
	
	Apart from this it is very similar to BasisPropagator, and uses TensorPotential
	to set up the potential matrices.
	"""

	__Base = BasisPropagator

	def __init__(self, psi):
		self.__Base.__init__(self, psi)
		self.Rank = psi.GetRank()
		self.PotentialList = []
		self.CutOff = 0.0

		#Need a wavefunction for later
		self.Psi = self.psi.Copy()

		self.Logger = GetClassLogger(self)


	def GeneratePotentials(self, config):
		"""
		Generate TensorPotentials from potentials specified on the grid in the
		configuration file. Then consolidate/copy into Epetra matrices.
		"""

		#Potentials we should create on the fly
		if hasattr(config.Propagation, "grid_potential_list"):
			potentials = config.Propagation.grid_potential_list

			for potentialName in potentials:
				#Find the corresponding config section
				configSection = config.GetSection(potentialName)

				#generate potential 
				tensorPot = self.GeneratePotential(configSection)
				localBasisPairs = [geom.GetBasisPairs() for geom in tensorPot.GeometryList]

				#Setup a new Epetra potential
				epetraPot = EpetraPotential(self.Psi)
				epetraPot.ApplyConfigSection(configSection)

				#check if current potential can be consolidated with an existing one
				for existingPot in self.PotentialList:
					if existingPot.CanConsolidate(epetraPot):
						self.Logger.debug("Consolidating %s" % epetraPot.Name)
						existingPot.AddTensorPotentialData(tensorPot.PotentialData, localBasisPairs, self.CutOff)
						existingPot.Name += "+" + tensorPot.Name
						tensorPot = None
						epetraPot = None
						break
						
				#add new potential to list
				if epetraPot != None:
					self.Logger.debug("New epetra potential %s" % epetraPot.Name)
					epetraPot.AddTensorPotentialData(tensorPot.PotentialData, localBasisPairs, self.CutOff)
					self.PotentialList.append(epetraPot)
					tensorPot = None

			#Global assemble all potentials
			for pot in self.PotentialList:
				pot.GlobalAssemble()

	
	def MultiplyHamiltonianBalancedOverlap(self, srcPsi, destPsi, t, dt):
		raise NotImplementedException("BasisPropagatorEpetra does not support MultiplyHamiltonianBalancedOverlap!")

	def MultiplyPotential(self, srcPsi, destPsi, t, dt):
		self.Psi.Clear()
		if dt == None:
			dt = self.TimeStep

		for potential in self.PotentialList:
			self.Psi.Clear()
			potential.MultiplyPotential(srcPsi, self.Psi, t, dt)
			destPsi.GetData()[:] += self.Psi.GetData()
class BasisPropagatorEpetra(BasisPropagator):
    """
	EpetraPropagator uses Trilinos::Epetra matrices to store potential matrices in
	a basis representation, and perform matrix-vector (potential-wavefunction) 
	multiplications with these. 
	
	Apart from this it is very similar to BasisPropagator, and uses TensorPotential
	to set up the potential matrices.
	"""

    __Base = BasisPropagator

    def __init__(self, psi):
        self.__Base.__init__(self, psi)
        self.Rank = psi.GetRank()
        self.PotentialList = []
        self.CutOff = 0.0

        #Need a wavefunction for later
        self.Psi = self.psi.Copy()

        self.Logger = GetClassLogger(self)

    def GeneratePotentials(self, config):
        """
		Generate TensorPotentials from potentials specified on the grid in the
		configuration file. Then consolidate/copy into Epetra matrices.
		"""

        #Potentials we should create on the fly
        if hasattr(config.Propagation, "grid_potential_list"):
            potentials = config.Propagation.grid_potential_list

            for potentialName in potentials:
                #Find the corresponding config section
                configSection = config.GetSection(potentialName)

                #generate potential
                tensorPot = self.GeneratePotential(configSection)
                localBasisPairs = [
                    geom.GetBasisPairs() for geom in tensorPot.GeometryList
                ]

                #Setup a new Epetra potential
                epetraPot = EpetraPotential(self.Psi)
                epetraPot.ApplyConfigSection(configSection)

                #check if current potential can be consolidated with an existing one
                for existingPot in self.PotentialList:
                    if existingPot.CanConsolidate(epetraPot):
                        self.Logger.debug("Consolidating %s" % epetraPot.Name)
                        existingPot.AddTensorPotentialData(
                            tensorPot.PotentialData, localBasisPairs,
                            self.CutOff)
                        existingPot.Name += "+" + tensorPot.Name
                        tensorPot = None
                        epetraPot = None
                        break

                #add new potential to list
                if epetraPot != None:
                    self.Logger.debug("New epetra potential %s" %
                                      epetraPot.Name)
                    epetraPot.AddTensorPotentialData(tensorPot.PotentialData,
                                                     localBasisPairs,
                                                     self.CutOff)
                    self.PotentialList.append(epetraPot)
                    tensorPot = None

            #Global assemble all potentials
            for pot in self.PotentialList:
                pot.GlobalAssemble()

    def MultiplyHamiltonianBalancedOverlap(self, srcPsi, destPsi, t, dt):
        raise NotImplementedException(
            "BasisPropagatorEpetra does not support MultiplyHamiltonianBalancedOverlap!"
        )

    def MultiplyPotential(self, srcPsi, destPsi, t, dt):
        self.Psi.Clear()
        if dt == None:
            dt = self.TimeStep

        for potential in self.PotentialList:
            self.Psi.Clear()
            potential.MultiplyPotential(srcPsi, self.Psi, t, dt)
            destPsi.GetData()[:] += self.Psi.GetData()
Esempio n. 6
0
	def __init__(self, storeProgressInfo=True):
		self.StoreProgressInfo = storeProgressInfo
		self.Logger = GetClassLogger(self)
		self.StartTime = -1
		self.InitialPsi = None
		self.ProgressItems = {}
Esempio n. 7
0
class ProgressReport(PropagationTask):
	"""
	Print some progress information during propagation, and store it
	in a HDF5-file when finished (time, norm and projection on initial state)
	"""

	def __init__(self, storeProgressInfo=True):
		self.StoreProgressInfo = storeProgressInfo
		self.Logger = GetClassLogger(self)
		self.StartTime = -1
		self.InitialPsi = None
		self.ProgressItems = {}

	def setupTask(self, prop):
		self.Logger.info("Setting up task...")
		self.StartTime = time.time()
		self.InitialPsi = prop.psi.Copy()
	
		#check if output dir exist, create if not
		if self.StoreProgressInfo:
			self.OutputFileName = prop.Config.Names.output_file_name
			CreatePath(self.OutputFileName)
		
		#Report items
		self.ProgressItems["SampleTimes"] = []
		self.ProgressItems["Norm"] = []
		self.ProgressItems["InitialCorrelation"] = []

	def callback(self, prop):
		t = prop.PropagatedTime
		T = prop.Duration + prop.StartTime
		norm = prop.psi.GetNorm()
		corr = abs(prop.psi.InnerProduct(self.InitialPsi))**2
		eta = self.__EstimateETA(prop)
		self.ProgressItems["SampleTimes"] += [t]
		self.ProgressItems["Norm"] += [norm]
		self.ProgressItems["InitialCorrelation"] += [corr]
		#FormatDuration = lambda t: time.strftime("%Hh %Mm %Ss", time.gmtime(t))
		#FormatDuration = lambda t: time.strftime("%dd %Hh %Mm %Ss", time.gmtime(t))
		PrintOut("t = %.2f / %.2f; N = %.15f; Corr = %.12f, ETA = %s" % (t, T, norm, corr, self._FormatDuration(eta)))

	def postProcess(self, prop):
		"""
		Store problem information collected during propagation
		"""
		if self.StoreProgressInfo and (pyprop.ProcId == 0):
			with tables.openFile(self.OutputFileName, "a") as h5file:
				for itemName, itemVal in self.ProgressItems.iteritems():
					if itemName in h5file.root:
						h5file.removeNode(h5file.root, itemName, recursive=True)
					h5file.createArray("/", itemName, itemVal)


	def __EstimateETA(self, prop):
		"""
		Estimates remaining time before propagation is finished
		"""
		curTime = time.time() - self.StartTime
		#totalTime = (curTime / prop.PropagatedTime) * prop.Duration
		totalTime = (curTime / (prop.PropagatedTime - prop.StartTime)) * prop.Duration
		eta = totalTime - curTime
		return eta

	def _FormatDuration(self, t):
		days, remainder = divmod(t, 24 * 60 * 60)
		hours, remainder = divmod(remainder, 60 * 60)
		minutes, seconds = divmod(remainder, 60)
		if days > 0:
			timeStr = "%id %ih" % (days, hours)
		elif hours > 0:
			timeStr = "%ih %im" % (hours, minutes)
		else:
			timeStr = "%im %is" % (minutes, seconds)
			
		return timeStr
Esempio n. 8
0
class Propagate:
	"""
	Setup and run a Pyprop problem.
	
	Propagate wavefunction from	T_start to T_end. Also perform
	all given PropagationTasks during the propagation phase.

	"""
	def __init__(self, conf, propagationTasks, numberOfCallbacks):
		self.Logger = GetClassLogger(self)
		self.PropagationTasks = propagationTasks
		self.Config = conf
		self.NumberOfCallbacks = numberOfCallbacks

		#setup Pyprop problem from config
		self.Problem = pyprop.Problem(self.Config)
		self.Problem.SetupStep()

		self.PreProcessed = False
		
	def preprocess(self):
		#run pre-propagation step for all tasks
		for task in self.PropagationTasks:
			task.setupTask(self.Problem)

		#Calculate intial state energy
		tmpPsi = self.Problem.psi.Copy()
		en = self.GetEnergyExpectationValue(self.Problem.psi, tmpPsi).real
		self.Logger.info("Initial state energy = %s" % en)

		self.PreProcessed = True

	def run(self):
		"""
		Propagate problem until end time.
		"""
		assert (self.PreProcessed)
		for t in self.Problem.Advance(self.NumberOfCallbacks):
			for task in self.PropagationTasks:
				task.callback(self.Problem)
		
		#run postprocessing
		self.postProcess()

	
	def postProcess(self):
		"""
		Run postprocessing for all propagation tasks
		"""
		for task in self.PropagationTasks:
			task.postProcess(self.Problem)


	def GetEnergyExpectationValue(self, psi, tmpPsi):
		"""
		Calculates the total energy of the problem by finding the expectation value 
		of the time-independent part of the Hamiltonian. Assumes that Tensor potentials
		and BasisPropagator are used.
		"""
		energy = 0.0
		
		#Iterate over all potentials, check for time dependence
		for pot in self.Problem.Propagator.BasePropagator.PotentialList:
			if not pot.IsTimeDependent:
				energy += pot.GetExpectationValue(psi, tmpPsi, 0, 0)

		return energy