def solve_neutral(self, phi_g, rho_g): # b_phi1 and b_phi2 are the boundary Hartree potential values # of left and right sides if self.comm_reshape: global_rho_g0 = self.gd.collect(rho_g) rho_g1 = self.scatter_r_distribution(global_rho_g0) else: rho_g1 = rho_g # use copy() to avoid the C_contiguous=False rho_g2 = fft2(rho_g1, None, (0, 1)).copy() global_rho_g = self.gather_r_distribution(rho_g2) if self.gd.comm.rank == 0: global_rho_g.shape = (self.d1 * self.d2, self.d3) rho_g3 = self.scatter_k_distribution(global_rho_g) du0 = np.zeros(self.d3 - 1, dtype=complex) du20 = np.zeros(self.d3 - 2, dtype=complex) h2 = self.gd.h_cv[2, 2] ** 2 phi_g1 = np.zeros(rho_g3.shape, dtype=complex) index = self.k_distribution[self.gd.comm.rank] for phi, rho, rv2, bp1, bp2, i in zip(phi_g1, rho_g3, self.k_vq2, self.loc_b_phi1, self.loc_b_phi2, range(len(index))): A = np.zeros(self.d3, dtype=complex) + 2 + h2 * rv2 phi = rho * np.pi * 4 * h2 phi[0] += bp1 phi[-1] += bp2 du = du0 - 1 dl = du0 - 1 du2 = du20 - 1 _gpaw.linear_solve_tridiag(self.d3, A, du, dl, du2, phi) phi_g1[i] = phi global_phi_g = self.gather_k_distribution(phi_g1) if self.gd.comm.rank == 0: global_phi_g.shape = (self.d1, self.d2, self.d3) phi_g2 = self.scatter_r_distribution(global_phi_g, dtype=complex) # use copy() to avoid the C_contiguous=False phi_g3 = ifft2(phi_g2, None, (0, 1)).real.copy() if self.comm_reshape: global_phi_g = self.gather_r_distribution(phi_g3, dtype=float) self.gd.distribute(global_phi_g, phi_g) else: phi_g[:] = phi_g3