示例#1
0
    def initialize_for_fourier(self, grid):
        # NOTE: This code is only temporary until we get the
        #       more versatile initial value specifications.

        # TODO: Make a specification of the IV setup in configurations
        Psi = []

        for packet_descr in self._parameters["initvals"]:
            packet = BlockFactory().create_wavepacket(packet_descr)

            # Evaluate the
            X = grid.get_nodes(flat=True)
            values = packet.evaluate_at(X, prefactor=True)

            # Reshape values into hypercubic shape
            values = [ val.reshape(grid.get_number_nodes()) for val in values ]
            Psi.append( values )

        # TODO: Maybe sum up immediately instead of at the end to reduce memory usage
        Psi = reduce(lambda x,y: x+y, Psi)

        # Pack the values in a WaveFunction instance
        WF = WaveFunction(self._parameters)
        WF.set_grid(grid)
        WF.set_values(Psi)

        return WF
    def prepare_simulation(self):
        r"""
        Set up a Fourier propagator for the simulation loop. Set the
        potential and initial values according to the configuration.

        :raise ValueError: For invalid or missing input data.
        """
        # Compute the position space grid points
        nodes = self.parameters["f"] * sp.pi * sp.arange(-1, 1, 2.0/self.parameters["ngn"], dtype=np.complexfloating)

        # The potential instance
        potential = PF().create_potential(self.parameters)

        # Check for enough initial values
        if not self.parameters.has_key("initial_values"):
            if len(self.parameters["parameters"]) < potential.get_number_components():
                raise ValueError("Too few initial states given. Parameters are missing.")

            if len(self.parameters["coefficients"]) < potential.get_number_components():
                raise ValueError("Too few initial states given. Coefficients are missing.")

        # Calculate the initial values sampled from a hagedorn wave packet
        d = dict([("ncomponents", 1), ("basis_size", self.parameters["basis_size"]), ("eps", self.parameters["eps"])])

        # Initial values given in the "fourier" specific format
        if self.parameters.has_key("initial_values"):
            initialvalues = [ np.zeros(nodes.shape, dtype=np.complexfloating) for i in xrange(self.parameters["ncomponents"]) ]

            for level, params, coeffs in self.parameters["initial_values"]:
                hwp = HagedornWavepacket(d)
                hwp.set_parameters(params)

                for index, value in coeffs:
                    hwp.set_coefficient(0, index, value)

                iv = hwp.evaluate_at(nodes, component=0, prefactor=True)

                initialvalues[level] = initialvalues[level] + iv

        # Initial value read in compatibility mode to the packet algorithms
        else:
            # See if we have a list of parameter tuples or just a single 5-tuple
            # This is for compatibility with the inhomogeneous case.
            try:
                # We have a list of parameter tuples this is ok for the loop below
                len(self.parameters["parameters"][0])
                parameters = self.parameters["parameters"]
            except TypeError:
                # We have just a single 5-tuple of parameters, we need to replicate for looping
                parameters = [ self.parameters["parameters"] for i in xrange(self.parameters["ncomponents"]) ]

            initialvalues = []

            for level, item in enumerate(parameters):
                hwp = HagedornWavepacket(d)
                hwp.set_parameters(item)

                # Set the coefficients of the basis functions
                for index, value in self.parameters["coefficients"][level]:
                    hwp.set_coefficient(0, index, value)

                iv = hwp.evaluate_at(nodes, component=0, prefactor=True)

                initialvalues.append(iv)

        # Project the initial values to the canonical basis
        initialvalues = potential.project_to_canonical(nodes, initialvalues)

        # Store the initial values in a WaveFunction object
        IV = WaveFunction(self.parameters)
        IV.set_grid(nodes)
        IV.set_values(initialvalues)

        # Finally create and initialize the propagator instace
        self.propagator = FourierPropagator(potential, IV, self.parameters)

        # Which data do we want to save
        tm = self.parameters.get_timemanager()
        slots = tm.compute_number_saves()

        print(tm)

        self.IOManager.add_grid(self.parameters, blockid="global")
        self.IOManager.add_fourieroperators(self.parameters)
        self.IOManager.add_wavefunction(self.parameters, timeslots=slots)

        # Write some initial values to disk
        self.IOManager.save_grid(nodes, blockid="global")
        self.IOManager.save_fourieroperators(self.propagator.get_operators())
        self.IOManager.save_wavefunction(IV.get_values(), timestep=0)