Esempio n. 1
0
 def sendreceive(self, a, dest, b, src, sendtag=123, recvtag=123):
     assert 0 <= dest < self.size
     assert dest != self.rank
     assert is_contiguous(a)
     assert 0 <= src < self.size
     assert src != self.rank
     assert is_contiguous(b)
     return self.comm.sendreceive(a, dest, b, src, sendtag, recvtag)
Esempio n. 2
0
 def sendreceive(self, a, dest, b, src, sendtag=123, recvtag=123):
     assert 0 <= dest < self.size
     assert dest != self.rank
     assert is_contiguous(a)
     assert 0 <= src < self.size
     assert src != self.rank
     assert is_contiguous(b)
     return self.comm.sendreceive(a, dest, b, src, sendtag, recvtag)
    def apply(self, input, output=None, phases=None):
        assert is_contiguous(input, self.dtype)
        assert input.shape[-3:] == self.ngpin
        if output is not None:
            assert is_contiguous(output, self.dtype)
            assert output.shape[-3:] == self.ngpout
        assert self.dtype == float or (phases.dtype == complex and phases.shape == (3, 2))

        return self.transformer.apply(input, output, phases)
Esempio n. 4
0
    def apply(self, input, output=None, phases=None):
        assert is_contiguous(input, self.dtype)
        assert input.shape[-3:] == self.ngpin
        if output is not None:
            assert is_contiguous(output, self.dtype)
            assert output.shape[-3:] == self.ngpout
        assert (self.dtype == float
                or (phases.dtype == complex and phases.shape == (3, 2)))

        return self.transformer.apply(input, output, phases)
Esempio n. 5
0
    def apply(self, input, output, phases=None):
        assert is_contiguous(input, self.dtype)
        assert is_contiguous(output, self.dtype)
        assert input.shape[-3:] == self.ngpin
        assert output.shape[-3:] == self.ngpout
        assert (self.dtype == float or
                (phases.dtype == complex and
                 phases.shape == (3, 2)))

        assert self.allocated
        self.transformer.apply(input, output, phases)
Esempio n. 6
0
    def add_density(self, n_G, f_i):
        """Add atomic electron density to extended density array.

        Special method for adding the atomic electron density
        calculated from atomic orbitals and occupation numbers
        f_i."""
        
        assert is_contiguous(n_G, float)
        assert is_contiguous(f_i, float)
        assert n_G.shape == self.shape
        assert f_i.shape == (self.ni,)
        self.lfs.add_density(n_G, f_i)
Esempio n. 7
0
    def add(self, coef_xi, a_xg):
        """Add localized functions to extended arrays.

        Add the product of coef_xi and the localized functions to
        a_xg."""
        
        assert is_contiguous(a_xg, self.dtype)
        assert is_contiguous(coef_xi, self.dtype)
        assert a_xg.shape[:-3] == coef_xi.shape[:-1]
        assert a_xg.shape[-3:] == self.shape
        assert coef_xi.shape[-1] == self.ni
        self.lfs.add(coef_xi, a_xg)
Esempio n. 8
0
    def integrate(self, a_xg, result_xi):
        """Calculate integrals of arrays times localized functions.

        Return the integral of extended arrays times localized
        functions in result_xi."""
        
        assert is_contiguous(a_xg, self.dtype)
        assert is_contiguous(result_xi, self.dtype)
        assert a_xg.shape[:-3] == result_xi.shape[:-1]
        assert a_xg.shape[-3:] == self.shape
        assert result_xi.shape[-1] == self.ni
        self.lfs.integrate(a_xg, result_xi)
Esempio n. 9
0
    def add(self, coef_xi, a_xg):
        """Add localized functions to extended arrays.

        Add the product of coef_xi and the localized functions to
        a_xg."""

        assert is_contiguous(a_xg, self.dtype)
        assert is_contiguous(coef_xi, self.dtype)
        assert a_xg.shape[:-3] == coef_xi.shape[:-1]
        assert a_xg.shape[-3:] == self.shape
        assert coef_xi.shape[-1] == self.ni
        self.lfs.add(coef_xi, a_xg)
