Example #1
0
    def load(self, method):
        """Make sure all necessary attributes have been initialized"""

        assert method in ('real', 'recip_gauss', 'recip_ewald'),\
            str(method) + ' is an invalid method name,\n' +\
            'use either real, recip_gauss, or recip_ewald'

        if method.startswith('recip'):
            if self.gd.comm.size > 1:
                raise RuntimeError("Cannot do parallel FFT, use method='real'")
            if not hasattr(self, 'k2'):
                self.k2, self.N3 = construct_reciprocal(self.gd)
            if method.endswith('ewald') and not hasattr(self, 'ewald'):
                # cutoff radius
                assert self.gd.orthogonal
                rc = 0.5 * np.average(self.gd.cell_cv.diagonal())
                # ewald potential: 1 - cos(k rc)
                self.ewald = (np.ones(self.gd.n_c) -
                              np.cos(np.sqrt(self.k2) * rc))
                # lim k -> 0 ewald / k2
                self.ewald[0, 0, 0] = 0.5 * rc**2
            elif method.endswith('gauss') and not hasattr(self, 'ng'):
                gauss = Gaussian(self.gd)
                self.ng = gauss.get_gauss(0) / sqrt(4 * pi)
                self.vg = gauss.get_gauss_pot(0) / sqrt(4 * pi)
        else:  # method == 'real'
            if not hasattr(self, 'solve'):
                if self.poisson is not None:
                    self.solve = self.poisson.solve
                else:
                    solver = PoissonSolver(nn=2)
                    solver.set_grid_descriptor(self.gd)
                    solver.initialize(load_gauss=True)
                    self.solve = solver.solve
Example #2
0
 def initialize(self, gd, load_gauss=False):
     # XXX this won't work now, but supposedly this class will be deprecated
     # in favour of FFTPoissonSolver, no?
     self.gd = gd
     if self.gd.comm.size > 1:
         raise RuntimeError('Cannot do parallel FFT.')
     self.k2, self.N3 = construct_reciprocal(self.gd)
     if load_gauss:
         gauss = Gaussian(self.gd)
         self.rho_gauss = gauss.get_gauss(0)
         self.phi_gauss = gauss.get_gauss_pot(0)
Example #3
0
 def initialize(self, gd, load_gauss=False):
     # XXX this won't work now, but supposedly this class will be deprecated
     # in favour of FFTPoissonSolver, no?
     self.gd = gd
     if self.gd.comm.size > 1:
         raise RuntimeError('Cannot do parallel FFT.')
     self.k2, self.N3 = construct_reciprocal(self.gd)
     if load_gauss:
         gauss = Gaussian(self.gd)
         self.rho_gauss = gauss.get_gauss(0)
         self.phi_gauss = gauss.get_gauss_pot(0)
Example #4
0
    def load_gauss(self, center=None):
        """Load compensating charge distribution for charged systems.

        See Appendix B of
        A. Held and M. Walter, J. Chem. Phys. 141, 174108 (2014).
        """
        # XXX Check if update is needed (dielectric changed)?
        epsr, dx_epsr, dy_epsr, dz_epsr = self.dielectric.eps_gradeps
        gauss = Gaussian(self.gd, center=center)
        rho_g = gauss.get_gauss(0)
        phi_g = gauss.get_gauss_pot(0)
        x, y, z = gauss.xyz
        fac = 2. * np.sqrt(gauss.a) * np.exp(-gauss.a * gauss.r2)
        fac /= np.sqrt(np.pi) * gauss.r2
        fac -= erf(np.sqrt(gauss.a) * gauss.r) / (gauss.r2 * gauss.r)
        fac *= 2.0 * 1.7724538509055159
        dx_phi_g = fac * x
        dy_phi_g = fac * y
        dz_phi_g = fac * z
        sp = dx_phi_g * dx_epsr + dy_phi_g * dy_epsr + dz_phi_g * dz_epsr
        rho = epsr * rho_g - 1. / (4. * np.pi) * sp
        invnorm = np.sqrt(4. * np.pi) / self.gd.integrate(rho)
        self.phi_gauss = phi_g * invnorm
        self.rho_gauss = rho * invnorm
Example #5
0
# Check that it is removed correctly
v = gauss.remove_moment(nH, 0)
m = gauss.get_moment(nH, 0)
print('\nZero\'th moment of compensated Hydrogen density =', m)
equal(m, 0., 1e-7)

# /-------------------------------------------------\
# | Check if Gaussian potentials are made correctly |
# \-------------------------------------------------/

