예제 #1
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):
		self.Logger = GetClassLogger(self)
		self.TimeList = []
		self.NormList = []
		self.CorrList = []
		self.StartTime = -1
		self.InitialPsi = None

	def setupTask(self, prop):
		self.Logger.info("Setting up task...")
		self.StartTime = time.time()
		self.InitialPsi = prop.psi.Copy()
		self.OutputFileName = prop.Config.Names.output_file_name
	
		#check if output dir exist, create if not
		CreatePath(self.OutputFileName)

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

	def postProcess(self, prop):
		"""
		Store problem information collected during propagation
		"""
		if pyprop.ProcId == 0:
			nodeNames = ["SampleTimes", "Norm", "InitialCorrelation"]
			with tables.openFile(self.OutputFileName, "r+", MAX_THREADS=1) as h5file:
				for nodeName in nodeNames:
					if nodeName in h5file.root:
						h5file.removeNode(h5file.root, nodeName, recursive=True)

				h5file.createArray("/", "SampleTimes", self.TimeList)
				h5file.createArray("/", "Norm", self.NormList)
				h5file.createArray("/", "InitialCorrelation", self.CorrList)


	def _EstimateETA(self, prop):
		"""
		Estimates remaining time before propagation is finished
		"""
		curTime = time.time() - self.StartTime
		totalTime = (curTime / prop.PropagatedTime) * 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
예제 #2
0
class Propagate(object):
	"""
	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()

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

	def run(self):
		"""
		Propagate problem until end time.
		"""
		for _ 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