# Grid is so small that domain decomposition cannot exceed 4 domains assert world.size % 4 == 0 group, other = divmod(world.rank, 4) ranks = np.arange(4*group, 4*(group+1)) domain_comm = world.new_communicator(ranks) else: domain_comm = world gd = GridDescriptor((8, 1, 1), (8.0, 1.0, 1.0), comm=domain_comm) a = gd.zeros() dadx = gd.zeros() a[:, 0, 0] = np.arange(gd.beg_c[0], gd.end_c[0]) gradx = Gradient(gd, v=0) print a.itemsize, a.dtype, a.shape print dadx.itemsize, dadx.dtype, dadx.shape gradx.apply(a, dadx) # a = [ 0. 1. 2. 3. 4. 5. 6. 7.] # # da # -- = [-2.5 1. 1. 1. 1. 1. 1. -2.5] # dx dadx = gd.collect(dadx, broadcast=True) assert dadx[3, 0, 0] == 1.0 and np.sum(dadx[:, 0, 0]) == 0.0 gd = GridDescriptor((1, 8, 1), (1.0, 8.0, 1.0), (1, 0, 1), comm=domain_comm) dady = gd.zeros() a = gd.zeros() grady = Gradient(gd, v=1) a[0, :, 0] = np.arange(gd.beg_c[1], gd.end_c[1]) - 1
class ADM12PoissonSolver(SolvationPoissonSolver): """Poisson solver with dielectric. Following O. Andreussi, I. Dabo, and N. Marzari, J. Chem. Phys. 136, 064102 (2012). Warning: Not intended for production use, as it is not tested thouroughly! XXX TODO : * Correction for charged systems??? * Check: Can the polarization charge introduce a monopole? * Convergence problems depending on eta. Apparently this method works best with FFT as in the original Paper. * Optimize numerics. """ def __init__(self, nn=3, relax='J', eps=2e-10, maxiter=1000, remove_moment=None, eta=.6, use_charge_center=False): """Constructor for ADM12PoissonSolver. Additional arguments not present in SolvationPoissonSolver: eta -- linear mixing parameter """ adm12_warning = UserWarning( 'ADM12PoissonSolver is not tested thoroughly' ' and therefore not recommended for production code!') warnings.warn(adm12_warning) self.eta = eta SolvationPoissonSolver.__init__(self, nn, relax, eps, maxiter, remove_moment, use_charge_center=use_charge_center) def set_grid_descriptor(self, gd): SolvationPoissonSolver.set_grid_descriptor(self, gd) self.gradx = Gradient(gd, 0, 1.0, self.nn) self.grady = Gradient(gd, 1, 1.0, self.nn) self.gradz = Gradient(gd, 2, 1.0, self.nn) def get_description(self): if len(self.operators) == 0: return 'uninitialized ADM12PoissonSolver' else: description = SolvationPoissonSolver.get_description(self) return description.replace('solver with', 'ADM12 solver with dielectric and') def _init(self): if self._initialized: return self.rho_iter = self.gd.zeros() self.d_phi = self.gd.empty() return SolvationPoissonSolver._init(self) def solve(self, phi, rho, charge=None, eps=None, maxcharge=1e-6, zero_initial_phi=False, timer=None): self._init() if self.gd.pbc_c.all(): actual_charge = self.gd.integrate(rho) if abs(actual_charge) > maxcharge: raise NotImplementedError( 'charged periodic systems are not implemented') return FDPoissonSolver.solve(self, phi, rho, charge, eps, maxcharge, zero_initial_phi, timer=timer) def solve_neutral(self, phi, rho, eps=2e-10, timer=None): self._init() self.rho = rho return SolvationPoissonSolver.solve_neutral(self, phi, rho, eps) def iterate2(self, step, level=0): self._init() if level == 0: epsr, dx_epsr, dy_epsr, dz_epsr = self.dielectric.eps_gradeps self.gradx.apply(self.phis[0], self.d_phi) sp = dx_epsr * self.d_phi self.grady.apply(self.phis[0], self.d_phi) sp += dy_epsr * self.d_phi self.gradz.apply(self.phis[0], self.d_phi) sp += dz_epsr * self.d_phi self.rho_iter = self.eta / (4. * np.pi) * sp + \ (1. - self.eta) * self.rho_iter self.rhos[0][:] = (self.rho_iter + self.rho) / epsr return SolvationPoissonSolver.iterate2(self, step, level)
# Grid is so small that domain decomposition cannot exceed 4 domains assert world.size % 4 == 0 group, other = divmod(world.rank, 4) ranks = np.arange(4 * group, 4 * (group + 1)) domain_comm = world.new_communicator(ranks) else: domain_comm = world gd = GridDescriptor((8, 1, 1), (8.0, 1.0, 1.0), comm=domain_comm) a = gd.zeros() dadx = gd.zeros() a[:, 0, 0] = np.arange(gd.beg_c[0], gd.end_c[0]) gradx = Gradient(gd, v=0) print a.itemsize, a.dtype, a.shape print dadx.itemsize, dadx.dtype, dadx.shape gradx.apply(a, dadx) # a = [ 0. 1. 2. 3. 4. 5. 6. 7.] # # da # -- = [-2.5 1. 1. 1. 1. 1. 1. -2.5] # dx dadx = gd.collect(dadx, broadcast=True) assert dadx[3, 0, 0] == 1.0 and np.sum(dadx[:, 0, 0]) == 0.0 gd = GridDescriptor((1, 8, 1), (1.0, 8.0, 1.0), (1, 0, 1), comm=domain_comm) dady = gd.zeros() a = gd.zeros() grady = Gradient(gd, v=1) a[0, :, 0] = np.arange(gd.beg_c[1], gd.end_c[1]) - 1