Esempio n. 10
0
    def add_density(self, n_G, f_i):
        """Add atomic electron density to extended density array.

        Special method for adding the atomic electron density
        calculated from atomic orbitals and occupation numbers
        f_i."""

        assert is_contiguous(n_G, float)
        assert is_contiguous(f_i, float)
        assert n_G.shape == self.shape
        assert f_i.shape == (self.ni, )
        self.lfs.add_density(n_G, f_i)
Esempio n. 11
0
    def integrate(self, a_xg, result_xi):
        """Calculate integrals of arrays times localized functions.

        Return the integral of extended arrays times localized
        functions in result_xi."""

        assert is_contiguous(a_xg, self.dtype)
        assert is_contiguous(result_xi, self.dtype)
        assert a_xg.shape[:-3] == result_xi.shape[:-1]
        assert a_xg.shape[-3:] == self.shape
        assert result_xi.shape[-1] == self.ni
        self.lfs.integrate(a_xg, result_xi)
Esempio n. 12
0
    def dump(self, filename):
        if debug:
            assert is_contiguous(self.Fnt_wsG, self.dtype)
            assert is_contiguous(self.Ant_sG, float)

        all_Fnt_wsG = self.gd.collect(self.Fnt_wsG)
        all_Ant_sG = self.gd.collect(self.Ant_sG)

        if self.world.rank == 0:
            all_Fnt_wsG.dump(filename)
            all_Ant_sG.dump(filename+'_avg') # crude but easy
            self.omega_w.dump(filename+'_omega') # crude but easy
            self.gamma_w.dump(filename+'_gamma') # crude but easy
Esempio n. 13
0
    def dump(self, filename):
        if debug:
            assert is_contiguous(self.Fnt_wsG, self.dtype)
            assert is_contiguous(self.Ant_sG, float)

        all_Fnt_wsG = self.gd.collect(self.Fnt_wsG)
        all_Ant_sG = self.gd.collect(self.Ant_sG)

        if self.world.rank == 0:
            all_Fnt_wsG.dump(filename)
            all_Ant_sG.dump(filename + '_avg')  # crude but easy
            self.omega_w.dump(filename + '_omega')  # crude but easy
            self.gamma_w.dump(filename + '_gamma')  # crude but easy
Esempio n. 14
0
    def derivative(self, a_xg, result_xic):
        """Calculate x-, y-, z-derivatives of localized integrals.

        Return the *x*- *y*- and *z*-derivatives of the integral of
        extended arrays times localized functions in
        result_xic."""

        assert self.forces
        assert is_contiguous(a_xg, self.dtype)
        assert is_contiguous(result_xic, self.dtype)
        assert a_xg.shape[:-3] == result_xic.shape[:-2]
        assert a_xg.shape[-3:] == self.shape
        assert result_xic.shape[-2:] == (self.ni, 3)
        self.lfs.derivative(a_xg, result_xic)
Esempio n. 15
0
    def derivative(self, a_xg, result_xic):
        """Calculate x-, y-, z-derivatives of localized integrals.

        Return the *x*- *y*- and *z*-derivatives of the integral of
        extended arrays times localized functions in
        result_xic."""

        assert self.forces
        assert is_contiguous(a_xg, self.dtype)
        assert is_contiguous(result_xic, self.dtype)
        assert a_xg.shape[:-3] == result_xic.shape[:-2]
        assert a_xg.shape[-3:] == self.shape
        assert result_xic.shape[-2:] == (self.ni, 3)
        self.lfs.derivative(a_xg, result_xic)
Esempio n. 16
0
    def add_density2(self, n_G, D_p):
        """Add atomic electron density to extended density array.
        
        Special method for adding the atomic electron density
        calculated from all cross products of atomic orbitals
        weighted using the density matrix D_p.

        The method returns the integral of the atomic electron density
        """

        assert is_contiguous(n_G, float)
        assert is_contiguous(D_p, float)
        assert n_G.shape == self.shape
        assert D_p.shape == (self.ni * (self.ni + 1) / 2, )
        return self.lfs.add_density2(n_G, D_p)
