def read_data_inhomogeneous(iom, blockid=0): r""" :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. """ BF = BlockFactory() parameters = iom.load_parameters() timegrid = iom.load_inhomogwavepacket_timegrid(blockid=blockid) # Basis shapes bsdescr = iom.load_inhomogwavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in bsdescr.iteritems(): BS[ahash] = BF.create_basis_shape(descr) # Plot the coefficients for all timesteps for j, step in enumerate(timegrid): hashes, coeffs = iom.load_inhomogwavepacket_coefficients(timestep=step, blockid=blockid, get_hashes=True) k = [] for i in xrange(parameters["ncomponents"]): bs = BS[int(hashes[i])] ki = array([bs[node] for node in bs.get_node_iterator()]) k.append(ki) plot_coefficients(k, coeffs, step, parameters["dt"], index=blockid)
def plot_frames( iom, blockid=0 ): #, view=None, plotphase=True, plotcomponents=False, plotabssqr=False, imgsize=(12,9)): parameters = iom.load_parameters() if not parameters["dimension"] == 2: print("No wavefunction of two space dimensions, silent return!") return G = BlockFactory().create_grid(parameters) V = BlockFactory().create_potential(parameters) print(G.get_extensions()) WF = WaveFunction(parameters) WF.set_grid(G) BT = BasisTransformationWF(V) BT.set_grid(G) timegrid = iom.load_wavefunction_timegrid(blockid=blockid) u, v = G.get_nodes(split=True, flat=False) u = real(u) v = real(v) N = WF.get_number_components() for step in timegrid: print(" Plotting frame of timestep # " + str(step)) wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [wave[j, ...] for j in xrange(parameters["ncomponents"])] WF.set_values(values) # Transform the values to the eigenbasis # TODO: improve this: if parameters["algorithm"] == "fourier": BT.transform_to_eigen(WF) else: pass Psi = WF.get_values() fig = figure() for level in xrange(N): z = Psi[level] subplot(N, 1, level + 1) plotcm(z, darken=0.3) savefig("wavefunction_level_" + str(level) + "_timestep_" + (5 - len(str(step))) * "0" + str(step) + ".png") close(fig) print(" Plotting frames finished")
def plot_frames(iom, blockid=0): parameters = iom.load_parameters() if not parameters["dimension"] == 2: print("No wavefunction of two space dimensions, silent return!") return G = BlockFactory().create_grid(parameters) V = BlockFactory().create_potential(parameters) WF = WaveFunction(parameters) WF.set_grid(G) BT = BasisTransformationWF(V) BT.set_grid(G) timegrid = iom.load_wavefunction_timegrid(blockid=blockid) u, v = G.get_nodes(split=True, flat=False) u = real(u) v = real(v) N = WF.get_number_components() for step in timegrid: print(" Plotting frame of timestep # " + str(step)) wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [ wave[j,...] for j in xrange(parameters["ncomponents"]) ] WF.set_values(values) # Transform the values to the eigenbasis # TODO: improve this: if parameters["algorithm"] == "fourier": BT.transform_to_eigen(WF) else: pass Psi = WF.get_values() for level in xrange(N): z = Psi[level] # Plot the probability densities projected to the eigenbasis fig = mlab.figure(size=(800,700)) surfcf(u, v, angle(z), abs(z)) #mlab.contour_surf(u, v, abs(z)) #mlab.outline() #mlab.axes() mlab.savefig("wavefunction_level_"+str(level)+"_timestep_"+(5-len(str(step)))*"0"+str(step)+".png") mlab.close(fig) print(" Plotting frames finished")
def plot_frames(iom, blockid=0):#, view=None, plotphase=True, plotcomponents=False, plotabssqr=False, imgsize=(12,9)): parameters = iom.load_parameters() if not parameters["dimension"] == 2: print("No wavefunction of two space dimensions, silent return!") return G = BlockFactory().create_grid(parameters) V = BlockFactory().create_potential(parameters) print(G.get_extensions()) WF = WaveFunction(parameters) WF.set_grid(G) BT = BasisTransformationWF(V) BT.set_grid(G) timegrid = iom.load_wavefunction_timegrid(blockid=blockid) u, v = G.get_nodes(split=True, flat=False) u = real(u) v = real(v) N = WF.get_number_components() for step in timegrid: print(" Plotting frame of timestep # " + str(step)) wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [ wave[j,...] for j in xrange(parameters["ncomponents"]) ] WF.set_values(values) # Transform the values to the eigenbasis # TODO: improve this: if parameters["algorithm"] == "fourier": BT.transform_to_eigen(WF) else: pass Psi = WF.get_values() fig = figure() for level in xrange(N): z = Psi[level] subplot(N,1,level+1) plotcm(z, darken=0.3) savefig("wavefunction_level_"+str(level)+"_timestep_"+(5-len(str(step)))*"0"+str(step)+".png") close(fig) print(" Plotting frames finished")
def compute_norm_inhawp(iom, blockid=0, eigentrafo=True): """Compute the norm of a wavepacket timeseries. This function is for inhomogeneous wavepackets. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. :type blockid: Integer, Default is ``0`` :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. """ parameters = iom.load_parameters() # Number of time steps we saved timesteps = iom.load_inhomogwavepacket_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Basis transformator if eigentrafo is True: # The potential used Potential = BlockFactory().create_potential(parameters) BT = BasisTransformationHAWP(Potential) # We want to save norms, thus add a data slot to the data file iom.add_norm(parameters, timeslots=nrtimesteps, blockid=blockid) # Initialize a Hagedorn wavepacket with the data descr = iom.load_inhomogwavepacket_description(blockid=blockid) HAWP = BlockFactory().create_wavepacket(descr) if eigentrafo is True: BT.set_matrix_builder(HAWP.get_quadrature()) # Basis shapes BS_descr = iom.load_inhomogwavepacket_basisshapes() BS = {} for ahash, descr in BS_descr.iteritems(): BS[ahash] = BlockFactory().create_basis_shape(descr) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing norms of timestep "+str(step)) # Retrieve simulation data params = iom.load_inhomogwavepacket_parameters(timestep=step, blockid=blockid) hashes, coeffs = iom.load_inhomogwavepacket_coefficients(timestep=step, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWP.set_parameters(params) HAWP.set_basis_shape([ BS[int(ha)] for ha in hashes ]) HAWP.set_coefficients(coeffs) # Transform to the eigenbasis. if eigentrafo is True: BT.transform_to_eigen(HAWP) # Measure norms in the eigenbasis norm = HAWP.norm() # Save the norms iom.save_norm(norm, timestep=step, blockid=blockid)
def read_data_inhomogeneous(iom, blockid=0): r""" :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. """ parameters = iom.load_parameters() timegrid = iom.load_inhomogwavepacket_timegrid(blockid=blockid) time = timegrid * parameters["dt"] # The potential used Potential = BlockFactory().create_potential(parameters) # Basis transformator BT = BasisTransformationHAWP(Potential) # Basis shapes BS_descr = iom.load_wavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in BS_descr.iteritems(): BS[ahash] = BlockFactory().create_basis_shape(descr) # Initialize a Hagedorn wavepacket with the data descr = iom.load_inhomogwavepacket_description(blockid=blockid) HAWP = BlockFactory().create_wavepacket(descr) BT.set_matrix_builder(HAWP.get_quadrature()) # Store the resulting coefficients here CI = [ [] for i in xrange(HAWP.get_number_components()) ] # Iterate over all timesteps, this is an *expensive* transformation for i, step in enumerate(timegrid): print(" Computing eigentransformation at timestep "+str(step)) # Retrieve simulation data params = iom.load_inhomogwavepacket_parameters(timestep=step, blockid=blockid) hashes, coeffs = iom.load_inhomogwavepacket_coefficients(timestep=step, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWP.set_parameters(params) HAWP.set_basis_shapes([ BS[int(ha)] for ha in hashes ]) HAWP.set_coefficients(coeffs) # Transform to the eigenbasis. BT.transform_to_eigen(HAWP) for index, item in enumerate(HAWP.get_coefficients()): CI[index].append(item) CI = [ transpose(hstack(item)) for item in CI ] return time, CI
def transform_wavefunction_to_eigen(iomin, iomout, blockidin=0, blockidout=0): """Compute the transformation to the eigenbasis for a wavefunction. Save the result back to a file. :param iomin: An :py:class:`IOManager: instance providing the simulation data. :param iomout: An :py:class:`IOManager: instance for saving the transformed data. :param blockidin: The data block from which the values are read. Default is `0`. :param blockidout: The data block to which the values are written. Default is `0`. """ parameters = iomin.load_parameters() # Number of time steps we saved timesteps = iomin.load_wavefunction_timegrid(blockid=blockidin) nrtimesteps = timesteps.shape[0] iomout.add_wavefunction(parameters, timeslots=nrtimesteps, blockid=blockidout) # The grid on the domain grid = BlockFactory().create_grid(parameters) # The potential used Potential = BlockFactory().create_potential(parameters) # Basis transformator BT = BasisTransformationWF(Potential) BT.set_grid(grid) # And two empty wavefunctions WF = WaveFunction(parameters) WF.set_grid(grid) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Compute eigentransform at timestep # " + str(step)) # Retrieve simulation data values = iomin.load_wavefunction(timestep=step, blockid=blockidin) values = [values[j, ...] for j in xrange(parameters["ncomponents"])] WF.set_values(values) # Project wavefunction values to eigenbasis BT.transform_to_eigen(WF) # Save the transformed values iomout.save_wavefunction(WF.get_values(), timestep=step, blockid=blockidout)
def compute_norm(iom, blockid=0, eigentrafo=True): """Compute the norm of a wavefunction timeseries. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. Default is `0`. :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. """ parameters = iom.load_parameters() # Number of time steps we saved timesteps = iom.load_wavefunction_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Construct the grid from the parameters grid = BlockFactory().create_grid(parameters) # Basis transformator if eigentrafo is True: # The potential used Potential = BlockFactory().create_potential(parameters) BT = BasisTransformationWF(Potential) BT.set_grid(grid) # And two empty wavefunctions WF = WaveFunction(parameters) WF.set_grid(grid) # We want to save norms, thus add a data slot to the data file iom.add_norm(parameters, timeslots=nrtimesteps, blockid=blockid) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing norms of timestep " + str(step)) # Retrieve simulation data values = iom.load_wavefunction(timestep=step, blockid=blockid) values = [values[j, ...] for j in xrange(parameters["ncomponents"])] WF.set_values(values) # Project wavefunction values to eigenbasis if eigentrafo is True: BT.transform_to_eigen(WF) # Calculate the norm of the wave functions projected into the eigenbasis norms = WF.norm() iom.save_norm(norms, timestep=step, blockid=blockid)
def read_data_inhomogeneous(iom, blockid=0, timerange=None, path='.'): r""" :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. """ BF = BlockFactory() if iom.has_parameters(): parameters = iom.load_parameters() if "dt" in parameters: dt = parameters["dt"] else: dt = None timegrid = iom.load_inhomogwavepacket_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") # Basis shapes bsdescr = iom.load_inhomogwavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in bsdescr.items(): BS[ahash] = BF.create_basis_shape(descr) # Plot the coefficients for all timesteps for j, step in enumerate(timegrid): allhashes, allcoeffs = iom.load_inhomogwavepacket_coefficients( timestep=step, blockid=blockid, get_hashes=True) k = [] ck = [] for ahash, coeffs in zip(allhashes, allcoeffs): bs = BS[int(ahash)] ki = array([bs[node] for node in bs.get_node_iterator(mode="mag")]) ck.append(coeffs[ki]) ki.sort() k.append(ki) plot_coefficients(k, ck, step, dt, blockid=blockid, path=path)
def read_data_inhomogeneous(iom, blockid=0, timerange=None, path='.'): r""" :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. """ BF = BlockFactory() parameters = iom.load_parameters() timegrid = iom.load_inhomogwavepacket_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") # Basis shapes bsdescr = iom.load_inhomogwavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in bsdescr.items(): BS[ahash] = BF.create_basis_shape(descr) # Plot the coefficients for all timesteps for j, step in enumerate(timegrid): allhashes, allcoeffs = iom.load_inhomogwavepacket_coefficients(timestep=step, blockid=blockid, get_hashes=True) k = [] ck = [] for ahash, coeffs in zip(allhashes, allcoeffs): bs = BS[int(ahash)] ki = array([bs[node] for node in bs.get_node_iterator(mode="mag")]) ck.append(coeffs[ki]) ki.sort() k.append(ki) dt = parameters["dt"] if "dt" in parameters else None plot_coefficients(k, ck, step, dt, blockid=blockid, path=path)
def read_data_inhomogeneous(iom, blockid=0): r""" :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. """ parameters = iom.load_parameters() timegrid = iom.load_inhomogwavepacket_timegrid(blockid=blockid) dt = parameters["dt"] if "dt" in parameters else 1.0 time = timegrid * dt # The potential used Potential = BlockFactory().create_potential(parameters) # Basis transformator BT = BasisTransformationHAWP(Potential) # Initialize a Hagedorn wavepacket with the data descr = iom.load_inhomogwavepacket_description(blockid=blockid) HAWP = BlockFactory().create_wavepacket(descr) BT.set_matrix_builder(HAWP.get_quadrature()) # Store the resulting coefficients here CI = [[] for i in range(HAWP.get_number_components())] # Iterate over all timesteps, this is an *expensive* transformation for i, step in enumerate(timegrid): print(" Computing eigentransformation at timestep {}".format(step)) # Retrieve simulation data HAWP = iom.load_inhomogwavepacket(timestep=step, blockid=blockid) # Transform to the eigenbasis. BT.transform_to_eigen(HAWP) for index, item in enumerate(HAWP.get_coefficients()): CI[index].append(item) CI = [transpose(hstack(item)) for item in CI] return time, CI
def plot_coefficients(parameters, data, index=0, imgsize=(10, 20)): """ :param parameters: A :py:class:`ParameterProvider` instance. :param timegrid: The timegrid that belongs to the coefficient values. :param coeffs: The coefficient values. :param imgsize: The size of the plot. For a large number of plotted coefficients, we might have to increase this value. """ print("Plotting the coefficients of data block '" + str(index) + "'") # Check if we have enough coefficients to plot timegrid, coeffs, hashes = data N = len(coeffs) # Reconstruct basis shapes BS = [] for i in xrange(N): d = iom.load_wavepacket_basisshapes(the_hash=hashes[i][0]) bs = BlockFactory().create_basis_shape(d) BS.append(bs) # Compute all multi indices available (union of all shapes) allvects = set([]) for bs in BS: allvects.update(set([i for i in bs])) # And plot for vect in allvects: print(" Plotting coefficient " + str(vect) + " out of " + str(len(allvects))) fig = figure() for level in xrange(N): j = BS[level][vect] if j is not None: ax = fig.add_subplot(N, 1, level + 1) ax.plot(timegrid, real(coeffs[level][:, j])) ax.plot(timegrid, imag(coeffs[level][:, j])) ax.plot(timegrid, abs(coeffs[level][:, j])) ax.grid(True) ax.ticklabel_format(style="sci", scilimits=(0, 0), axis="y") ax.set_xlabel(r"$t$") ax.set_ylabel(r"$c^" + str(level) + r"$") fig.suptitle(r"$\underline{k} = " + str(vect) + r"$") fig.savefig("coefficient_k" + str(vect) + "_block" + str(index) + GD.output_format) close(fig)
def plot_frames(PP, iom, blockid=0, eigentransform=False, timerange=None, view=None, plotphase=True, plotcomponents=False, plotabssqr=False, load=False, gridblockid=None, imgsize=(12, 9), path='.'): """Plot the wavepacket for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. """ parameters = iom.load_parameters() BF = BlockFactory() if not parameters["dimension"] == 1: print("No one-dimensional wavepacket, silent return!") return if PP is None: PP = parameters if load is True: if gridblockid is None: gridblockid = blockid print("Loading grid data from datablock '{}'".format(gridblockid)) G = iom.load_grid(blockid=gridblockid) grid = real(G.reshape(-1)) else: print("Creating new grid") G = BlockFactory().create_grid(PP) grid = real(G.get_nodes(flat=True).reshape(-1)) if eigentransform: V = BF.create_potential(parameters) BT = BasisTransformationHAWP(V) timegrid = iom.load_wavepacket_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") # View if view is not None: if view[0] is None: view[0] = grid.min() if view[1] is None: view[1] = grid.max() for step in timegrid: print(" Plotting frame of timestep # {}".format(step)) HAWP = iom.load_wavepacket(step, blockid=blockid) # Transform the values to the eigenbasis if eigentransform: BT.transform_to_eigen(HAWP) values = HAWP.evaluate_at(G.get_nodes(), prefactor=True, component=0) # Plot fig = figure(figsize=imgsize) for index, component in enumerate(values): ax = fig.add_subplot(parameters["ncomponents"], 1, index + 1) ax.ticklabel_format(style="sci", scilimits=(0, 0), axis="y") if plotcomponents is True: ax.plot(grid, real(component)) ax.plot(grid, imag(component)) ax.set_ylabel(r"$\Re \varphi_{%d}, \Im \varphi_{%d}$" % (index, index)) if plotabssqr is True: ax.plot(grid, real(component * conj(component))) ax.set_ylabel( r"$\langle \varphi_{%d} | \varphi_{%d} \rangle$" % (index, index)) if plotphase is True: plotcf(grid, angle(component), real(component * conj(component))) ax.set_ylabel( r"$\langle \varphi_{%d} | \varphi_{%d} \rangle$" % (index, index)) ax.set_xlabel(r"$x$") # Set the aspect window ax.set_xlim(view[:2]) ax.set_ylim(view[2:]) if "dt" in parameters: fig.suptitle(r"$\Psi$ at time $%f$" % (step * parameters["dt"])) else: fig.suptitle(r"$\Psi$") fig.savefig( os.path.join( path, "wavepacket_block_%s_timestep_%07d.png" % (blockid, step))) close(fig)
def compute_autocorrelation_inhawp(iom, obsconfig, blockid=0, eigentrafo=True): """Compute the autocorrelation of a wavepacket timeseries. This function is for inhomogeneous wavepackets. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param obsconfig: Configuration parameters describing f.e. the inner product to use. :type obsconfig: A :py:class:`ParameterProvider` instance. :param blockid: The data block from which the values are read. :type blockid: Integer, Default is ``0`` :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. """ parameters = iom.load_parameters() BF = BlockFactory() # Number of time steps we saved timesteps = iom.load_inhomogwavepacket_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Basis transformator if eigentrafo is True: # The potential used Potential = BF.create_potential(parameters) BT = BasisTransformationHAWP(Potential) # We want to save autocorrelations, thus add a data slot to the data file iom.add_autocorrelation(parameters, timeslots=nrtimesteps, blockid=blockid) # Initialize a Hagedorn wavepacket with the data descr = iom.load_inhomogwavepacket_description(blockid=blockid) HAWPo = BF.create_wavepacket(descr) HAWPt = BF.create_wavepacket(descr) if eigentrafo is True: BT.set_matrix_builder(HAWPo.get_innerproduct()) # Basis shapes BS_descr = iom.load_inhomogwavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in BS_descr.items(): BS[ahash] = BF.create_basis_shape(descr) # Comfigure the original wavepacket # Retrieve simulation data params = iom.load_inhomogwavepacket_parameters(timestep=0, blockid=blockid) hashes, coeffs = iom.load_inhomogwavepacket_coefficients(timestep=0, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWPo.set_parameters(params) HAWPo.set_basis_shapes([BS[int(ha)] for ha in hashes]) HAWPo.set_coefficients(coeffs) # Set up the innerproduct for solving the integrals <phi_0 | phi_t> IP = BF.create_inner_product(obsconfig["innerproduct"]) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing autocorrelations of timestep %d" % step) # Retrieve simulation data params = iom.load_inhomogwavepacket_parameters(timestep=step, blockid=blockid) hashes, coeffs = iom.load_inhomogwavepacket_coefficients(timestep=step, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWPt.set_parameters(params) HAWPt.set_basis_shapes([BS[int(ha)] for ha in hashes]) HAWPt.set_coefficients(coeffs) # Transform to the eigenbasis. if eigentrafo is True: BT.transform_to_eigen(HAWPt) # Measure autocorrelations in the eigenbasis acs = IP.quadrature(HAWPo, HAWPt, diagonal=True) # Save the autocorrelations iom.save_autocorrelation(acs, timestep=step, blockid=blockid)
def compute_autocorrelation(iom, obsconfig=None, blockid=0, eigentrafo=True): """Compute the autocorrelation of a wavefunction timeseries. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param obsconfig: Configuration parameters describing f.e. the inner product to use. :type obsconfig: A :py:class:`ParameterProvider` instance. Value has no effect in this class. :param blockid: The data block from which the values are read. :type blockid: Integer, Default is ``0`` :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. """ parameters = iom.load_parameters() # Number of time steps we saved timesteps = iom.load_wavefunction_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Construct the grid from the parameters grid = BlockFactory().create_grid(parameters) # Basis transformator if eigentrafo is True: # The potential used Potential = BlockFactory().create_potential(parameters) BT = BasisTransformationWF(Potential) BT.set_grid(grid) # And two empty wavefunctions WFo = WaveFunction(parameters) WFo.set_grid(grid) WFt = WaveFunction(parameters) WFt.set_grid(grid) # We want to save norms, thus add a data slot to the data file iom.add_autocorrelation(parameters, timeslots=nrtimesteps, blockid=blockid) # Preconfigure the values = iom.load_wavefunction(timestep=0, blockid=blockid) values = [values[j, ...] for j in range(parameters["ncomponents"])] WFo.set_values(values) # Project wavefunction values to eigenbasis if eigentrafo is True: BT.transform_to_eigen(WFo) # Fourier transform the values WFo.set_values([fftn(value) for value in WFo.get_values()]) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing autocorrelations of timestep %d" % step) # Retrieve simulation data values = iom.load_wavefunction(timestep=step, blockid=blockid) values = [values[j, ...] for j in range(parameters["ncomponents"])] WFt.set_values(values) # Project wavefunction values to eigenbasis if eigentrafo is True: BT.transform_to_eigen(WFt) # Fourier transform the values WFt.set_values([fftn(value) for value in WFt.get_values()]) # Compute the prefactor T = grid.get_extensions() N = grid.get_number_nodes() prefactor = product(array(T) / array(N).astype(floating)**2) # Compute the autocorrelation # TODO: Consider splitting into cases `fft` versus `fftn` valueso = WFo.get_values() valuest = WFt.get_values() acs = [prefactor * ifftn(sum(conjugate(valueso[n]) * valuest[n])) for n in range(parameters["ncomponents"])] iom.save_autocorrelation(acs, timestep=step, blockid=blockid)
iom = IOManager() iom.open_file(filename=datafile) # Read file with parameter data for grid parameters = iom.load_parameters() if args.parametersfile: PL = ParameterLoader() gridparams = PL.load_from_file(parametersfile) else: gridparams = parameters # The axes rectangle that is plotted view = args.xrange + args.yrange + args.zrange # Plot if parameters["dimension"] == 2: Potential = BlockFactory().create_potential(parameters) Grid = TensorProductGrid(gridparams["limits"], gridparams["number_nodes"]) plot_potential(Grid, Potential, sparsify=args.sparsify, view=view, interactive=args.interactive, path=resultspath) else: print("Not a potential in two space dimensions, silent return!") iom.finalize()
potvars = map(lambda x: ":math:`"+str(x)+"`", potvars) potvars = reduce(lambda a,b: a+", "+b, potvars) if type(potdef["potential"]) == str: potformula = latex(sympify(potdef["potential"])) else: potformula = latex(Matrix(sympify(potdef["potential"]))) if potdef.has_key("defaults"): potdefaults = potdef["defaults"] else: potdefaults = {} # Create the potential "the right way" params["potential"] = potdef P = BlockFactory().create_potential(params) if len(potdef["variables"]) == 1: # Plot the potential values = P.evaluate_eigenvalues_at(x) figure(figsize=(4,3)) for value in values: plot(squeeze(x), squeeze(value)) grid(True) xlabel(r"$x$") ylabel(r"$\lambda_i\left(x\right)$") xlim(min(x), max(x)) savefig(potdef["name"] + ".png") elif len(potdef["variables"]) == 2:
def compute_eigenstate(parameters, filename="eigenstates.hdf5", computepq=True, computePQ=True): r""" Special variables necessary in configuration: * eigenstate_of_level (default: 0) * eigenstates_indices (default: [0]) * starting_point (default: (2, ..., 2)) * hawp_template * innerproduct """ D = parameters["dimension"] if "eigenstate_of_level" in parameters: N = parameters["eigenstate_of_level"] else: # Upper-most potential surface N = 0 # Create output file now, in case this fails we did not waste computation time IOM = IOManager() IOM.create_file(filename) # Save the simulation parameters IOM.add_parameters() IOM.save_parameters(parameters) gid = IOM.create_group() BF = BlockFactory() # Create the potential V = BF.create_potential(parameters) V.calculate_local_quadratic() # Compute position and momentum if computepq: # Minimize the potential to find q0 f = lambda x: real((squeeze(V.evaluate_at(x)[N]))) # Start with an offset because exact 0.0 values can give # issues, especially with the Hessian evaluation. This way # the minimizer will always stay away from zero a tiny bit. # The current starting point can give issues if the potential # is stationary at the point (2, ..., 2) but that is less likely. if "starting_point" in parameters: x0 = atleast_1d(parameters["starting_point"]) else: x0 = 0.5 * ones(D) q0 = fmin(f, x0, xtol=1e-12) q0 = q0.reshape((D, 1)) # We are at the minimum with no momentum p0 = zeros_like(q0) else: if "q0" in parameters: q0 = atleast_2d(parameters["q0"]) else: q0 = zeros((D, 1)) if "p0" in parameters: p0 = atleast_2d(parameters["p0"]) else: p0 = zeros((D, 1)) # Compute spreads if computePQ: # Q_0 = H^(-1/4) H = V.evaluate_hessian_at(q0) Q0 = inv(sqrtm(sqrtm(H))) # P_0 = i Q_0^(-1) P0 = 1.0j * inv(Q0) else: if "Q0" in parameters: Q0 = atleast_2d(parameters["Q0"]) else: Q0 = identity(D) if "P0" in parameters: P0 = atleast_2d(parameters["P0"]) else: P0 = 1.0j * inv(Q0) # The parameter set Pi print(70 * "-") print("Parameter values are:") print("---------------------") print(" q0:") print(str(q0)) print(" p0:") print(str(p0)) print(" Q0:") print(str(Q0)) print(" P0:") print(str(P0)) # Consistency check print(" Consistency check:") print(" P^T Q - Q^T P =?= 0") print(dot(P0.T, Q0) - dot(Q0.T, P0)) print(" Q^H P - P^H Q =?= 2i") print(dot(transpose(conjugate(Q0)), P0) - dot(transpose(conjugate(P0)), Q0)) # Next find the new coefficients c' HAWP = BF.create_wavepacket(parameters["hawp_template"]) # Set the parameter values Pi = HAWP.get_parameters() Pi[0] = q0 Pi[1] = p0 Pi[2] = Q0 Pi[3] = P0 HAWP.set_parameters(Pi) # Next compute the matrix M_ij = <phi_i | T + V | phi_j> # The potential part HQ = BF.create_inner_product(parameters["innerproduct"]) opV = lambda x, q, entry: V.evaluate_at(x, entry=entry) MV = HQ.build_matrix(HAWP, operator=opV) # The kinetic part MT = zeros_like(MV, dtype=complexfloating) GR = GradientHAWP() BS = HAWP.get_basis_shapes(component=N) vects = {} for i in BS: z = zeros_like(HAWP.get_coefficient_vector(), dtype=complexfloating) HAWP.set_coefficient_vector(z) HAWP.set_coefficient(N, i, 1.0) Kn, cnew = GR.apply_gradient(HAWP, component=N, as_packet=False) vects[i] = cnew for j in BS: for k in BS: cj = vects[j] ck = vects[k] entry = 0.5 * squeeze(sum(conjugate(cj) * ck)) MT[BS[j], BS[k]] = entry # Find eigenvalues and eigenvectors of the whole matrix M = MT + MV ew, ev = eigh(M) ind = argsort(ew) # Build the requested energy levels and states if "eigenstates_indices" in parameters: states = parameters["eigenstates_indices"] else: # Groundstate only states = [0] BS = HAWP.get_basis_shapes(component=0) KEY = ("q", "p", "Q", "P", "S", "adQ") print(70 * "-") for state in states: if state > BS.get_basis_size(): print("Warning: can not compute energy level {} with basis size of {}".format((state, BS))) continue index = ind[state] coeffs = ev[:, index] energy = ew[index] # Try to resolve ambiguities in sign imax = argmax(abs(coeffs)) a = abs(angle(coeffs[imax])) if a > pi / 2.0: coeffs *= -1 print("State: {}".format(state)) print("Energy: {}".format(energy)) print("Coefficients: \n") print(str(coeffs)) print(70 * "-") HAWP.set_coefficient_vector(coeffs.reshape((-1, 1))) # Save all the wavepacket data bid = IOM.create_block(groupid=gid) IOM.add_wavepacket(parameters, blockid=bid, key=KEY) IOM.save_wavepacket(HAWP, 0, blockid=bid, key=KEY) IOM.finalize() # TODO: Find better criterion if norm(q0) > 1000: print("+----------------------------------+") print("| Run-away minimum? |") print("| Maybe try different: |") print("| starting_point = [x0, y0, ...] |") print("+----------------------------------+")
def load_from_file(filepath, blockid=0, timestep=0, sizeK=None): r"""Utility script to load wavepacket parameters and coefficients from another simulation result in a form suitable for the input configuration of a new simulation. This is (mainly) used to start simulations with previously computed eigenstates. :param filepath: The path to the `.hdf5` file from which data will be read. :param blockid: The `datablock` from which to read the data. Default is the block with `blockid=0`. :param timestep: Load the data corresponding to the given `timestep`. The default timestep is `0`. :param sizeK: Load at most 'sizeK' many coefficients. Note that the order is defined by the linearization mapping :math:`\mu` of the packet's current basis shape. We then pick the first `sizeK` ones. """ IOM = IOManager() IOM.open_file(filepath) # Check if we have data tg = IOM.load_wavepacket_timegrid(blockid=blockid) if timestep not in tg: raise ValueError("No data for timestep {}".format(timestep)) # Load data and assemble packet BF = BlockFactory() # Basis shapes BS_descr = IOM.load_wavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in BS_descr.items(): BS[ahash] = BF.create_basis_shape(descr) # Create a packet wpd = IOM.load_wavepacket_description(blockid=blockid) HAWP = BF.create_wavepacket(wpd) # Data ha, ci = IOM.load_wavepacket_coefficients(blockid=blockid, timestep=timestep, get_hashes=True) Pi = IOM.load_wavepacket_parameters(blockid=blockid, timestep=timestep) HAWP.set_parameters(Pi) HAWP.set_basis_shapes([BS[int(h)] for h in ha]) HAWP.set_coefficients(ci) # Reformat data C = [] for n in range(HAWP.get_number_components()): B = HAWP.get_basis_shapes(component=n) cn = HAWP.get_coefficients(component=n) l = [] for i in range(B.get_basis_size()): l.append((B[i], cn[i, 0])) C.append(l) if sizeK is not None: # We load at most 'sizeK' coefficients. # Note that this does NOT specify which # ones in terms of multi-indices. C = [c[:sizeK] for c in C] return Pi, C
def plot_frames(PP, iom, blockid=0, load=False): r""" """ parameters = iom.load_parameters() if not parameters["dimension"] == 2: print("No wavefunction of two space dimensions, silent return!") return if PP is None: PP = parameters if load is True: # TODO: Implement reshaping raise NotImplementedError("Loading of 2D grids is not implemented") #G = iom.load_grid(blockid=blockid) #G = grid.reshape((1, -1)) else: G = BlockFactory().create_grid(PP) V = BlockFactory().create_potential(parameters) WF = WaveFunction(parameters) WF.set_grid(G) BT = BasisTransformationWF(V) BT.set_grid(G) timegrid = iom.load_wavefunction_timegrid(blockid=blockid) u, v = G.get_nodes(split=True, flat=False) u = real(u) v = real(v) N = WF.get_number_components() for step in timegrid: print(" Plotting frame of timestep # " + str(step)) wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [ wave[j,...] for j in xrange(parameters["ncomponents"]) ] WF.set_values(values) # Transform the values to the eigenbasis # TODO: improve this: if parameters["algorithm"] == "fourier": BT.transform_to_eigen(WF) else: pass Psi = WF.get_values() for level in xrange(N): z = Psi[level] z = z.reshape(G.get_number_nodes()) # Plot the probability densities projected to the eigenbasis fig = mlab.figure(size=(800,700)) surfcf(u, v, angle(z), abs(z)) #mlab.contour_surf(u, v, abs(z)) #mlab.outline() #mlab.axes() mlab.savefig("wavefunction_level_"+str(level)+"_timestep_"+(5-len(str(step)))*"0"+str(step)+".png") mlab.close(fig) print(" Plotting frames finished")
def plot_frames(PP, iom, blockid=0, load=False, eigentransform=False, timerange=None, view=None, path='.'): """Plot the wavepacket for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. """ parameters = iom.load_parameters() BF = BlockFactory() if not parameters["dimension"] == 2: print("No two-dimensional wavepacket, silent return!") return if PP is None: PP = parameters if load is True: # TODO: Implement reshaping raise NotImplementedError("Loading of 2D grids is not implemented") else: G = BF.create_grid(PP) if eigentransform: V = BF.create_potential(parameters) BT = BasisTransformationHAWP(V) timegrid = iom.load_wavepacket_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") u, v = G.get_axes() u = real(u.reshape(-1)) v = real(v.reshape(-1)) # View if view is not None: if view[0] is None: view[0] = u.min() if view[1] is None: view[1] = u.max() if view[2] is None: view[2] = v.min() if view[3] is None: view[3] = v.max() for step in timegrid: print(" Plotting frame of timestep # {}".format(step)) HAWP = iom.load_wavepacket(step, blockid=blockid) N = HAWP.get_number_components() # Transform the values to the eigenbasis if eigentransform: BT.transform_to_eigen(HAWP) psi = HAWP.evaluate_at(G.get_nodes(), prefactor=True, component=0) # Plot fig = figure() for level in range(N): z = psi[level] z = z.reshape(G.get_number_nodes()) fig.add_subplot(N, 1, level + 1) plotcf2d(u, v, z, darken=0.3, limits=view) fig.savefig(os.path.join(path, "wavepacket_block_%s_level_%d_timestep_%07d.png" % (blockid, level, step))) close(fig)
def compute_energy_inhawp(iom, blockid=0, eigentrafo=True, iseigen=True): """Compute the energies of a wavepacket timeseries. This function is for inhomogeneous wavepackets. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. :type blockid: Integer, Default is ``0`` :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. :param iseigen: Whether the data is assumed to be in the eigenbasis. :type iseigen: Boolean, default is ``True`` """ parameters = iom.load_parameters() # Number of time steps we saved timesteps = iom.load_inhomogwavepacket_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # The potential used Potential = BlockFactory().create_potential(parameters) # Basis transformator if eigentrafo is True: BT = BasisTransformationHAWP(Potential) # We want to save energies, thus add a data slot to the data file iom.add_energy(parameters, timeslots=nrtimesteps, blockid=blockid) # Initialize a Hagedorn wavepacket with the data descr = iom.load_inhomogwavepacket_description(blockid=blockid) HAWP = BlockFactory().create_wavepacket(descr) if eigentrafo is True: BT.set_matrix_builder(HAWP.get_innerproduct()) # Basis shapes BS_descr = iom.load_inhomogwavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in BS_descr.iteritems(): BS[ahash] = BlockFactory().create_basis_shape(descr) O = ObservablesHAWP() KEY = ("q","p","Q","P","S","adQ") # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing energies of timestep "+str(step)) # Retrieve simulation data params = iom.load_inhomogwavepacket_parameters(timestep=step, blockid=blockid, key=KEY) hashes, coeffs = iom.load_inhomogwavepacket_coefficients(timestep=step, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWP.set_parameters(params, key=KEY) HAWP.set_basis_shapes([ BS[int(ha)] for ha in hashes ]) HAWP.set_coefficients(coeffs) # Transform to the eigenbasis. if eigentrafo is True: BT.transform_to_eigen(HAWP) # Compute the energies O.set_innerproduct(HAWP.get_innerproduct()) ekin = O.kinetic_energy(HAWP) if iseigen is True: epot = O.potential_energy(HAWP, Potential.evaluate_eigenvalues_at) else: epot = O.potential_energy(HAWP, Potential.evaluate_at) iom.save_energy((ekin, epot), timestep=step, blockid=blockid)
def plot_frames(PP, iom, blockid=0, load=False, eigentransform=False, timerange=None, sparsify=10, view=None, interactive=False, path='.'): """Plot the wave function for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. """ parameters = iom.load_parameters() if not parameters["dimension"] == 2: print("No wavefunction of two space dimensions, silent return!") return if PP is None: PP = parameters if load is True: # TODO: Implement reshaping raise NotImplementedError("Loading of 2D grids is not implemented") else: G = BlockFactory().create_grid(PP) if eigentransform: V = BlockFactory().create_potential(parameters) BT = BasisTransformationWF(V) BT.set_grid(G) WF = WaveFunction(parameters) WF.set_grid(G) N = WF.get_number_components() timegrid = iom.load_wavefunction_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") u, v = G.get_nodes(split=True, flat=False) u = real(u[::sparsify, ::sparsify]) v = real(v[::sparsify, ::sparsify]) # View if view is not None: if view[0] is None: view[0] = u.min() if view[1] is None: view[1] = u.max() if view[2] is None: view[2] = v.min() if view[3] is None: view[3] = v.max() for step in timegrid: print(" Plotting frame of timestep # {}".format(step)) # Load the data wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [wave[j, ...] for j in range(parameters["ncomponents"])] WF.set_values(values) # Transform the values to the eigenbasis if eigentransform: BT.transform_to_eigen(WF) Psi = WF.get_values() for level in range(N): # Wavefunction data z = Psi[level] z = z.reshape(G.get_number_nodes())[::sparsify, ::sparsify] # View if view is not None: if view[4] is None: view[4] = 0.0 if view[5] is None: view[5] = 1.1 * abs(z).max() # Plot # if not interactive: # mlab.options.offscreen = True fig = mlab.figure(size=(800, 700)) surfcf(u, v, angle(z), abs(z), view=view) mlab.draw() if interactive: mlab.show() else: mlab.savefig( os.path.join( "wavefunction_surface_block_%s_level_%d_timestep_%07d.png" % (blockid, level, step))) mlab.close(fig)
def plot_frames(PP, iom, blockid=0, view=None, plotphase=True, plotcomponents=False, plotabssqr=False, load=True, gridblockid=None, imgsize=(12,9)): """Plot the wave function for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param view: The aspect ratio. :param plotphase: Whether to plot the complex phase. (slow) :param plotcomponents: Whether to plot the real/imaginary parts.. :param plotabssqr: Whether to plot the absolute value squared. """ parameters = iom.load_parameters() if not parameters["dimension"] == 1: print("No wavefunction of one space dimensions, silent return!") return if PP is None: PP = parameters if load is True: print("Loading grid data from datablock 'global'") if gridblockid is None: gridblockid = blockid G = iom.load_grid(blockid=gridblockid) G = G.reshape((1, -1)) grid = G else: print("Creating new grid") G = BlockFactory().create_grid(PP) grid = G.get_nodes(flat=True) timegrid = iom.load_wavefunction_timegrid(blockid=blockid) for step in timegrid: print(" Plotting frame of timestep # " + str(step)) wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [ wave[j,...] for j in xrange(parameters["ncomponents"]) ] # Plot the probability densities projected to the eigenbasis fig = figure(figsize=imgsize) for index, component in enumerate(values): ax = fig.add_subplot(parameters["ncomponents"],1,index+1) ax.ticklabel_format(style="sci", scilimits=(0,0), axis="y") if plotcomponents is True: ax.plot(squeeze(grid), real(component)) ax.plot(squeeze(grid), imag(component)) ax.set_ylabel(r"$\Re \varphi_"+str(index)+r", \Im \varphi_"+str(index)+r"$") if plotabssqr is True: ax.plot(squeeze(grid), component*conj(component)) ax.set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$") if plotphase is True: plotcf(squeeze(grid), angle(component), component*conj(component)) ax.set_ylabel(r"$\langle \varphi_"+str(index)+r"| \varphi_"+str(index)+r"\rangle$") ax.set_xlabel(r"$x$") # Set the aspect window if view is not None: ax.set_xlim(view[:2]) ax.set_ylim(view[2:]) if parameters.has_key("dt"): fig.suptitle(r"$\Psi$ at time $"+str(step*parameters["dt"])+r"$") else: fig.suptitle(r"$\Psi$") fig.savefig("wavefunction_block"+str(blockid)+"_"+ (7-len(str(step)))*"0"+str(step) +GD.output_format) close(fig) print(" Plotting frames finished")
def compute_norm_inhawp(iom, blockid=0, eigentrafo=True): """Compute the norm of a wavepacket timeseries. This function is for inhomogeneous wavepackets. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. :type blockid: Integer, Default is ``0`` :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. """ parameters = iom.load_parameters() # Number of time steps we saved timesteps = iom.load_inhomogwavepacket_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Basis transformator if eigentrafo is True: # The potential used Potential = BlockFactory().create_potential(parameters) BT = BasisTransformationHAWP(Potential) # We want to save norms, thus add a data slot to the data file iom.add_norm(parameters, timeslots=nrtimesteps, blockid=blockid) # Initialize a Hagedorn wavepacket with the data descr = iom.load_inhomogwavepacket_description(blockid=blockid) HAWP = BlockFactory().create_wavepacket(descr) if eigentrafo is True: BT.set_matrix_builder(HAWP.get_quadrature()) # Basis shapes BS_descr = iom.load_inhomogwavepacket_basisshapes() BS = {} for ahash, descr in BS_descr.iteritems(): BS[ahash] = BlockFactory().create_basis_shape(descr) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing norms of timestep " + str(step)) # Retrieve simulation data params = iom.load_inhomogwavepacket_parameters(timestep=step, blockid=blockid) hashes, coeffs = iom.load_inhomogwavepacket_coefficients( timestep=step, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWP.set_parameters(params) HAWP.set_basis_shape([BS[int(ha)] for ha in hashes]) HAWP.set_coefficients(coeffs) # Transform to the eigenbasis. if eigentrafo is True: BT.transform_to_eigen(HAWP) # Measure norms in the eigenbasis norm = HAWP.norm() # Save the norms iom.save_norm(norm, timestep=step, blockid=blockid)
def plot_frames(PP, iom, blockid=0, timerange=None, view=None, plotphase=True, plotcomponents=False, plotabssqr=False, load=True, gridblockid=None, imgsize=(12, 9), path='.'): """Plot the wave function for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param view: The aspect ratio. :param plotphase: Whether to plot the complex phase. (slow) :param plotcomponents: Whether to plot the real/imaginary parts.. :param plotabssqr: Whether to plot the absolute value squared. """ parameters = iom.load_parameters() if not parameters["dimension"] == 1: print("No two-dimensional wavefunction, silent return!") return if PP is None: PP = parameters if load is True: if gridblockid is None: gridblockid = blockid print("Loading grid data from datablock '%s'" % gridblockid) G = iom.load_grid(blockid=gridblockid) grid = real(G.reshape(-1)) else: print("Creating new grid") G = BlockFactory().create_grid(PP) grid = real(G.get_nodes(flat=True).reshape(-1)) # View if view[0] is None: view[0] = grid.min() if view[1] is None: view[1] = grid.max() timegrid = iom.load_wavefunction_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") for step in timegrid: print(" Plotting frame of timestep # {}".format(step)) wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [wave[j, ...] for j in range(parameters["ncomponents"])] # Plot fig = figure(figsize=imgsize) for index, component in enumerate(values): ax = fig.add_subplot(parameters["ncomponents"], 1, index + 1) ax.ticklabel_format(style="sci", scilimits=(0, 0), axis="y") if plotcomponents is True: ax.plot(grid, real(component)) ax.plot(grid, imag(component)) ax.set_ylabel(r"$\Re \varphi_{%d}, \Im \varphi_{%d}$" % (index, index)) if plotabssqr is True: ax.plot(grid, real(component * conj(component))) ax.set_ylabel( r"$\langle \varphi_{%d} | \varphi_{%d} \rangle$" % (index, index)) if plotphase is True: plotcf(grid, angle(component), real(component * conj(component))) ax.set_ylabel( r"$\langle \varphi_{%d} | \varphi_{%d} \rangle$" % (index, index)) ax.set_xlabel(r"$x$") # Set the aspect window ax.set_xlim(view[:2]) ax.set_ylim(view[2:]) if "dt" in parameters: fig.suptitle(r"$\Psi$ at time $%f$" % (step * parameters["dt"])) else: fig.suptitle(r"$\Psi$") fig.savefig( os.path.join( path, "wavefunction_block_%s_timestep_%07d.png" % (blockid, step))) close(fig)
def compute_energy(iom, blockid=0, eigentrafo=True, iseigen=True): """ :param iom: An :py:class:`IOManager: instance providing the simulation data. :param blockid: The data block from which the values are read. Default is `0`. :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. :param iseigen: Whether the data is assumed to be in the eigenbasis. :type iseigen: Boolean, default is ``True`` """ parameters = iom.load_parameters() # Number of time steps we saved timesteps = iom.load_wavefunction_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Construct grid from the parameters grid = BlockFactory().create_grid(parameters) # The potential used Potential = BlockFactory().create_potential(parameters) # The operators KO = KineticOperator(grid) KO.calculate_operator(parameters["eps"]) opT = KO if eigentrafo is True: opV = Potential.evaluate_at(grid) else: if iseigen is True: opV = Potential.evaluate_eigenvalues_at(grid, as_matrix=True) else: opV = Potential.evaluate_at(grid, as_matrix=True) # Basis transformator if eigentrafo is True: BT = BasisTransformationWF(Potential) BT.set_grid(grid) # And two empty wavefunctions WF = WaveFunction(parameters) WF.set_grid(grid) WF2 = WaveFunction(parameters) WF2.set_grid(grid) # We want to save norms, thus add a data slot to the data file iom.add_energy(parameters, timeslots=nrtimesteps, blockid=blockid) nst = Potential.get_number_components() if eigentrafo is True: # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing energies of timestep # " + str(step)) # Retrieve simulation data values = iom.load_wavefunction(timestep=step, blockid=blockid) values = [ values[j,...] for j in xrange(parameters["ncomponents"]) ] WF.set_values(values) # Project wavefunction values to eigenbasis BT.transform_to_eigen(WF) ekinlist = [] epotlist = [] # For each component of |Psi> values = WF.get_values() for index, item in enumerate(values): # tmp is the Vector (0, 0, 0, \psi_i, 0, 0, ...) tmp = [ zeros(item.shape) for z in xrange(nst) ] tmp[index] = item WF2.set_values(tmp) # Project this vector to the canonical basis BT.transform_to_canonical(WF2) # And calculate the energies of these components ekinlist.append(WF2.kinetic_energy(opT, summed=True)) epotlist.append(WF2.potential_energy(opV, summed=True)) iom.save_energy((ekinlist, epotlist), timestep=step, blockid=blockid) else: # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing energies of timestep # " + str(step)) # Retrieve simulation data values = iom.load_wavefunction(timestep=step, blockid=blockid) values = [ values[j,...] for j in xrange(parameters["ncomponents"]) ] WF.set_values(values) # And calculate the energies of these components ekinlist = WF.kinetic_energy(opT, summed=False) epotlist = WF.potential_energy(opV, summed=False) iom.save_energy((ekinlist, epotlist), timestep=step, blockid=blockid)
def compute_energy(iom, blockid=0, eigentrafo=True, iseigen=True): """ :param iom: An :py:class:`IOManager: instance providing the simulation data. :param blockid: The data block from which the values are read. Default is `0`. :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. :param iseigen: Whether the data is assumed to be in the eigenbasis. :type iseigen: Boolean, default is ``True`` """ parameters = iom.load_parameters() # Number of time steps we saved timesteps = iom.load_wavefunction_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Construct grid from the parameters grid = BlockFactory().create_grid(parameters) # The potential used Potential = BlockFactory().create_potential(parameters) # The operators KO = KineticOperator(grid) KO.calculate_operator(parameters["eps"]) opT = KO if eigentrafo is True: opV = Potential.evaluate_at(grid) else: if iseigen is True: opV = Potential.evaluate_eigenvalues_at(grid, as_matrix=True) else: opV = Potential.evaluate_at(grid, as_matrix=True) # Basis transformator if eigentrafo is True: BT = BasisTransformationWF(Potential) BT.set_grid(grid) # And two empty wavefunctions WF = WaveFunction(parameters) WF.set_grid(grid) WF2 = WaveFunction(parameters) WF2.set_grid(grid) # We want to save norms, thus add a data slot to the data file iom.add_energy(parameters, timeslots=nrtimesteps, blockid=blockid) nst = Potential.get_number_components() if eigentrafo is True: # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing energies of timestep # " + str(step)) # Retrieve simulation data values = iom.load_wavefunction(timestep=step, blockid=blockid) values = [ values[j, ...] for j in xrange(parameters["ncomponents"]) ] WF.set_values(values) # Project wavefunction values to eigenbasis BT.transform_to_eigen(WF) ekinlist = [] epotlist = [] # For each component of |Psi> values = WF.get_values() for index, item in enumerate(values): # tmp is the Vector (0, 0, 0, \psi_i, 0, 0, ...) tmp = [zeros(item.shape) for z in xrange(nst)] tmp[index] = item WF2.set_values(tmp) # Project this vector to the canonical basis BT.transform_to_canonical(WF2) # And calculate the energies of these components ekinlist.append(WF2.kinetic_energy(opT, summed=True)) epotlist.append(WF2.potential_energy(opV, summed=True)) iom.save_energy((ekinlist, epotlist), timestep=step, blockid=blockid) else: # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing energies of timestep # " + str(step)) # Retrieve simulation data values = iom.load_wavefunction(timestep=step, blockid=blockid) values = [ values[j, ...] for j in xrange(parameters["ncomponents"]) ] WF.set_values(values) # And calculate the energies of these components ekinlist = WF.kinetic_energy(opT, summed=False) epotlist = WF.potential_energy(opV, summed=False) iom.save_energy((ekinlist, epotlist), timestep=step, blockid=blockid)
def plot_frames(PP, iom, blockid=0, load=False, eigentransform=False, timerange=None, sparsify=10, view=None, interactive=False, path='.'): """Plot the wave function for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. """ parameters = iom.load_parameters() if not parameters["dimension"] == 2: print("No wavefunction of two space dimensions, silent return!") return if PP is None: PP = parameters if load is True: # TODO: Implement reshaping raise NotImplementedError("Loading of 2D grids is not implemented") else: G = BlockFactory().create_grid(PP) if eigentransform: V = BlockFactory().create_potential(parameters) BT = BasisTransformationWF(V) BT.set_grid(G) WF = WaveFunction(parameters) WF.set_grid(G) N = WF.get_number_components() timegrid = iom.load_wavefunction_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") u, v = G.get_nodes(split=True, flat=False) u = real(u[::sparsify, ::sparsify]) v = real(v[::sparsify, ::sparsify]) # View if view is not None: if view[0] is None: view[0] = u.min() if view[1] is None: view[1] = u.max() if view[2] is None: view[2] = v.min() if view[3] is None: view[3] = v.max() for step in timegrid: print(" Plotting frame of timestep # {}".format(step)) # Load the data wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [wave[j, ...] for j in range(parameters["ncomponents"])] WF.set_values(values) # Transform the values to the eigenbasis if eigentransform: BT.transform_to_eigen(WF) Psi = WF.get_values() for level in range(N): # Wavefunction data z = Psi[level] z = z.reshape(G.get_number_nodes())[::sparsify, ::sparsify] # View if view is not None: if view[4] is None: view[4] = 0.0 if view[5] is None: view[5] = 1.1 * abs(z).max() # Plot # if not interactive: # mlab.options.offscreen = True fig = mlab.figure(size=(800, 700)) surfcf(u, v, angle(z), abs(z), view=view) mlab.draw() if interactive: mlab.show() else: mlab.savefig(os.path.join("wavefunction_surface_block_%s_level_%d_timestep_%07d.png" % (blockid, level, step))) mlab.close(fig)
def transform_inhawp_to_eigen(iomin, iomout, blockidin=0, blockidout=0): """Compute the transformation to the eigenbasis for a wavepacket. Save the result back to a file. :param iomin: An :py:class:`IOManager: instance providing the simulation data. :param iomout: An :py:class:`IOManager: instance for saving the transformed data. :param blockidin: The data block from which the values are read. Default is `0`. :param blockidout: The data block to which the values are written. Default is `0`. """ parameters = iomin.load_parameters() # Number of time steps we saved timesteps = iomin.load_inhomogwavepacket_timegrid(blockid=blockidin) nrtimesteps = timesteps.shape[0] # The potential used Potential = BlockFactory().create_potential(parameters) # Basis transformator BT = BasisTransformationHAWP(Potential) # Initialize a Hagedorn wavepacket with the data descr = iomin.load_inhomogwavepacket_description(blockid=blockidin) HAWP = BlockFactory().create_wavepacket(descr) iomout.add_inhomogwavepacket(descr, timeslots=nrtimesteps, blockid=blockidout) iomout.save_inhomogwavepacket_description(HAWP.get_description(), blockid=blockidout) BT.set_matrix_builder(HAWP.get_quadrature()) # Basis shapes BS_descr = iomin.load_inhomogwavepacket_basisshapes() BS = {} for ahash, descr in BS_descr.iteritems(): BS[ahash] = BlockFactory().create_basis_shape(descr) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Compute eigentransform at timestep # " + str(step)) # Retrieve simulation data params = iomin.load_inhomogwavepacket_parameters(timestep=step, blockid=blockidin) hashes, coeffs = iomin.load_inhomogwavepacket_coefficients( timestep=step, get_hashes=True, blockid=blockidin) # Configure the wavepacket HAWP.set_parameters(params) HAWP.set_basis_shape([BS[int(ha)] for ha in hashes]) HAWP.set_coefficients(coeffs) # Transform to the eigenbasis. BT.transform_to_eigen(HAWP) # Save the transformed packet # Pi iomout.save_inhomogwavepacket_parameters(HAWP.get_parameters(), timestep=step, blockid=blockidout) # Basis shapes (in case they changed!) for shape in HAWP.get_basis_shape(): iomout.save_inhomogwavepacket_basisshapes(shape, blockid=blockidout) # Coefficients iomout.save_inhomogwavepacket_coefficients(HAWP.get_coefficients(), HAWP.get_basis_shape(), timestep=step, blockid=blockidout)
def transform_inhawp_to_eigen(iomin, iomout, blockidin=0, blockidout=0): """Compute the transformation to the eigenbasis for a wavepacket. Save the result back to a file. :param iomin: An :py:class:`IOManager: instance providing the simulation data. :param iomout: An :py:class:`IOManager: instance for saving the transformed data. :param blockidin: The data block from which the values are read. Default is `0`. :param blockidout: The data block to which the values are written. Default is `0`. """ parameters = iomin.load_parameters() KEY = ("q","p","Q","P","S","adQ") # Number of time steps we saved timesteps = iomin.load_inhomogwavepacket_timegrid(blockid=blockidin) nrtimesteps = timesteps.shape[0] # The potential used Potential = BlockFactory().create_potential(parameters) # Basis transformator BT = BasisTransformationHAWP(Potential) # Initialize a Hagedorn wavepacket with the data descr = iomin.load_inhomogwavepacket_description(blockid=blockidin) HAWP = BlockFactory().create_wavepacket(descr) iomout.add_inhomogwavepacket(descr, timeslots=nrtimesteps, blockid=blockidout, key=KEY) iomout.save_inhomogwavepacket_description(HAWP.get_description(), blockid=blockidout) BT.set_matrix_builder(HAWP.get_innerproduct()) # Basis shapes BS_descr = iomin.load_inhomogwavepacket_basisshapes(blockid=blockidin) BS = {} for ahash, descr in BS_descr.iteritems(): BS[ahash] = BlockFactory().create_basis_shape(descr) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Compute eigentransform at timestep # " + str(step)) # Retrieve simulation data params = iomin.load_inhomogwavepacket_parameters(timestep=step, blockid=blockidin, key=KEY) hashes, coeffs = iomin.load_inhomogwavepacket_coefficients(timestep=step, get_hashes=True, blockid=blockidin) # Configure the wavepacket HAWP.set_parameters(params, key=KEY) HAWP.set_basis_shapes([ BS[int(ha)] for ha in hashes ]) HAWP.set_coefficients(coeffs) # Transform to the eigenbasis. BT.transform_to_eigen(HAWP) # Save the transformed packet # Pi iomout.save_inhomogwavepacket_parameters(HAWP.get_parameters(key=KEY), timestep=step, blockid=blockidout, key=KEY) # Basis shapes (in case they changed!) for shape in HAWP.get_basis_shapes(): iomout.save_inhomogwavepacket_basisshapes(shape, blockid=blockidout) # Coefficients iomout.save_inhomogwavepacket_coefficients(HAWP.get_coefficients(), HAWP.get_basis_shapes(), timestep=step, blockid=blockidout)
def compute_autocorrelation_hawp(iom, obsconfig, blockid=0, eigentrafo=True): """Compute the autocorrelation of a wavepacket timeseries. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param obsconfig: Configuration parameters describing f.e. the inner product to use. :type obsconfig: A :py:class:`ParameterProvider` instance. :param blockid: The data block from which the values are read. :type blockid: Integer, Default is ``0`` :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. """ parameters = iom.load_parameters() BF = BlockFactory() # Number of time steps we saved timesteps = iom.load_wavepacket_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Basis transformator if eigentrafo is True: # The potential used Potential = BF.create_potential(parameters) BT = BasisTransformationHAWP(Potential) # We want to save norms, thus add a data slot to the data file iom.add_autocorrelation(parameters, timeslots=nrtimesteps, blockid=blockid) # Initialize a Hagedorn wavepacket with the data descr = iom.load_wavepacket_description(blockid=blockid) HAWPo = BF.create_wavepacket(descr) HAWPt = BF.create_wavepacket(descr) if eigentrafo is True: BT.set_matrix_builder(HAWPo.get_innerproduct()) # Basis shapes BS_descr = iom.load_wavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in BS_descr.items(): BS[ahash] = BF.create_basis_shape(descr) # Comfigure the original wavepacket KEY = ("q", "p", "Q", "P", "S", "adQ") # Retrieve simulation data params = iom.load_wavepacket_parameters(timestep=0, blockid=blockid, key=KEY) hashes, coeffs = iom.load_wavepacket_coefficients(timestep=0, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWPo.set_parameters(params, key=KEY) HAWPo.set_basis_shapes([BS[int(ha)] for ha in hashes]) HAWPo.set_coefficients(coeffs) # Set up the innerproduct for solving the integrals <phi_0 | phi_t> IP = BF.create_inner_product(obsconfig["innerproduct"]) # Transform to the eigenbasis. if eigentrafo is True: BT.transform_to_eigen(HAWPo) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing autocorrelation of timestep %d" % step) # Retrieve simulation data paramst = iom.load_wavepacket_parameters(timestep=step, blockid=blockid, key=KEY) hashes, coeffs = iom.load_wavepacket_coefficients(timestep=step, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWPt.set_parameters(paramst, key=KEY) HAWPt.set_basis_shapes([BS[int(ha)] for ha in hashes]) HAWPt.set_coefficients(coeffs) # Transform to the eigenbasis. if eigentrafo is True: BT.transform_to_eigen(HAWPt) # Measure autocorrelations in the eigenbasis acs = IP.quadrature(HAWPo, HAWPt, diagonal=True) # Save the autocorrelations iom.save_autocorrelation(acs, timestep=step, blockid=blockid)
def plot_frames(PP, iom, blockid=0, load=False, eigentransform=False, timerange=None, view=None, path='.'): """Plot the wavepacket for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. """ parameters = iom.load_parameters() BF = BlockFactory() if not parameters["dimension"] == 2: print("No two-dimensional wavepacket, silent return!") return if PP is None: PP = parameters if load is True: # TODO: Implement reshaping raise NotImplementedError("Loading of 2D grids is not implemented") else: G = BF.create_grid(PP) if eigentransform: V = BF.create_potential(parameters) BT = BasisTransformationHAWP(V) timegrid = iom.load_wavepacket_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") u, v = G.get_axes() u = real(u.reshape(-1)) v = real(v.reshape(-1)) # View if view is not None: if view[0] is None: view[0] = u.min() if view[1] is None: view[1] = u.max() if view[2] is None: view[2] = v.min() if view[3] is None: view[3] = v.max() for step in timegrid: print(" Plotting frame of timestep # {}".format(step)) HAWP = iom.load_wavepacket(step, blockid=blockid) N = HAWP.get_number_components() # Transform the values to the eigenbasis if eigentransform: BT.transform_to_eigen(HAWP) psi = HAWP.evaluate_at(G.get_nodes(), prefactor=True, component=0) # Plot fig = figure() for level in range(N): z = psi[level] z = z.reshape(G.get_number_nodes()) fig.add_subplot(N, 1, level + 1) plotcf2d(u, v, z, darken=0.3, limits=view) fig.savefig( os.path.join( path, "wavepacket_block_%s_level_%d_timestep_%07d.png" % (blockid, level, step))) close(fig)
def compute_energy_inhawp(iom, blockid=0, eigentrafo=True, iseigen=True): """Compute the energies of a wavepacket timeseries. This function is for inhomogeneous wavepackets. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. :type blockid: Integer, Default is ``0`` :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. :param iseigen: Whether the data is assumed to be in the eigenbasis. :type iseigen: Boolean, default is ``True`` """ parameters = iom.load_parameters() BF = BlockFactory() # Number of time steps we saved timesteps = iom.load_inhomogwavepacket_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # The potential used Potential = BF.create_potential(parameters) # Basis transformator if eigentrafo is True: BT = BasisTransformationHAWP(Potential) # We want to save energies, thus add a data slot to the data file iom.add_energy(parameters, timeslots=nrtimesteps, blockid=blockid) # Initialize a Hagedorn wavepacket with the data descr = iom.load_inhomogwavepacket_description(blockid=blockid) HAWP = BF.create_wavepacket(descr) # Inner product if HAWP.get_innerproduct() is None: IP = BF.create_inner_product(parameters["innerproduct"]) HAWP.set_innerproduct(IP) if eigentrafo is True: BT.set_matrix_builder(HAWP.get_innerproduct()) # Basis shapes BS_descr = iom.load_inhomogwavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in BS_descr.items(): BS[ahash] = BF.create_basis_shape(descr) O = ObservablesHAWP() KEY = ("q", "p", "Q", "P", "S", "adQ") # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing energies of timestep %d" % step) # Retrieve simulation data params = iom.load_inhomogwavepacket_parameters(timestep=step, blockid=blockid, key=KEY) hashes, coeffs = iom.load_inhomogwavepacket_coefficients( timestep=step, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWP.set_parameters(params, key=KEY) HAWP.set_basis_shapes([BS[int(ha)] for ha in hashes]) HAWP.set_coefficients(coeffs) # Transform to the eigenbasis. if eigentrafo is True: BT.transform_to_eigen(HAWP) # Compute the energies O.set_innerproduct(HAWP.get_innerproduct()) O.set_gradient(HAWP.get_gradient_operator()) ekin = O.kinetic_energy(HAWP) if iseigen is True: epot = O.potential_energy(HAWP, Potential.evaluate_eigenvalues_at) else: epot = O.potential_energy(HAWP, Potential.evaluate_at) iom.save_energy((ekin, epot), timestep=step, blockid=blockid)
def plot_coefficients(parameters, data, absang=False, index=0, reim=False, imgsize=(10, 20), view=[None, None], path='.'): """ :param parameters: A :py:class:`ParameterProvider` instance. """ print("Plotting the coefficients of data block '%s'" % index) # Check if we have enough coefficients to plot time, coeffs, hashes = data # View if view[0] is None: view[0] = nanmin(time) if view[1] is None: view[1] = nanmax(time) N = len(coeffs) # Reconstruct basis shapes BS = [] for i in range(N): d = iom.load_wavepacket_basisshapes(the_hash=hashes[i][0]) bs = BlockFactory().create_basis_shape(d) BS.append(bs) # Compute all multi indices available (union of all shapes) allvects = set([]) for bs in BS: allvects.update(set([i for i in bs])) # Plot for vect in allvects: print(" Plotting coefficient {} out of {}".format(vect, len(allvects))) fig = figure() for level in range(N): j = BS[level][vect] if j is not None: ax = fig.add_subplot(N, 1, level + 1) if not reim: ax.plot(time, angle(coeffs[level][:, j]), label=r"$\arg c$") else: ax.plot(time, real(coeffs[level][:, j]), label=r"$\Re c$") ax.plot(time, imag(coeffs[level][:, j]), label=r"$\Im c$") ax.plot(time, abs(coeffs[level][:, j]), "r", label=r"$|c|$") ax.grid(True) ax.set_xlim(view[0], view[1]) ax.ticklabel_format(style="sci", scilimits=(0, 0), axis="y") ax.legend(loc='upper right') ax.set_xlabel(r"$t$") ax.set_ylabel(r"$c^{%d}$" % level) fig.suptitle(r"$\underline{k} = " + str(vect) + r"$") fig.savefig( os.path.join( path, "coefficient_k" + str(vect) + "_block" + str(index) + GD.output_format)) close(fig)
def plot_frames(PP, iom, blockid=0, load=False, eigentransform=False, timerange=None, view=None, path='.'): """Plot the wave function for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. """ parameters = iom.load_parameters() if not parameters["dimension"] == 2: print("No wavefunction of two space dimensions, silent return!") return if PP is None: PP = parameters if load is True: # TODO: Implement reshaping raise NotImplementedError("Loading of 2D grids is not implemented") else: G = BlockFactory().create_grid(PP) if eigentransform: V = BlockFactory().create_potential(parameters) BT = BasisTransformationWF(V) BT.set_grid(G) WF = WaveFunction(parameters) WF.set_grid(G) N = WF.get_number_components() timegrid = iom.load_wavefunction_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") u, v = G.get_axes() u = real(u.reshape(-1)) v = real(v.reshape(-1)) # View if view is not None: if view[0] is None: view[0] = u.min() if view[1] is None: view[1] = u.max() if view[2] is None: view[2] = v.min() if view[3] is None: view[3] = v.max() for step in timegrid: print(" Plotting frame of timestep # {}".format(step)) # Load the data wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [wave[j, ...] for j in range(parameters["ncomponents"])] WF.set_values(values) # Transform the values to the eigenbasis if eigentransform: BT.transform_to_eigen(WF) Psi = WF.get_values() # Plot fig = figure() for level in range(N): # Wavefunction data z = Psi[level] z = z.reshape(G.get_number_nodes()) fig.add_subplot(N, 1, level + 1) plotcf2d(u, v, z, darken=0.3, limits=view) fig.savefig( os.path.join( path, "wavefunction_contour_block_%s_level_%d_timestep_%07d.png" % (blockid, level, step))) close(fig)
def plot_frames(PP, iom, blockid=0, load=False, limits=None): r""" """ parameters = iom.load_parameters() BF = BlockFactory() if not parameters["dimension"] == 2: print("No wavepacket of two space dimensions, silent return!") return if PP is None: PP = parameters if load is True: # TODO: Implement reshaping raise NotImplementedError("Loading of 2D grids is not implemented") #G = iom.load_grid(blockid=blockid) #G = grid.reshape((1, -1)) else: G = BF.create_grid(PP) u, v = map(squeeze, G.get_axes()) V = BF.create_potential(parameters) BT = BasisTransformationHAWP(V) wpd = iom.load_wavepacket_description(blockid=blockid) HAWP = BF.create_wavepacket(wpd) # Basis shapes BS_descr = iom.load_wavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in BS_descr.iteritems(): BS[ahash] = BF.create_basis_shape(descr) timegrid = iom.load_wavepacket_timegrid(blockid=blockid) N = HAWP.get_number_components() for step in timegrid: print(" Plotting frame of timestep # " + str(step)) hi, ci = iom.load_wavepacket_coefficients(timestep=step, get_hashes=True, blockid=blockid) Pi = iom.load_wavepacket_parameters(timestep=step, blockid=blockid) HAWP.set_parameters(Pi) HAWP.set_basis_shapes([ BS[int(ha)] for ha in hi ]) HAWP.set_coefficients(ci) psi = HAWP.evaluate_at(G, prefactor=True, component=0) fig = figure() for level in xrange(N): z = psi[level] z = z.reshape(G.get_number_nodes()) subplot(N,1,level+1) #plotcm(z.reshape(G.get_number_nodes()), darken=0.3) plotcf2d(u, v, z, darken=0.3, limits=limits) savefig("wavepacket_block_"+str(blockid)+"_level_"+str(level)+"_timestep_"+(5-len(str(step)))*"0"+str(step)+".png") close(fig) print(" Plotting frames finished")
def compute_eigenstate(parameters): r""" Special variables necessary in configuration: * eigenstate_of_level (default: 0) * states_indices (default: [0]) """ D = parameters["dimension"] if parameters.has_key("eigenstate_of_level"): N = parameters["eigenstate_of_level"] else: # Upper-most potential surface N = 0 # Create output file now, in case this fails we did not waste computations IOM = IOManager() IOM.create_file("eigenstates.hdf5") # Save the simulation parameters IOM.add_parameters() IOM.save_parameters(parameters) gid = IOM.create_group() BF = BlockFactory() # Create the potential V = BF.create_potential(parameters) V.calculate_local_quadratic() # Minimize the potential to find q0 f = lambda x: real((squeeze(V.evaluate_at(x)[N]))) # Start with an offset because exact 0.0 values can give # issues, especially with the Hessian evaluation. This way # the minimizer will always stay away from zero a tiny bit. # The current starting point can give issues if the potential # is stationary at the point (2, ..., 2) but that is less likely. x0 = 2.0*ones(D) q0 = fmin(f, x0, xtol=1e-12) q0 = q0.reshape((D,1)) # We are at the minimum with no momentum p0 = zeros_like(q0) # Compute spreads now # Q_0 = H^(-1/4) H = V.evaluate_hessian_at(q0) Q0 = inv(sqrtm(sqrtm(H))) # Take P_00 = i Q_0^(-1) P0 = 1.0j * inv(Q0) # print(70*"-") print("Parameter values are:") print("---------------------") print(" q0:") print(str(q0)) print(" p0:") print(str(p0)) print(" Q0:") print(str(Q0)) print(" P0:") print(str(P0)) # Consistency check print(" consistency:") print(str(conj(Q0)*P0 - conj(P0)*Q0)) print(70*"-") # Next find the new coefficients c' HAWP = BF.create_wavepacket(parameters["hawp_template"]) # Set the parameter values Pi = HAWP.get_parameters() Pi[0] = q0 Pi[1] = p0 Pi[2] = Q0 Pi[3] = P0 HAWP.set_parameters(Pi) # Next compute the matrix M_ij = <phi_i | T + V | phi_j> # The potential part HQ = BF.create_inner_product(parameters["innerproduct"]) opV = lambda x, q, entry: V.evaluate_at(x, entry=entry) MV = HQ.build_matrix(HAWP, operator=opV) # The kinetic part MT = zeros_like(MV, dtype=complexfloating) GR = GradientHAWP() BS = HAWP.get_basis_shapes(N) vects = {} for i in BS: z = zeros_like(HAWP.get_coefficient_vector(), dtype=complexfloating) HAWP.set_coefficient_vector(z) HAWP.set_coefficient(N, i, 1.0) Kn, cnew = GR.apply_gradient(HAWP, N) vects[i] = cnew for j in BS: for k in BS: cj = vects[j] ck = vects[k] entry = 0.5 * squeeze(sum(conj(cj) * ck)) MT[BS[j], BS[k]] = entry # Find eigenvalues and eigenvectors of the whole matrix M = MT + MV ew, ev = eigh(M) ind = argsort(ew) # Build the requested energy levels and states if parameters.has_key("eigenstates_indices"): states = parameters["eigenstates_indices"] else: # Groundstate only states = [0] BS = HAWP.get_basis_shapes(component=0) KEY = ("q","p","Q","P","S","adQ") print(70*"-") for state in states: if state > BS.get_basis_size(): print("Warning: can not compute energy level "+state+" with basis size of "+str(BS)) continue index = ind[state] coeffs = ev[:,index] energy = ew[index] print("Level: "+str(state)) print("Energy: "+str(energy)) print("Coefficients: \n") print(str(coeffs)) print(70*"-") HAWP.set_coefficient_vector(coeffs.reshape((-1, 1))) # Save all the wavepacket data bid = IOM.create_block(groupid=gid) IOM.add_wavepacket(parameters, blockid=bid, key=KEY) IOM.save_wavepacket_description(HAWP.get_description(), blockid=bid) for shape in HAWP.get_basis_shapes(): IOM.save_wavepacket_basisshapes(shape, blockid=bid) IOM.save_wavepacket_parameters(HAWP.get_parameters(key=KEY), timestep=0, blockid=bid, key=KEY) IOM.save_wavepacket_coefficients(HAWP.get_coefficients(), HAWP.get_basis_shapes(), timestep=0, blockid=bid) IOM.finalize()
def plot_frames(PP, iom, blockid=0, load=False, eigentransform=False, timerange=None, view=None, path='.'): """Plot the wave function for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. """ parameters = iom.load_parameters() if not parameters["dimension"] == 2: print("No wavefunction of two space dimensions, silent return!") return if PP is None: PP = parameters if load is True: # TODO: Implement reshaping raise NotImplementedError("Loading of 2D grids is not implemented") else: G = BlockFactory().create_grid(PP) if eigentransform: V = BlockFactory().create_potential(parameters) BT = BasisTransformationWF(V) BT.set_grid(G) WF = WaveFunction(parameters) WF.set_grid(G) N = WF.get_number_components() timegrid = iom.load_wavefunction_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") u, v = G.get_axes() u = real(u.reshape(-1)) v = real(v.reshape(-1)) # View if view is not None: if view[0] is None: view[0] = u.min() if view[1] is None: view[1] = u.max() if view[2] is None: view[2] = v.min() if view[3] is None: view[3] = v.max() for step in timegrid: print(" Plotting frame of timestep # {}".format(step)) # Load the data wave = iom.load_wavefunction(blockid=blockid, timestep=step) values = [wave[j, ...] for j in range(parameters["ncomponents"])] WF.set_values(values) # Transform the values to the eigenbasis if eigentransform: BT.transform_to_eigen(WF) Psi = WF.get_values() # Plot fig = figure() for level in range(N): # Wavefunction data z = Psi[level] z = z.reshape(G.get_number_nodes()) fig.add_subplot(N, 1, level + 1) plotcf2d(u, v, z, darken=0.3, limits=view) fig.savefig(os.path.join(path, "wavefunction_contour_block_%s_level_%d_timestep_%07d.png" % (blockid, level, step))) close(fig)
def read_data_homogeneous(iom, blockid=0): r""" :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. """ parameters = iom.load_parameters() timegrid = iom.load_wavepacket_timegrid(blockid=blockid) time = timegrid * parameters["dt"] # The potential used Potential = BlockFactory().create_potential(parameters) # Basis transformator BT = BasisTransformationHAWP(Potential) # Basis shapes BS_descr = iom.load_wavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in BS_descr.iteritems(): BS[ahash] = BlockFactory().create_basis_shape(descr) # Initialize a Hagedorn wavepacket with the data descr = iom.load_wavepacket_description(blockid=blockid) HAWP = BlockFactory().create_wavepacket(descr) BT.set_matrix_builder(HAWP.get_quadrature()) # Store the resulting coefficients here CI = [[] for i in xrange(HAWP.get_number_components())] # Iterate over all timesteps, this is an *expensive* transformation for i, step in enumerate(timegrid): print(" Computing eigentransformation at timestep " + str(step)) # Retrieve simulation data params = iom.load_wavepacket_parameters(timestep=step, blockid=blockid) hashes, coeffs = iom.load_wavepacket_coefficients(timestep=step, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWP.set_parameters(params) HAWP.set_basis_shape([BS[int(ha)] for ha in hashes]) HAWP.set_coefficients(coeffs) # Transform to the eigenbasis. BT.transform_to_eigen(HAWP) for index, item in enumerate(HAWP.get_coefficients()): CI[index].append(item) CI = [transpose(hstack(item)) for item in CI] return time, CI
def plot_frames(PP, iom, blockid=0, eigentransform=False, timerange=None, view=None, plotphase=True, plotcomponents=False, plotabssqr=False, load=False, gridblockid=None, imgsize=(12, 9), path='.'): """Plot the wavepacket for a series of timesteps. :param iom: An :py:class:`IOManager` instance providing the simulation data. """ parameters = iom.load_parameters() BF = BlockFactory() if not parameters["dimension"] == 1: print("No one-dimensional wavepacket, silent return!") return if PP is None: PP = parameters if load is True: if gridblockid is None: gridblockid = blockid print("Loading grid data from datablock '{}'".format(gridblockid)) G = iom.load_grid(blockid=gridblockid) grid = real(G.reshape(-1)) else: print("Creating new grid") G = BlockFactory().create_grid(PP) grid = real(G.get_nodes(flat=True).reshape(-1)) if eigentransform: V = BF.create_potential(parameters) BT = BasisTransformationHAWP(V) timegrid = iom.load_wavepacket_timegrid(blockid=blockid) if timerange is not None: if len(timerange) == 1: I = (timegrid == timerange) else: I = ((timegrid >= timerange[0]) & (timegrid <= timerange[1])) if any(I): timegrid = timegrid[I] else: raise ValueError("No valid timestep remains!") # View if view is not None: if view[0] is None: view[0] = grid.min() if view[1] is None: view[1] = grid.max() for step in timegrid: print(" Plotting frame of timestep # {}".format(step)) HAWP = iom.load_wavepacket(step, blockid=blockid) # Transform the values to the eigenbasis if eigentransform: BT.transform_to_eigen(HAWP) values = HAWP.evaluate_at(G.get_nodes(), prefactor=True, component=0) # Plot fig = figure(figsize=imgsize) for index, component in enumerate(values): ax = fig.add_subplot(parameters["ncomponents"], 1, index + 1) ax.ticklabel_format(style="sci", scilimits=(0, 0), axis="y") if plotcomponents is True: ax.plot(grid, real(component)) ax.plot(grid, imag(component)) ax.set_ylabel(r"$\Re \varphi_{%d}, \Im \varphi_{%d}$" % (index, index)) if plotabssqr is True: ax.plot(grid, real(component * conj(component))) ax.set_ylabel(r"$\langle \varphi_{%d} | \varphi_{%d} \rangle$" % (index, index)) if plotphase is True: plotcf(grid, angle(component), real(component * conj(component))) ax.set_ylabel(r"$\langle \varphi_{%d} | \varphi_{%d} \rangle$" % (index, index)) ax.set_xlabel(r"$x$") # Set the aspect window ax.set_xlim(view[:2]) ax.set_ylim(view[2:]) if "dt" in parameters: fig.suptitle(r"$\Psi$ at time $%f$" % (step * parameters["dt"])) else: fig.suptitle(r"$\Psi$") fig.savefig(os.path.join(path, "wavepacket_block_%s_timestep_%07d.png" % (blockid, step))) close(fig)
def compute_eigenstate(parameters, filename="eigenstates.hdf5", computepq=True, computePQ=True): r""" Special variables necessary in configuration: * eigenstate_of_level (default: 0) * eigenstates_indices (default: [0]) * starting_point (default: (2, ..., 2)) * hawp_template * innerproduct """ D = parameters["dimension"] if "eigenstate_of_level" in parameters: N = parameters["eigenstate_of_level"] else: # Upper-most potential surface N = 0 # Create output file now, in case this fails we did not waste computation time IOM = IOManager() IOM.create_file(filename) # Save the simulation parameters IOM.add_parameters() IOM.save_parameters(parameters) gid = IOM.create_group() BF = BlockFactory() # Create the potential V = BF.create_potential(parameters) V.calculate_local_quadratic() # Compute position and momentum if computepq: # Minimize the potential to find q0 f = lambda x: real((squeeze(V.evaluate_at(x)[N]))) # Start with an offset because exact 0.0 values can give # issues, especially with the Hessian evaluation. This way # the minimizer will always stay away from zero a tiny bit. # The current starting point can give issues if the potential # is stationary at the point (2, ..., 2) but that is less likely. if "starting_point" in parameters: x0 = atleast_1d(parameters["starting_point"]) else: x0 = 0.5 * ones(D) q0 = fmin(f, x0, xtol=1e-12) q0 = q0.reshape((D, 1)) # We are at the minimum with no momentum p0 = zeros_like(q0) else: if "q0" in parameters: q0 = atleast_2d(parameters["q0"]) else: q0 = zeros((D, 1)) if "p0" in parameters: p0 = atleast_2d(parameters["p0"]) else: p0 = zeros((D, 1)) # Compute spreads if computePQ: # Q_0 = H^(-1/4) H = V.evaluate_hessian_at(q0) Q0 = inv(sqrtm(sqrtm(H))) # P_0 = i Q_0^(-1) P0 = 1.0j * inv(Q0) else: if "Q0" in parameters: Q0 = atleast_2d(parameters["Q0"]) else: Q0 = identity(D) if "P0" in parameters: P0 = atleast_2d(parameters["P0"]) else: P0 = 1.0j * inv(Q0) # The parameter set Pi print(70 * "-") print("Parameter values are:") print("---------------------") print(" q0:") print(str(q0)) print(" p0:") print(str(p0)) print(" Q0:") print(str(Q0)) print(" P0:") print(str(P0)) # Consistency check print(" Consistency check:") print(" P^T Q - Q^T P =?= 0") print(dot(P0.T, Q0) - dot(Q0.T, P0)) print(" Q^H P - P^H Q =?= 2i") print( dot(transpose(conjugate(Q0)), P0) - dot(transpose(conjugate(P0)), Q0)) # Next find the new coefficients c' HAWP = BF.create_wavepacket(parameters["hawp_template"]) # Set the parameter values Pi = HAWP.get_parameters() Pi[0] = q0 Pi[1] = p0 Pi[2] = Q0 Pi[3] = P0 HAWP.set_parameters(Pi) # Next compute the matrix M_ij = <phi_i | T + V | phi_j> # The potential part HQ = BF.create_inner_product(parameters["innerproduct"]) opV = lambda x, q, entry: V.evaluate_at(x, entry=entry) MV = HQ.build_matrix(HAWP, operator=opV) # The kinetic part MT = zeros_like(MV, dtype=complexfloating) GR = GradientHAWP() BS = HAWP.get_basis_shapes(component=N) vects = {} for i in BS: z = zeros_like(HAWP.get_coefficient_vector(), dtype=complexfloating) HAWP.set_coefficient_vector(z) HAWP.set_coefficient(N, i, 1.0) Kn, cnew = GR.apply_gradient(HAWP, component=N, as_packet=False) vects[i] = cnew for j in BS: for k in BS: cj = vects[j] ck = vects[k] entry = 0.5 * squeeze(sum(conjugate(cj) * ck)) MT[BS[j], BS[k]] = entry # Find eigenvalues and eigenvectors of the whole matrix M = MT + MV ew, ev = eigh(M) ind = argsort(ew) # Build the requested energy levels and states if "eigenstates_indices" in parameters: states = parameters["eigenstates_indices"] else: # Groundstate only states = [0] BS = HAWP.get_basis_shapes(component=0) KEY = ("q", "p", "Q", "P", "S", "adQ") print(70 * "-") for state in states: if state > BS.get_basis_size(): print( "Warning: can not compute energy level {} with basis size of {}" .format((state, BS))) continue index = ind[state] coeffs = ev[:, index] energy = ew[index] # Try to resolve ambiguities in sign imax = argmax(abs(coeffs)) a = abs(angle(coeffs[imax])) if a > pi / 2.0: coeffs *= -1 print("State: {}".format(state)) print("Energy: {}".format(energy)) print("Coefficients: \n") print(str(coeffs)) print(70 * "-") HAWP.set_coefficient_vector(coeffs.reshape((-1, 1))) # Save all the wavepacket data bid = IOM.create_block(groupid=gid) IOM.add_wavepacket(parameters, blockid=bid, key=KEY) IOM.save_wavepacket(HAWP, 0, blockid=bid, key=KEY) IOM.finalize() # TODO: Find better criterion if norm(q0) > 1000: print("+----------------------------------+") print("| Run-away minimum? |") print("| Maybe try different: |") print("| starting_point = [x0, y0, ...] |") print("+----------------------------------+")
def compute_evaluate_wavepackets(pp, iom, blockid=0, eigentrafo=True): """Evaluate a homogeneous Hagedorn wavepacket on a given grid for each timestep. :param pp: An :py:class:`ParameterProvider` instance providing the grid data. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param blockid: The data block from which the values are read. :param eigentrafo: Whether or not do an eigentransformation before evaluation is done. """ parameters = iom.load_parameters() if pp is None: pp = parameters # Number of time steps we saved timesteps = iom.load_wavepacket_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Prepare the potential for basis transformations Potential = BlockFactory().create_potential(parameters) grid = BlockFactory().create_grid(pp) # We want to save wavefunctions, thus add a data slot to the data file d = {"ncomponents": parameters["ncomponents"], "number_nodes": pp["number_nodes"], "dimension": parameters["dimension"]} iom.add_grid(d, blockid=blockid) iom.add_wavefunction(d, timeslots=nrtimesteps, flat=True, blockid=blockid) iom.save_grid(grid.get_nodes(), blockid=blockid) # Initialize a Hagedorn wavepacket with the data descr = iom.load_wavepacket_description(blockid=blockid) HAWP = BlockFactory().create_wavepacket(descr) # Basis transformator if eigentrafo is True: BT = BasisTransformationHAWP(Potential) BT.set_matrix_builder(HAWP.get_innerproduct()) # Basis shapes BS_descr = iom.load_wavepacket_basisshapes(blockid=blockid) BS = {} for ahash, descr in BS_descr.items(): BS[ahash] = BlockFactory().create_basis_shape(descr) WF = WaveFunction(parameters) WF.set_grid(grid) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Evaluating homogeneous wavepacket at timestep %d" % step) # Retrieve simulation data params = iom.load_wavepacket_parameters(timestep=step, blockid=blockid, key=("q", "p", "Q", "P", "S", "adQ")) hashes, coeffs = iom.load_wavepacket_coefficients(timestep=step, get_hashes=True, blockid=blockid) # Configure the wavepacket HAWP.set_parameters(params, key=("q", "p", "Q", "P", "S", "adQ")) HAWP.set_basis_shapes([BS[int(ha)] for ha in hashes]) HAWP.set_coefficients(coeffs) # Transform to the eigenbasis. if eigentrafo is True: BT.transform_to_eigen(HAWP) # Evaluate the wavepacket values = HAWP.evaluate_at(grid, prefactor=True) WF.set_values(values) # Save the wave function iom.save_wavefunction(WF.get_values(), timestep=step, blockid=blockid)
potvars = map(lambda x: ":math:`" + str(x) + "`", potvars) potvars = reduce(lambda a, b: a + ", " + b, potvars) if type(potdef["potential"]) == str: potformula = latex(sympify(potdef["potential"])) else: potformula = latex(Matrix(sympify(potdef["potential"]))) if potdef.has_key("defaults"): potdefaults = potdef["defaults"] else: potdefaults = {} # Create the potential "the right way" params["potential"] = potdef P = BlockFactory().create_potential(params) if len(potdef["variables"]) == 1: # Plot the potential values = P.evaluate_eigenvalues_at(x) figure(figsize=(4, 3)) for value in values: plot(squeeze(x), squeeze(value)) grid(True) xlabel(r"$x$") ylabel(r"$\lambda_i\left(x\right)$") xlim(min(x), max(x)) savefig(potdef["name"] + ".png") elif len(potdef["variables"]) == 2:
def compute_autocorrelation(iom, obsconfig=None, blockid=0, eigentrafo=True): """Compute the autocorrelation of a wavefunction timeseries. :param iom: An :py:class:`IOManager` instance providing the simulation data. :param obsconfig: Configuration parameters describing f.e. the inner product to use. :type obsconfig: A :py:class:`ParameterProvider` instance. Value has no effect in this class. :param blockid: The data block from which the values are read. :type blockid: Integer, Default is ``0`` :param eigentrafo: Whether to make a transformation into the eigenbasis. :type eigentrafo: Boolean, default is ``True``. """ parameters = iom.load_parameters() # Number of time steps we saved timesteps = iom.load_wavefunction_timegrid(blockid=blockid) nrtimesteps = timesteps.shape[0] # Construct the grid from the parameters grid = BlockFactory().create_grid(parameters) # Basis transformator if eigentrafo is True: # The potential used Potential = BlockFactory().create_potential(parameters) BT = BasisTransformationWF(Potential) BT.set_grid(grid) # And two empty wavefunctions WFo = WaveFunction(parameters) WFo.set_grid(grid) WFt = WaveFunction(parameters) WFt.set_grid(grid) # We want to save norms, thus add a data slot to the data file iom.add_autocorrelation(parameters, timeslots=nrtimesteps, blockid=blockid) # Preconfigure the values = iom.load_wavefunction(timestep=0, blockid=blockid) values = [values[j, ...] for j in range(parameters["ncomponents"])] WFo.set_values(values) # Project wavefunction values to eigenbasis if eigentrafo is True: BT.transform_to_eigen(WFo) # Fourier transform the values WFo.set_values([fftn(value) for value in WFo.get_values()]) # Iterate over all timesteps for i, step in enumerate(timesteps): print(" Computing autocorrelations of timestep %d" % step) # Retrieve simulation data values = iom.load_wavefunction(timestep=step, blockid=blockid) values = [values[j, ...] for j in range(parameters["ncomponents"])] WFt.set_values(values) # Project wavefunction values to eigenbasis if eigentrafo is True: BT.transform_to_eigen(WFt) # Fourier transform the values WFt.set_values([fftn(value) for value in WFt.get_values()]) # Compute the prefactor T = grid.get_extensions() N = grid.get_number_nodes() prefactor = product(array(T) / array(N).astype(floating)**2) # Compute the autocorrelation # TODO: Consider splitting into cases `fft` versus `fftn` valueso = WFo.get_values() valuest = WFt.get_values() acs = [ prefactor * ifftn(sum(conjugate(valueso[n]) * valuest[n])) for n in range(parameters["ncomponents"]) ] iom.save_autocorrelation(acs, timestep=step, blockid=blockid)