示例#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
示例#2
0
 def __init__(self, wf_params):
     self.l, self.N = wf_params[:2]
     self.wf = WaveFunction(wf_params)
     eta = self.wf.eta
     self.eta_add = np.add.outer(eta, eta)
     self.conj_eta_add = np.add.outer(eta.conj(), eta)
     self.eta_mult = np.multiply.outer(eta, eta)
     self.conj_eta_mult = np.multiply.outer(eta.conj(), eta)
     self.N_cos_ij = np.multiply.outer(self.wf.N_cos, self.wf.N_cos)
示例#3
0
    def __init__(self, system_params, wf_params, potential_params, r):
        system = NuclearSystem(wf_params, system_params, potential_params)
        system.calculate_energy()
        self.bound_energy = system.energies[0]

        wf = WaveFunction(wf_params)
        radial_wavefunctions = r * np.matmul(system.C.transpose(), wf.phi(r))
        self.bound_wavefunction = np.abs(radial_wavefunctions[0, :])

        k = np.sqrt(-2 * self.bound_energy * system.mass / system.const1)
        eta = system.mass * system.z1 * system.z2 * system.const2 / k / system.const1

        self.whitw_ = np.array(
            [whitw(-eta, wf.l + 0.5, 2 * k * r_i) for r_i in r], dtype=float)
示例#4
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
示例#5
0
class MatrixElements:
    def __init__(self, wf_params):
        self.l, self.N = wf_params[:2]
        self.wf = WaveFunction(wf_params)
        eta = self.wf.eta
        self.eta_add = np.add.outer(eta, eta)
        self.conj_eta_add = np.add.outer(eta.conj(), eta)
        self.eta_mult = np.multiply.outer(eta, eta)
        self.conj_eta_mult = np.multiply.outer(eta.conj(), eta)
        self.N_cos_ij = np.multiply.outer(self.wf.N_cos, self.wf.N_cos)

    def overlap_matrix(self):
        AL = np.power(1 / self.eta_add, self.l + 1.5)
        BL = np.power(1 / self.conj_eta_add, self.l + 1.5)
        return self.calc_mat_elems(AL, BL) * gamma(self.l + 1.5) / 2

    def kinetic_pot(self, const1, mass):
        AH0 = np.divide(self.eta_mult, np.power(self.eta_add, self.l + 2.5))
        BH0 = np.divide(self.conj_eta_mult,
                        np.power(self.conj_eta_add, self.l + 2.5))
        return self.calc_mat_elems(
            AH0, BH0) * const1 / mass * (self.l + 1.5) * gamma(self.l + 1.5)

    def nuclear_pot(self, potential_params):
        V0, Vso, S, J, R0, Rso, a0, aso = potential_params
        LS = J * (J + 1) - self.l * (self.l + 1) - S * (S + 1)
        r_step = 0.1
        r = np.arange(1e-6, 15, r_step)
        V1 = V0 * self.woods_saxon(a0, R0, r)
        V2 = 2 * Vso * LS / aso * np.exp(
            (r - Rso) / aso) * np.power(self.woods_saxon(aso, Rso, r), 2) / r
        return np.einsum("ir, r, jr -> ij", self.wf.phi(r),
                         (V1 + V2) * r**2, self.wf.phi(r)) * r_step

    def coulomb_pot(self, z1, z2, const2, Rc):
        Vc_0_Rc = self.V_coul_from_0_to_Rc(Rc)
        Vc_Rc_Inf = self.V_coul_from_Rc_to_Inf(Rc)
        return z1 * z2 * const2 * (Vc_0_Rc + Vc_Rc_Inf)

    def V_coul_from_0_to_Rc(self, Rc):
        AVc = 3 * self.integral_0_b(Rc, 2 * self.l + 2, self.eta_add) - \
              1 / Rc**2 * self.integral_0_b(Rc, 2 * self.l + 4, self.eta_add)
        BVc = 3 * self.integral_0_b(Rc, 2 * self.l + 2, self.conj_eta_add) - \
              1 / Rc**2 * self.integral_0_b(Rc, 2 * self.l + 4, self.conj_eta_add)
        return self.calc_mat_elems(AVc, BVc) / 2 / Rc

    def V_coul_from_Rc_to_Inf(self, Rc):
        # $\int_b^\Inf = \int_0^\Inf - \int_0^b$
        AVc = np.power(1 / self.eta_add, self.l + 1) * factorial(self.l) / 2 - \
              self.integral_0_b(Rc, 2 * self.l + 1, self.eta_add)
        BVc = np.power(1 / self.conj_eta_add, self.l + 1) * factorial(self.l) / 2 - \
              self.integral_0_b(Rc, 2 * self.l + 1, self.conj_eta_add)
        return self.calc_mat_elems(AVc, BVc)

    def calc_mat_elems(self, A, B):
        return (A + A.conj() + B + B.conj()).real * self.N_cos_ij / 4

    @staticmethod
    def woods_saxon(a, R, r):
        return 1 / (1 + np.exp((r - R) / a))

    @staticmethod
    def integral_0_b(b, n, a):
        if n == 0:
            return 0.5 * np.sqrt(np.pi / a) * erf(np.sqrt(a) * b)
        if n == 1:
            return (1 - np.exp(-a * b**2)) / 2 / a
        return (n - 1) / 2 / a * MatrixElements.integral_0_b(
            b, n - 2, a) - b**(n - 1) / 2 / a * np.exp(-a * b**2)
    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)