Esempio n. 17
0
    def add_density2(self, n_G, D_p):
        """Add atomic electron density to extended density array.
        
        Special method for adding the atomic electron density
        calculated from all cross products of atomic orbitals
        weighted using the density matrix D_p.

        The method returns the integral of the atomic electron density
        """
        
        assert is_contiguous(n_G, float)
        assert is_contiguous(D_p, float)
        assert n_G.shape == self.shape
        assert D_p.shape == (self.ni * (self.ni + 1) / 2,)
        return self.lfs.add_density2(n_G, D_p)
 def allocate(self):
     if not self.allocated:
         
         # Ground state pseudo density
         self.n0t_sG = self.density.nt_sG.copy()
         
         # Fourier transformed pseudo density
         self.Fnt_wsG = self.gd.zeros((self.nw, self.nspins),
                                      dtype=self.dtype)
 
         # Ground state D_asp
         self.D0_asp = {}
         for a, D_sp in self.density.D_asp.items():
             self.D0_asp[a] = D_sp.copy()
         
         # Size of D_p for each atom
         self.np_a = {}
         for a, D_sp in self.D0_asp.items():
             self.np_a[a] = np.array(len(D_sp[0]))
         
         # Fourier transformed D_asp
         self.FD_awsp = {}
         for a, np_ in self.np_a.items():
             self.FD_awsp[a] = np.zeros((self.nw, self.nspins, np_),
                                        dtype=self.dtype)
         
         self.allocated = True
         
     if debug:
         assert is_contiguous(self.Fnt_wsG, self.dtype)
Esempio n. 19
0
    def new_communicator(self, ranks):
        """Create a new MPI communicator for a subset of ranks in a group.
        Must be called with identical arguments by all relevant processes.

        Note that a valid communicator is only returned to the processes
        which are included in the new group; other ranks get None returned.

        Parameters:

        ranks: ndarray (type int)
            List of integers of the ranks to include in the new group.
            Note that these ranks correspond to indices in the current
            group whereas the rank attribute in the new communicators
            correspond to their respective index in the subset.

        """
        assert is_contiguous(ranks, int)
        sranks = np.sort(ranks)
        # Are all ranks in range?
        assert 0 <= sranks[0] and sranks[-1] < self.size
        # No duplicates:
        for i in range(len(sranks) - 1):
            assert sranks[i] != sranks[i + 1]
        assert len(ranks) > 0
        
        comm = self.comm.new_communicator(ranks)
        if comm is None:
            # This cpu is not in the new communicator:
            return None
        else:
            return _Communicator(comm, parent=self)
Esempio n. 20
0
 def send(self, a, dest, tag=123, block=True):
     assert 0 <= dest < self.size
     assert dest != self.rank
     assert is_contiguous(a)
     if not block:
         pass #assert sys.getrefcount(a) > 3
     return self.comm.send(a, dest, tag, block)
Esempio n. 21
0
    def product(self, a, root=-1):
        """Do multiplication by MPI reduce operations of numerical data.

        Parameters:

        a: ndarray or value (type int or float)
            Numerical data to multiply across all ranks in the communicator
            group. NB: Find the global product from the local products.
            If the data is a single value of type int or float (no complex),
            the result is returned because the input argument is immutable.
            Otherwise, the reduce operation is carried out in-place such
            that the elements of the input array will represent the product
            of the equivalent elements across all processes in the group.
        root: int (default -1)
            Rank of the root process, on which the outcome of the reduce
            operation is valid. A root rank of -1 signifies that the result
            will be distributed back to all processes, i.e. a broadcast.

        """
        if isinstance(a, (int, float)):
            return self.comm.product(a, root)
        else:
            tc = a.dtype
            assert tc == int or tc == float
            assert is_contiguous(a, tc)
            assert root == -1 or 0 <= root < self.size
            self.comm.product(a, root)
Esempio n. 22
0
    def product(self, a, root=-1):
        """Do multiplication by MPI reduce operations of numerical data.

        Parameters:

        a: ndarray or value (type int or float)
            Numerical data to multiply across all ranks in the communicator
            group. NB: Find the global product from the local products.
            If the data is a single value of type int or float (no complex),
            the result is returned because the input argument is immutable.
            Otherwise, the reduce operation is carried out in-place such
            that the elements of the input array will represent the product
            of the equivalent elements across all processes in the group.
        root: int (default -1)
            Rank of the root process, on which the outcome of the reduce
            operation is valid. A root rank of -1 signifies that the result
            will be distributed back to all processes, i.e. a broadcast.

        """
        if isinstance(a, (int, float)):
            return self.comm.product(a, root)
        else:
            tc = a.dtype
            assert tc == int or tc == float
            assert is_contiguous(a, tc)
            assert root == -1 or 0 <= root < self.size
            self.comm.product(a, root)
