def test_grad_P_varying_qn(): NX = 32 #const.NX xmin = 0.0 #const.xmin xmax = 2*np.pi #const.xmax dx = xmax / NX x = np.arange(xmin, xmax, dx/100.) # Simulation domain space 0,NX (normalized to grid) k = 2.0 # Physical location of nodes E_nodes = (np.arange(NX + 3) - 0.5) * dx B_nodes = (np.arange(NX + 3) - 1.0) * dx # Set analytic solutions (input/output) qn_input = const.q*(np.sin(k*E_nodes) + 1) # Analytic input at node points (number density varying) te_input = np.ones(NX + 3)*const.Te0 pe_anal = const.kB * const.Te0 * k*np.cos(k*B_nodes) # Analytic solution at nodes grad_P_anal= const.kB * const.Te0 * k*np.cos(k*x) # Highly sampled output (derivative) # Finite differences grad_PB, grad_P = fields.get_grad_P(qn_input, te_input, DX=dx) r2 = r_squared(grad_P[1:-2], pe_anal[1:-2]) ## PLOT ## plot = False if plot == True: plt.figure(figsize=(15, 15)) marker_size = None plt.plot(x, grad_P_anal, linestyle=':', c='b', label='Analytic Solution') plt.scatter(B_nodes, pe_anal, marker='o', c='k', s=marker_size, label='Node Solution') plt.scatter(B_nodes, grad_PB, marker='x', c='b', s=marker_size, label='Finite Difference (on B)') plt.scatter(E_nodes, grad_P, marker='x', c='r', s=marker_size, label='Finite Difference (on E)') plt.title(r'Test of $\nabla p_e$') for kk in range(NX + 3): plt.axvline(E_nodes[kk], linestyle='--', c='r', alpha=0.2) plt.axvline(B_nodes[kk], linestyle='--', c='b', alpha=0.2) plt.axvline(xmin, linestyle='-', c='k', alpha=0.2) plt.axvline(xmax, linestyle='-', c='k', alpha=0.2) plt.gcf().text(0.15, 0.93, '$R^2 = %.4f$' % r2) plt.xlim(xmin - 1.5*dx, xmax + 2*dx) plt.legend() return
def set_equilibrium_te0(q_dens, Te0): ''' Modifies the initial Te array to allow grad(P_e) = grad(nkT) = 0 Iterative? Analytic? NOTE: Removed factors 2dx from qdens_gradient and m_arr, since they cancel out Note: Could probably calculate Te0 from some sort of density/temperature relationship with the ions, rather than defining it a priori, for now it should be ok (set via beta same as cold ions) ''' qdens_gradient = np.zeros(NC , dtype=np.float64) # Get density gradient: Central differencing, internal points for ii in nb.prange(1, NC - 1): qdens_gradient[ii] = (q_dens[ii + 1] - q_dens[ii - 1]) # Forwards/Backwards difference at physical boundaries (In this case, the gradient will be zero) qdens_gradient[0] = 0 qdens_gradient[NC - 1] = 0 m_arr = (qdens_gradient/q_dens) # Construct solution array to work out Te soln_array = np.zeros((NC, NC), dtype=np.float64) ans_arr = np.zeros(NC, dtype=np.float64) # Construct central points (Centered finite difference with constant) for ii in range(1, NC-1): soln_array[ii, ii - 1] = -1.0 soln_array[ii, ii ] = 1.0 * m_arr[ii] soln_array[ii, ii + 1] = 1.0 # Enter boundary points : Neumann boundary conditions soln_array[0, 0] = 1.0 soln_array[NC - 1, NC - 1] = 1.0 ans_arr[0] = Te0_scalar ans_arr[NC - 1] = Te0_scalar Te0[:] = np.dot(np.linalg.inv(soln_array), ans_arr) if False: # Test: This should be zero if working grad_P = np.zeros(NC , dtype=np.float64) temp = np.zeros(NC + 1, dtype=np.float64) fields.get_grad_P(q_dens, Te0, grad_P, temp) import sys fig, axes = plt.subplots(4, sharex=True, figsize=(15, 10)) axes[0].set_title('Initial Temp/Dens with zero derivative at ND-NX interface') axes[0].plot(q_dens / (q*ne)) axes[0].set_ylabel('ne / ne0') axes[1].plot(qdens_gradient) axes[1].set_ylabel('dne/dx') axes[2].plot(Te0) axes[2].set_ylabel('Te') axes[3].plot(grad_P) axes[3].set_ylabel('grad(P)') axes[3].set_xlabel('Cell number') sys.exit() return