def solve_coulomb(rho_U, Uext, r, tau_u_set, tau_rho_set, **kwarg): params = { 'it' : 0, 'zero_endpoint' : False, 'display_callback' : empty_callback, 'fname_template' : "data/coulombsim-it=%d.npz" } params.update(kwarg) print params zero_endpoint = params['zero_endpoint'] it = params['it'] display_callback = params['display_callback'] fname_template = params['fname_template'] rexp = util.make_exp_grid(r.min(), r.max(), len(r)) C = coulomb.kernel( rexp ) U = np.array( Uext ) rho = np.zeros( (len(r)) ) j = 0 zero_U = True def mkFilename(it): fname = fname_template % (it) print "fname: ", fname return fname if it > 0: # Load previous solution, if possible data = np.load( mkFilename( it ) ) rho = data['rho'] U = data['U'] while True: tau_U = tau_u_set [it % len(tau_u_set)] tau_rho = tau_rho_set[it % len(tau_rho_set)] it += 1 U1 = np.dot( C, util.gridswap(r, rexp, rho ) ) U1 = util.gridswap(rexp, r, U1) #rho = util.gridswap(rexp, r, rho) U1 += Uext if zero_endpoint: U1 -= U1[-1]; err_U = linalg.norm(U - U1) U += tau_U * (U1 - U) if zero_endpoint: U -= U[-1]; rho1 = rho_U(U, r) err_rho = linalg.norm(rho1 - rho) rho += tau_rho * (rho1 - rho) print "U error", err_U, "rho error", err_rho, "it", it np.savez(mkFilename( it ), rho=rho, U=U, rho1=rho1, U1=U1, r=r) display_callback(it, r, U, rho, U1, rho1) if (err_U < (1e-4)) and (err_rho < (1e-5)): break if (err_U > 1e+6) or (err_rho > 1e+6): print "A clear divergence" break return U, rho
#def Ur(rx): # if rx > r_0: # return -Z/rx # return -Z / r_0 #U = np.vectorize(Ur)(r) #def rho_b(rx): # #if rx > r_0: return 0.0; # #return Z / math.pi / r_0**2 # return r_0**2 / math.pi / (rx**2 + r_0**2)**2 * Z delta_func = deltafunc.DeltaGauss(r_0) #delta_func = deltafunc.DeltaCubic(r_0) rho_bare = Z * delta_func.rho(r) U = Z * delta_func.U(r) rexp = util.make_exp_grid(0.001, 50.0, 1000) Qcoul = Kernel(rexp, coulomb.kernel(rexp)) #rho_bare = np.vectorize(rho_b)(r) #U = Qcoul(r, rho_bare) #U[0:3] = U[3] if True: import pylab as pl pl.plot (r, U) pl.plot (r, Z / np.sqrt(r**2 + r_0**2)) pl.figure() pl.loglog(r, np.abs(U)) pl.loglog(r, Z / np.sqrt(r**2 + r_0**2)) pl.show () rho_th = - math.pi / 8.0 * rho_bare #rho_th = -Z * r_0 / 16.0 / np.sqrt(r**2 + r_0**2)**3 rho_RPA = graphene.rho_RPA(U)
#def Ur(rx): # if rx > r_0: # return -Z/rx # return -Z / r_0 #U = np.vectorize(Ur)(r) #def rho_b(rx): # #if rx > r_0: return 0.0; # #return Z / math.pi / r_0**2 # return r_0**2 / math.pi / (rx**2 + r_0**2)**2 * Z delta_func = deltafunc.DeltaGauss(r_0) #delta_func = deltafunc.DeltaCubic(r_0) rho_bare = Z * delta_func.rho(r) U = Z * delta_func.U(r) rexp = util.make_exp_grid(0.001, 50.0, 1000) Qcoul = Kernel(rexp, coulomb.kernel(rexp)) #rho_bare = np.vectorize(rho_b)(r) #U = Qcoul(r, rho_bare) #U[0:3] = U[3] if True: import pylab as pl pl.plot(r, U) pl.plot(r, Z / np.sqrt(r**2 + r_0**2)) pl.figure() pl.loglog(r, np.abs(U)) pl.loglog(r, Z / np.sqrt(r**2 + r_0**2)) pl.show() rho_th = -math.pi / 8.0 * rho_bare #rho_th = -Z * r_0 / 16.0 / np.sqrt(r**2 + r_0**2)**3 rho_RPA = graphene.rho_RPA(U)