Esempio n. 23
0
    def allocate(self):
        if not self.allocated:

            # Ground state pseudo density
            self.n0t_sG = self.density.nt_sG.copy()

            # Fourier transformed pseudo density
            self.Fnt_wsG = self.gd.zeros((self.nw, self.nspins),
                                         dtype=self.dtype)

            # Ground state D_asp
            self.D0_asp = {}
            for a, D_sp in self.density.D_asp.items():
                self.D0_asp[a] = D_sp.copy()

            # Size of D_p for each atom
            self.np_a = {}
            for a, D_sp in self.D0_asp.items():
                self.np_a[a] = np.array([len(D_sp[0])])

            # Fourier transformed D_asp
            self.FD_awsp = {}
            for a, np_ in self.np_a.items():
                self.FD_awsp[a] = np.zeros((self.nw, self.nspins, np_[0]),
                                           dtype=self.dtype)

            self.allocated = True

        if debug:
            assert is_contiguous(self.Fnt_wsG, self.dtype)
Esempio n. 24
0
 def send(self, a, dest, tag=123, block=True):
     assert 0 <= dest < self.size
     assert dest != self.rank
     assert is_contiguous(a)
     if not block:
         pass  # assert sys.getrefcount(a) > 3
     return self.comm.send(a, dest, tag, block)
Esempio n. 25
0
def dotu(a, b):
    """Dot product, NOT conjugating the first vector with complex arguments.

    Returns the value of the operation::

        _
       \ 
        ) a       * b
       /_  ijk...    ijk...
       ijk...


    """
    assert ((is_contiguous(a, float) and is_contiguous(b, float)) or
            (is_contiguous(a, complex) and is_contiguous(b,complex)))
    assert a.shape == b.shape
    return _gpaw.dotu(a, b)
Esempio n. 26
0
def dotu(a, b):
    """Dot product, NOT conjugating the first vector with complex arguments.

    Returns the value of the operation::

        _
       \
        ) a       * b
       /_  ijk...    ijk...
       ijk...


    """
    assert ((is_contiguous(a, float) and is_contiguous(b, float)) or
            (is_contiguous(a, complex) and is_contiguous(b, complex)))
    assert a.shape == b.shape
    return _gpaw.dotu(a, b)
Esempio n. 27
0
def axpy(alpha, x, y):
    """alpha x plus y.

    Performs the operation::

      y <- alpha * x + y
      
    """
    if isinstance(alpha, complex):
        assert is_contiguous(x, complex) and is_contiguous(y, complex)
    else:
        assert isinstance(alpha, float)
        assert x.dtype in [float, complex]
        assert x.dtype == y.dtype
        assert x.flags.contiguous and y.flags.contiguous
    assert x.shape == y.shape
    _gpaw.axpy(alpha, x, y)
Esempio n. 28
0
def axpy(alpha, x, y):
    """alpha x plus y.

    Performs the operation::

      y <- alpha * x + y
      
    """
    if isinstance(alpha, complex):
        assert is_contiguous(x, complex) and is_contiguous(y, complex)
    else:
        assert isinstance(alpha, float)
        assert x.dtype in [float, complex]
        assert x.dtype == y.dtype
        assert x.flags.contiguous and y.flags.contiguous
    assert x.shape == y.shape
    _gpaw.axpy(alpha, x, y)
Esempio n. 29
0
def czher(alpha, x, a):
    """alpha x * x.conj() + a.

    Performs the operation::

      y <- alpha * x * x.conj() + a

    where x is a N element vector and a is a N by N hermitian matrix, alpha
    is a real scalar.
    """

    assert isinstance(alpha, float)
    assert is_contiguous(x, complex) and is_contiguous(a, complex)
    assert x.flags.contiguous and a.flags.contiguous
    assert x.ndim == 1 and a.ndim == 2
    assert x.shape[0] == a.shape[0]

    _gpaw.czher(alpha, x, a)