# Array for storing the potential
pot = gd.zeros(dtype=float, global_array=False)
for L in range(7):  # Angular index of gaussian
    # Get analytic functions
    ng = gauss.get_gauss(L)
    vg = gauss.get_gauss_pot(L)

    # Solve potential numerically
    niter = solve(pot, ng, charge=None, zero_initial_phi=True)

    # Determine residual
    residual = norm(pot - vg)
    residual = gd.integrate((pot - vg)**2)**0.5

    # print result
    print('L=%s, processor %s of %s: %s' %
          (L, gd.comm.rank + 1, gd.comm.size, residual))

    assert residual < 0.6

# mpirun -np 2 python gauss_func.py --gpaw-parallel --gpaw-debug
Example #6
0
 def load_gauss(self):
     if not hasattr(self, 'rho_gauss'):
         gauss = Gaussian(self.gd)
         self.rho_gauss = gauss.get_gauss(0)
         self.phi_gauss = gauss.get_gauss_pot(0)
v = gauss.remove_moment(nH, 0)
m = gauss.get_moment(nH, 0)
print("\nZero'th moment of compensated Hydrogen density =", m)
equal(m, 0.0, 1e-7)


# /-------------------------------------------------\
# | Check if Gaussian potentials are made correctly |
# \-------------------------------------------------/

# Array for storing the potential
pot = gd.zeros(dtype=float, global_array=False)
for L in range(7):  # Angular index of gaussian
    # Get analytic functions
    ng = gauss.get_gauss(L)
    vg = gauss.get_gauss_pot(L)

    # Solve potential numerically
    niter = solve(pot, ng, charge=None, zero_initial_phi=True)

    # Determine residual
    residual = norm(pot - vg)
    residual = gd.integrate((pot - vg) ** 2) ** 0.5

    # print result
    print("L=%s, processor %s of %s: %s" % (L, gd.comm.rank + 1, gd.comm.size, residual))

    assert residual < 0.6

# mpirun -np 2 python gauss_func.py --gpaw-parallel --gpaw-debug
Example #8
0
 def load_gauss(self, center=None):
     if not hasattr(self, 'rho_gauss') or center is not None:
         gauss = Gaussian(self.gd, center=center)
         self.rho_gauss = gauss.get_gauss(0)
         self.phi_gauss = gauss.get_gauss_pot(0)
Example #9
0
 def load_gauss(self):
     if not hasattr(self, 'rho_gauss'):
         gauss = Gaussian(self.gd)
         self.rho_gauss = gauss.get_gauss(0)
         self.phi_gauss = gauss.get_gauss_pot(0)
Example #10
0
            PolarizationPoissonSolver)

# test neutral system with constant permittivity
parprint('neutral, constant permittivity')
epsinf = 80.
eps = gd.zeros()
eps.fill(epsinf)
qs = (-1., 1.)
shifts = (-1., 1.)
rho = gd.zeros()
phi_expected = gd.zeros()
for q, shift in zip(qs, shifts):
    gauss_norm = q / np.sqrt(4 * np.pi)
    gauss = Gaussian(gd, center=(box / 2. + shift) * np.ones(3) / Bohr)
    rho += gauss_norm * gauss.get_gauss(0)
    phi_expected += gauss_norm * gauss.get_gauss_pot(0) / epsinf

for ps in psolvers:
    phi = solve(ps, eps, rho)
    parprint(ps, np.abs(phi - phi_expected).max())
    equal(phi, phi_expected, 1e-3)

# test charged system with constant permittivity
parprint('charged, constant permittivity')
epsinf = 80.
eps = gd.zeros()
eps.fill(epsinf)
q = -2.
gauss_norm = q / np.sqrt(4 * np.pi)
gauss = Gaussian(gd, center=(box / 2. + 1.) * np.ones(3) / Bohr)
rho_gauss = gauss_norm * gauss.get_gauss(0)
Example #11
0
Nc = (N, N, N)                # Number of grid points along each axis
gd = GridDescriptor(Nc, (a, a, a), 0)    # Grid-descriptor object
solver = PoissonSolver(nn=3, use_charge_center=True)
solver.set_grid_descriptor(gd)
solver.initialize()
gauss = Gaussian(gd, a=inv_width, center=center_of_charge)
test_poisson = Gaussian(gd, a=inv_width, center=center_of_charge)

# /-------------------------------------------------\
# | Check if Gaussian potentials are made correctly |
# \-------------------------------------------------/

# Array for storing the potential
pot = gd.zeros(dtype=float, global_array=False)
solver.load_gauss()
vg = test_poisson.get_gauss_pot(0)
# Get analytic functions
ng = gauss.get_gauss(0)
#    vg = solver.phi_gauss
# Solve potential numerically
niter = solver.solve(pot, ng, charge=1.0, zero_initial_phi=False)
# Determine residual
# residual = norm(pot - vg)
residual = gd.integrate((pot - vg)**2)**0.5

print('residual %s' % (
    residual))
assert residual < 1e-5  # Better than 5.x

# mpirun -np 2 python gauss_func.py --gpaw-parallel --gpaw-debug