def dot_product(prec, factor_array1, factor_array2, out_tree, MRA): ''' performs the dot product operation on two tree arrays of size 3. the operation is performed as if each of the arrays is a 3D vector and each of the trees are a value in that vector. ''' add_tree1 = vp.FunctionTree(MRA) mult_tree1 = vp.FunctionTree(MRA) mult_tree2 = vp.FunctionTree(MRA) mult_tree3 = vp.FunctionTree(MRA) vp.multiply(prec, mult_tree1, 1, factor_array1[0], factor_array2[0]) vp.multiply(prec, mult_tree2, 1, factor_array1[1], factor_array2[1]) vp.multiply(prec, mult_tree3, 1, factor_array1[2], factor_array2[2]) vp.add(prec / 10, add_tree1, 1.0, mult_tree1, 1.0, mult_tree2) vp.add(prec / 10, out_tree, 1.0, mult_tree3, 1.0, add_tree1) mult_tree1.clear() mult_tree2.clear() mult_tree3.clear() add_tree1.clear() del mult_tree1 del mult_tree2 del mult_tree3 del add_tree1
def test_vec_dot(): vec = [] vec.append(tuple([1.0, phi_tree])) vec.append(tuple([-1.0, phi_tree])) tmp_1_tree = vp.FunctionTree(MRA) tmp_2_tree = vp.FunctionTree(MRA) vp.square(prec, tmp_2_tree, phi_tree) vp.dot(prec, tmp_1_tree, vec, vec) assert isclose(tmp_1_tree.integrate(), tmp_2_tree.integrate() * 2.0, rel_tol=prec)
def test_power_square_and_dot(): tmp_1_tree = vp.FunctionTree(MRA) tmp_2_tree = vp.FunctionTree(MRA) tmp_3_tree = vp.FunctionTree(MRA) vp.power(prec, tmp_1_tree, phi_tree, 2.0) vp.square(prec, tmp_2_tree, phi_tree) assert isclose(vp.dot(phi_tree, phi_tree), tmp_2_tree.integrate()) assert isclose(tmp_1_tree.integrate(), tmp_2_tree.integrate(), rel_tol=prec)
def test_gradient_and_divergence(): grad_tree = vp.FunctionTree(MRA) out_grad_tree = vp.FunctionTree(MRA) vp.project(prec, grad_tree, phi_exact) D = vp.ABGVOperator(MRA, 0.0, 0.0) grad = vp.gradient(D, grad_tree) assert isclose(grad[0][1].evalf([0.1, 0.0, 0.0]), d_phi_exact([0.1, 0.0, 0.0]), rel_tol=prec) grad_tree_vec = [] grad_tree_vec.append(tuple([1.0, grad_tree])) grad_tree_vec.append(tuple([1.0, grad_tree])) grad_tree_vec.append(tuple([1.0, grad_tree])) vp.divergence(out_grad_tree, D, grad_tree_vec) assert isclose(out_grad_tree.evalf([0.1, 0.1, 0.1]), 3.0 * grad[0][1].evalf([0.1, 0.1, 0.1]), rel_tol=prec)
def clone_tree(in_tree, out_tree, prec, MRA): def ones(r): return 1 temp_tree = vp.FunctionTree(MRA) vp.project(prec, temp_tree, ones) vp.multiply(prec, out_tree, 1, temp_tree, in_tree) temp_tree.clear() del temp_tree
def V_solver_Lin(prec, MRA, DerivativeOperator, PoissonOperator, eps_inv_tree, C_tree, V_tree, rho_eff_tree, old_V_tree): gamma_tree = vp.FunctionTree(MRA) poiss_tree = vp.FunctionTree(MRA) D = DerivativeOperator P = PoissonOperator DV_vector = D_functree(D, V_tree, MRA) clone_tree(V_tree, old_V_tree, prec, MRA) V_tree.clear() DC_vector = D_functree(D, C_tree, MRA) gamma_Lin(eps_inv_tree, DC_vector, DV_vector, gamma_tree, prec, MRA) vp.add(prec, poiss_tree, 1, rho_eff_tree, 1, gamma_tree) poisson_solver(V_tree, poiss_tree, P, prec) return gamma_tree
def test_gaussFunc(): sigma = 0.01 pos = [0.0, 0.0, 0.0] power = [0, 0, 0] alpha = 1.0 / (2.0 * np.pi * sigma**2)**(3 / 2) beta = 1.0 / (2.0 * sigma**2) gauss = vp.GaussFunc(beta, alpha, pos, power) g_tree = vp.FunctionTree(MRA) vp.build_grid(g_tree, gauss) vp.project(prec, g_tree, gauss) assert isclose(g_tree.integrate(), 1.0, rel_tol=prec)
def D_functree(D, in_tree, MRA): ''' differentiates a 3d FunctionTree Args: D: derivative operator in_tree: 3d functiontree to be differentiated MRA: from vampyr3d module MultiResolutionAnalysis output: list of 3 FunctionTrees which contain a partial derivative of the in_tree. This is in the form [d/dx, d/dy, d/dz] ''' out_treex = vp.FunctionTree(MRA) out_treey = vp.FunctionTree(MRA) out_treez = vp.FunctionTree(MRA) vp.apply(out_treex, D, in_tree, 0) # diff. in with respect to x vp.apply(out_treey, D, in_tree, 1) # diff. in with respect to y vp.apply(out_treez, D, in_tree, 2) # diff. in with respect to z return [out_treex, out_treey, out_treez]
def v_generator(v_tree, MRA, prec=10e-3, beta=100.0, mid=0.0, mu=0.0): import vampyr3d as vp from numpy import pi alpha = (beta / pi)**(3 / 2) x_tree = vp.FunctionTree(MRA) y_tree = vp.FunctionTree(MRA) z_tree = vp.FunctionTree(MRA) const_tree = vp.FunctionTree(MRA) x_tree_generator(x_tree, 0, prec, beta, mid) x_tree_generator(y_tree, 1, prec, beta, mid) x_tree_generator(z_tree, 2, prec, beta, mid) const_tree_generator(const_tree, prec, beta, mu, mid) vec = [] vec.append(tuple([1.0, x_tree])) vec.append(tuple([1.0, y_tree])) vec.append(tuple([1.0, z_tree])) vec.append(tuple([1.0, const_tree])) vp.build_grid(v_tree, vec) vp.add(prec, v_tree, vec) alpha = -alpha / (4.0 * pi) v_tree.rescale(alpha)
e_0 = 1 corner = [-1, -1, -1] boxes = [2, 2, 2] world = vp.BoundingBox(min_scale, corner, boxes) basis = vp.InterpolatingBasis(order) MRA = vp.MultiResolutionAnalysis(world, basis, max_depth) P = vp.PoissonOperator(MRA, prec) D = vp.ABGVOperator(MRA, 0.0, 0.0) # making rho as a GaussFunc rho_tree = vp.FunctionTree(MRA) pos = [0, 0, 0] power = [0, 0, 0] beta = 2000 alpha = (beta / np.pi) * np.sqrt(beta / np.pi) rho_gauss = vp.GaussFunc(beta, alpha, pos, power) vp.build_grid(rho_tree, rho_gauss) vp.project_gauss(prec, rho_tree, rho_gauss) # rho_tree has a GaussFunc for rho # linear dielectric function eps_inv_tree = vp.FunctionTree(MRA) rho_eff_tree = vp.FunctionTree(MRA) Cavity_tree = vp.FunctionTree(MRA) V_tree = vp.FunctionTree(MRA)
destroy_Cavity, change_e_inf min_scale = -5 max_depth = 25 order = 7 prec = 1e-3 corner = [-1, -1, -1] boxes = [2, 2, 2] world = vp.BoundingBox(min_scale, corner, boxes) basis = vp.InterpolatingBasis(order) MRA = vp.MultiResolutionAnalysis(world, basis, max_depth) P = vp.PoissonOperator(MRA, prec) D = vp.ABGVOperator(MRA, 0.0, 0.0) rho_tree = vp.FunctionTree(MRA) V_tree = vp.FunctionTree(MRA) charge = 1 Radius = [3.6] d = 0.2 e_inf = 2.00 Heh_p = np.array([[+0.0000, 0.0000, -0.1250], [-1.4375, 0.0000, 1.0250], [+1.4375, 0.0000, 1.0250]]) # [H, He] Heh_p_Z = np.array([8.0, 1.0, 1.0]) while (Radius[0] <= 6.0): initialize_cavity([[0.0, 0.0, 0.0]], Radius, d) change_e_inf(e_inf)
def test_copy_func(): copy_tree = vp.FunctionTree(MRA) vp.copy_grid(copy_tree, phi_tree) vp.copy_func(copy_tree, phi_tree) assert isclose(copy_tree.integrate(), phi_tree.integrate(), rel_tol=prec)
def test_multiply(): mult_tree = vp.FunctionTree(MRA) vp.multiply(prec, mult_tree, 1, phi_tree, phi_tree_pois) assert isclose(mult_tree.evalf([0, 0, 0]), phi_exact([0, 0, 0])**2, rel_tol=prec)
return alpha * np.exp(-beta * (x[0]**2 + x[1]**2 + x[2]**2)) def d_phi_exact(x): beta = 100.0 alpha = (beta / np.pi)**(3 / 2) return -2.0 * beta * alpha * x[0] * np.exp(-beta * (x[0]**2 + x[1]**2 + x[2]**2)) H = vp.HelmholtzOperator(MRA, mu, prec) P = vp.PoissonOperator(MRA, prec) phi_tree = vp.FunctionTree(MRA) phi_tree_pois = vp.FunctionTree(MRA) v_tree = vp.FunctionTree(MRA) v_generator(v_tree, MRA, prec, beta, mid, mu) v_tree_pois = vp.FunctionTree(MRA) v_generator(v_tree_pois, MRA, prec, beta, mid) add_tree = vp.FunctionTree(MRA) add_vec_tree = vp.FunctionTree(MRA) mult_vec_tree = vp.FunctionTree(MRA) vp.apply(prec, phi_tree, H, v_tree) vp.apply(prec, phi_tree_pois, P, v_tree_pois) def test_IsIntWorking():
def V_SCF_exp(MRA, prec, P, D, charge, rho_tree, V_tree, pos, Z): global e_inf global e_0 global Cavity # initializing FunctionTrees eps_inv_tree = vp.FunctionTree(MRA) rho_eff_tree = vp.FunctionTree(MRA) Cavity_tree = vp.FunctionTree(MRA) old_V_tree = vp.FunctionTree(MRA) print('set rho') set_rho(pos, Z, charge, 1000.0, rho_tree, prec) # making rho_eff_tree containing rho_eff print('set cavity functions') vp.project(prec / 100, eps_inv_tree, diel_f_exp_inv) vp.project(prec / 100, Cavity_tree, Cavity) vp.multiply(prec, rho_eff_tree, 1, eps_inv_tree, rho_tree) print("plotting the cavity") x_plt = np.linspace(-7.0, 7.0, 1000) Cavity_plt = np.array([Cavity_tree.evalf([x, 0., 0.]) for x in x_plt]) plt.plot(x_plt, Cavity_plt) plt.show() Cavity_tree.rescale(np.log(e_0 / e_inf)) j = 1 error = 1 poisson_solver(V_tree, rho_eff_tree, P, prec) while (error >= prec): # solving the poisson equation once gamma_tree = V_solver_exp(rho_eff_tree, V_tree, Cavity_tree, D, P, MRA, prec, old_V_tree) # finding error once temp_tree = vp.FunctionTree(MRA) vp.add(prec / 10, temp_tree, 1.0, V_tree, -1.0, old_V_tree) error = np.sqrt(temp_tree.getSquareNorm()) temp_tree.clear() del temp_tree # Reaction_charge = gamma_tree.integrate() # print('iter:\t\t\t%i\nerror:\t\t\t%f\nR charge:\t\t%f' % (j, error, # Reaction_charge)) print('iter:\t', j, '\t error:\t', error) # print('exact Reaction charge:\t%f\n'%((charge)*((1 - e_inf)/e_inf))) j += 1 print('converged total electrostatic potential\n') eps_inv_tree.clear() rho_eff_tree.clear() Cavity_tree.clear() old_V_tree.clear() del eps_inv_tree del rho_eff_tree del Cavity_tree del old_V_tree return gamma_tree
def gamma_Lin(eps_inv_tree, DC_vector, DV_vector, out_tree, prec, MRA): temp_tree = vp.FunctionTree(MRA) dot_product(prec, DV_vector, DC_vector, temp_tree, MRA) vp.multiply(prec, out_tree, 1, temp_tree, eps_inv_tree) out_tree.rescale((1 / (4 * np.pi))) # probably wrong recheck