Esempio n. 30
0
def czher(alpha, x, a):
    """alpha x * x.conj() + a.

    Performs the operation::

      y <- alpha * x * x.conj() + a

    where x is a N element vector and a is a N by N hermitian matrix, alpha is a real scalar
      
    """

    assert isinstance(alpha, float)
    assert is_contiguous(x, complex) and is_contiguous(a, complex)
    assert x.flags.contiguous and a.flags.contiguous
    assert x.ndim == 1 and a.ndim == 2
    assert x.shape[0] == a.shape[0]

    _gpaw.czher(alpha, x, a)
Esempio n. 31
0
    def load(self, filename):
        if self.world.rank == 0:
            all_Fnt_wsG = np.load(filename)
            all_Ant_sG = np.load(filename+'_avg') # crude but easy
        else:
            all_Fnt_wsG = None
            all_Ant_sG = None

        if debug:
            assert all_Fnt_wsG is None or is_contiguous(all_Fnt_wsG, self.dtype)
            assert all_Ant_sG is None or is_contiguous(all_Ant_sG, float)

        if not self.allocated:
            self.allocate()

        self.gd.distribute(all_Fnt_wsG, self.Fnt_wsG)
        self.gd.distribute(all_Ant_sG, self.Ant_sG)

        self.omega_w = np.load(filename+'_omega') # crude but easy
        self.gamma_w = np.load(filename+'_gamma') # crude but easy
Esempio n. 32
0
    def load(self, filename):
        if self.world.rank == 0:
            all_Fnt_wsG = np.load(filename)
            all_Ant_sG = np.load(filename + '_avg')  # crude but easy
        else:
            all_Fnt_wsG = None
            all_Ant_sG = None

        if debug:
            assert all_Fnt_wsG is None or is_contiguous(
                all_Fnt_wsG, self.dtype)
            assert all_Ant_sG is None or is_contiguous(all_Ant_sG, float)

        if not self.allocated:
            self.allocate()

        self.gd.distribute(all_Fnt_wsG, self.Fnt_wsG)
        self.gd.distribute(all_Ant_sG, self.Ant_sG)

        self.omega_w = np.load(filename + '_omega')  # crude but easy
        self.gamma_w = np.load(filename + '_gamma')  # crude but easy
Esempio n. 33
0
    def allocate(self):
        if not self.allocated:
            self.Fnt_wsG = self.gd.zeros((self.nw, self.nspins), \
                                        dtype=self.dtype)
            self.Fnt_wsg = None
            #self.Ant_sG = ...
            self.Ant_sg = None
            self.gamma_w = np.ones(self.nw, dtype=complex) * self.timestep
            self.allocated = True

        if debug:
            assert is_contiguous(self.Fnt_wsG, self.dtype)
Esempio n. 34
0
    def allocate(self):
        if not self.allocated:
            self.Fnt_wsG = self.gd.zeros((self.nw, self.nspins), \
                                        dtype=self.dtype)
            self.Fnt_wsg = None
            #self.Ant_sG = ...
            self.Ant_sg = None
            self.gamma_w = np.ones(self.nw, dtype=complex) * self.timestep
            self.allocated = True

        if debug:
            assert is_contiguous(self.Fnt_wsG, self.dtype)
Esempio n. 35
0
    def allocate(self):
        if not self.allocated:

            poisson = self.paw.hamiltonian.poisson
            # Ground state charge density
            self.n0_G = (-1.0 * poisson.classical_material.sign *
                         poisson.classical_material.charge_density.copy())

            # Fourier transformed charge density
            self.Fn_wG = poisson.cl.gd.zeros((self.nw, ), dtype=self.dtype)
            self.allocated = True

        if debug:
            assert is_contiguous(self.Fn_wG, self.dtype)
