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)
Exemple #2
0
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")
Exemple #3
0
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
Exemple #7
0
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)
Exemple #8
0
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)
Exemple #9
0
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
Exemple #12
0
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)
Exemple #13
0
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
Exemple #14
0
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)
Exemple #17
0
    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:
Exemple #19
0
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("+----------------------------------+")
Exemple #20
0
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)
Exemple #24
0
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")
Exemple #26
0
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)
Exemple #27
0
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)
Exemple #29
0
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)
Exemple #31
0
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)
Exemple #32
0
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 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)
Exemple #34
0
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)
Exemple #38
0
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)
Exemple #42
0
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)
Exemple #46
0
    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)