Esempio n. 36
0
def scal(alpha, x):
    """alpha x

    Performs the operation::

      x <- alpha * x 
      
    """
    if isinstance(alpha, complex):
        assert is_contiguous(x, complex)
    else:
        assert isinstance(alpha, float)
        assert x.dtype in [float, complex]
        assert x.flags.contiguous
    _gpaw.scal(alpha, x)
 def allocate(self):
     if not self.allocated:
         
         # Ground state charge density
         self.n0_G = (-1.0) * self.paw.hamiltonian.poisson.classical_material.sign * \
                              self.paw.hamiltonian.poisson.classical_material.charge_density.copy()
         
         # Fourier transformed charge density
         self.Fn_wsG = self.paw.hamiltonian.poisson.cl.gd.zeros((self.nw, self.nspins),
                                                                dtype=self.dtype)
 
         self.allocated = True
         
     if debug:
         assert is_contiguous(self.Ft_wG, self.dtype)
Esempio n. 38
0
def scal(alpha, x):
    """alpha x

    Performs the operation::

      x <- alpha * x
      
    """
    if isinstance(alpha, complex):
        assert is_contiguous(x, complex)
    else:
        assert isinstance(alpha, float)
        assert x.dtype in [float, complex]
        assert x.flags.contiguous
    _gpaw.scal(alpha, x)
Esempio n. 39
0
    def get_functions(self, gd, start_c, end_c, spos_c):
        h_cv = gd.h_cv
        # start_c is the new origin so we translate gd.beg_c to start_c
        origin_c = np.array([0, 0, 0])
        pos_v = np.dot(spos_c, gd.cell_cv) - np.dot(start_c, h_cv)
        A_gm, G_b = _gpaw.spline_to_grid(self.spline, origin_c, end_c - start_c, pos_v, h_cv, end_c - start_c, origin_c)

        if debug:
            assert G_b.ndim == 1 and G_b.shape[0] % 2 == 0
            assert is_contiguous(G_b, np.intc)
            assert A_gm.shape[:-1] == np.sum(G_b[1::2] - G_b[::2])

        indices_gm, ng, nm = self.spline.get_indices_from_zranges(start_c, end_c, G_b)
        shape = (nm,) + tuple(end_c - start_c)
        work_mB = np.zeros(shape, dtype=A_gm.dtype)
        np.put(work_mB, indices_gm, A_gm)
        return work_mB
Esempio n. 40
0
    def get_functions(self, gd, start_c, end_c, spos_c):
        h_cv = gd.h_cv
        # start_c is the new origin so we translate gd.beg_c to start_c
        origin_c = np.array([0,0,0])
        pos_v = np.dot(spos_c, gd.cell_cv) - np.dot(start_c, h_cv)
        A_gm, G_b = _gpaw.spline_to_grid(self.spline, origin_c, end_c-start_c,
                                         pos_v, h_cv, end_c-start_c, origin_c)

        if debug:
            assert G_b.ndim == 1 and G_b.shape[0] % 2 == 0
            assert is_contiguous(G_b, np.intc)
            assert A_gm.shape[:-1] == np.sum(G_b[1::2]-G_b[::2])

        indices_gm, ng, nm = self.spline.get_indices_from_zranges(start_c,
                                                                  end_c, G_b)
        shape = (nm,) + tuple(end_c-start_c)
        work_mB = np.zeros(shape, dtype=A_gm.dtype)
        np.put(work_mB, indices_gm, A_gm)
        return work_mB
Esempio n. 41
0
    def broadcast(self, a, root):
        """Share data from a single process to all ranks in a group.

        Parameters:

        a: ndarray
            Data, i.e. send buffer on root rank, receive buffer elsewhere.
            Note that after the broadcast, all ranks have the same data.
        root: int
            Rank of the root process, from which the data is to be shared.

        Example::

          # All ranks have parts of interesting data. Take a given index.
          mydata[:] = np.random.normal(size=N)

          # Who has the element at global index 13? Everybody needs it!
          index = 13
          root, myindex = divmod(index, N)
          element = np.empty(1, dtype=float)
          if comm.rank == root:
              # This process has the requested element so extract it
              element[:] = mydata[myindex]

          # Broadcast from owner to everyone else
          comm.broadcast(element, root)

          # .. which is equivalent to ..

          if comm.rank == root:
              # We are root so send it to the other ranks
              for rank in range(comm.size):
                  if rank != root:
                      comm.send(element, rank, tag=123)
          else:
              # We don't have it so receive from root
              comm.receive(element, root, tag=123)

        """
        assert 0 <= root < self.size
        assert is_contiguous(a)
        self.comm.broadcast(a, root)
Esempio n. 42
0
    def broadcast(self, a, root):
        """Share data from a single process to all ranks in a group.

        Parameters:

        a: ndarray
            Data, i.e. send buffer on root rank, receive buffer elsewhere.
            Note that after the broadcast, all ranks have the same data.
        root: int
            Rank of the root process, from which the data is to be shared.

        Example::

          # All ranks have parts of interesting data. Take a given index.
          mydata[:] = np.random.normal(size=N)

          # Who has the element at global index 13? Everybody needs it!
          index = 13
          root, myindex = divmod(index, N)
          element = np.empty(1, dtype=float)
          if comm.rank == root:
              # This process has the requested element so extract it
              element[:] = mydata[myindex]

          # Broadcast from owner to everyone else
          comm.broadcast(element, root)

          # .. which is equivalent to ..

          if comm.rank == root:
              # We are root so send it to the other ranks
              for rank in range(comm.size):
                  if rank != root:
                      comm.send(element, rank, tag=123)
          else:
              # We don't have it so receive from root
              comm.receive(element, root, tag=123)

        """
        assert 0 <= root < self.size
        assert is_contiguous(a)
        self.comm.broadcast(a, root)
Esempio n. 43
0
 def receive(self, a, src, tag=123, block=True):
     assert 0 <= src < self.size
     assert src != self.rank
     assert is_contiguous(a)
     return self.comm.receive(a, src, tag, block)
Esempio n. 44
0
 def ssend(self, a, dest, tag=123):
     assert 0 <= dest < self.size
     assert dest != self.rank
     assert is_contiguous(a)
     return self.comm.ssend(a, dest, tag)
Esempio n. 45
0
 def receive(self, a, src, tag=123, block=True):
     assert 0 <= src < self.size
     assert src != self.rank
     assert is_contiguous(a)
     return self.comm.receive(a, src, tag, block)
Esempio n. 46
0
 def ssend(self, a, dest, tag=123):
     assert 0 <= dest < self.size
     assert dest != self.rank
     assert is_contiguous(a)
     return self.comm.ssend(a, dest, tag)
Esempio n. 47
0
def gaussian_wave(r_vG,
                  r0_v,
                  sigma,
                  k_v=None,
                  A=None,
                  dtype=float,
                  out_G=None):
    """Generates function values for atom-centered Gaussian waves.

    ::
    
                         _ _
        _            / -|r-r0|^2 \           _ _
      f(r) = A * exp( ----------- ) * exp( i k.r )
                     \ 2 sigma^2 /

    If the parameter A is not specified, the Gaussian wave is normalized::

                                                  oo
           /    ____        \ -3/2               /       _  2  2
      A = (    /    '        )        =>    4 pi | dr |f(r)|  r  = 1
           \ \/  pi   sigma /                    /
                                                   0

    Parameters:

    r_vG: ndarray
        Set of coordinates defining the grid positions.
    r0_v: ndarray
        Set of coordinates defining the center of the Gaussian envelope.
    sigma: float
        Specifies the spatial width of the Gaussian envelope.
    k_v: ndarray or None
        Set of reciprocal lattice coordinates defining the wave vector.
        An argument of None is interpreted as the gamma point i.e. k_v=0.
    A: float, complex or None
        Specifies the amplitude of the Gaussian wave. Normalizes if None.
    dtype: type, defaults to float
        Specifies the output data type. Only returns the real-part if float.
    out_G: ndarray or None
        Optional pre-allocated buffer to fill in values. Allocates if None.

    """
    if k_v is None:
        k_v = np.zeros(r0_v.shape)

    if A is None:
        # 4*pi*int(exp(-r^2/(2*sigma^2))^2 * r^2, r=0...infinity)
        # = sigma^3*pi^(3/2) = 1/A^2 -> A = (sqrt(Pi)*sigma)^(-3/2)
        A = 1 / (sigma * np.pi**0.5)**1.5

    if debug:
        assert is_contiguous(r_vG, float)
        assert is_contiguous(r0_v, float)
        assert is_contiguous(k_v, float)
        assert r_vG.ndim >= 2 and r_vG.shape[0] > 0
        assert r0_v.ndim == 1 and r0_v.shape[0] > 0
        assert k_v.ndim == 1 and k_v.shape[0] > 0
        assert (r_vG.shape[0], ) == r0_v.shape == k_v.shape
        assert sigma > 0

    if out_G is None:
        out_G = np.empty(r_vG.shape[1:], dtype=dtype)
    elif debug:
        assert is_contiguous(out_G)
        assert out_G.shape == r_vG.shape[1:]

    # slice_v2vG = [slice(None)] + [np.newaxis]*3
    # gw = lambda r_vG, r0_v, sigma, k_v, A=1/(sigma*np.pi**0.5)**1.5: \
    #    * np.exp(-np.sum((r_vG-r0_v[slice_v2vG])**2, axis=0)/(2*sigma**2)) \
    #    * np.exp(1j*np.sum(np.r_vG*k_v[slice_v2vG], axis=0)) * A
    _gpaw.utilities_gaussian_wave(A, r_vG, r0_v, sigma, k_v, out_G)
    return out_G
Esempio n. 48
0
def gaussian_wave(r_vG, r0_v, sigma, k_v=None, A=None, dtype=float,
                  out_G=None):
    """Generates function values for atom-centered Gaussian waves.

    ::
    
                         _ _
        _            / -|r-r0|^2 \           _ _
      f(r) = A * exp( ----------- ) * exp( i k.r )
                     \ 2 sigma^2 /

    If the parameter A is not specified, the Gaussian wave is normalized::

                                                  oo
           /    ____        \ -3/2               /       _  2  2
      A = (    /    '        )        =>    4 pi | dr |f(r)|  r  = 1
           \ \/  pi   sigma /                    /
                                                   0

    Parameters:

    r_vG: ndarray
        Set of coordinates defining the grid positions.
    r0_v: ndarray
        Set of coordinates defining the center of the Gaussian envelope.
    sigma: float
        Specifies the spatial width of the Gaussian envelope.
    k_v: ndarray or None
        Set of reciprocal lattice coordinates defining the wave vector.
        An argument of None is interpreted as the gamma point i.e. k_v=0.
    A: float, complex or None
        Specifies the amplitude of the Gaussian wave. Normalizes if None.
    dtype: type, defaults to float
        Specifies the output data type. Only returns the real-part if float.
    out_G: ndarray or None
        Optional pre-allocated buffer to fill in values. Allocates if None.

    """
    if k_v is None:
        k_v = np.zeros(r0_v.shape)

    if A is None:
        # 4*pi*int(exp(-r^2/(2*sigma^2))^2 * r^2, r=0...infinity)
        # = sigma^3*pi^(3/2) = 1/A^2 -> A = (sqrt(Pi)*sigma)^(-3/2)
        A = 1/(sigma*np.pi**0.5)**1.5

    if debug:
        assert is_contiguous(r_vG, float)
        assert is_contiguous(r0_v, float)
        assert is_contiguous(k_v, float)
        assert r_vG.ndim >= 2 and r_vG.shape[0] > 0
        assert r0_v.ndim == 1 and r0_v.shape[0] > 0
        assert k_v.ndim == 1 and k_v.shape[0] > 0
        assert (r_vG.shape[0],) == r0_v.shape == k_v.shape
        assert sigma > 0

    if out_G is None:
        out_G = np.empty(r_vG.shape[1:], dtype=dtype)
    elif debug:
        assert is_contiguous(out_G)
        assert out_G.shape == r_vG.shape[1:]

    # slice_v2vG = [slice(None)] + [np.newaxis]*3
    # gw = lambda r_vG, r0_v, sigma, k_v, A=1/(sigma*np.pi**0.5)**1.5: \
    #    * np.exp(-np.sum((r_vG-r0_v[slice_v2vG])**2, axis=0)/(2*sigma**2)) \
    #    * np.exp(1j*np.sum(np.r_vG*k_v[slice_v2vG], axis=0)) * A
    _gpaw.utilities_gaussian_wave(A, r_vG, r0_v, sigma, k_v, out_G)
    return out_G