def calculate_density(f, vel_x): deltav = af.sum(vel_x[0, 1]-vel_x[0, 0]) value_of_density = af.sum(f, 1)*deltav af.eval(value_of_density) return(value_of_density)
def initialize_f(q1, q2, v1, v2, v3, params): m_e = params.mass[0, 0] m_i = params.mass[0, 1] k = params.boltzmann_constant n_b_e = params.n_background_e T_b_e = params.temperature_background_e n_b_i = params.n_background_i T_b_i = params.temperature_background_i n_e = n_b_e + params.alpha * af.cos(q1) n_i = n_b_i + 0 * q1 T_e = T_b_e T_i = T_b_i f_e = n_e * np.sqrt(1 / (2 * np.pi)) * af.sqrt(m_e * T_i/m_i * T_e) \ * af.exp(-0.5 * (m_e * T_i/m_i * T_e) * (v1[:, 0])**2) f_i = n_i * np.sqrt(1 / (2 * np.pi)) \ * af.exp(-0.5 * (v1[:, 1])**2) f = af.join(1, f_e, f_i) af.eval(f) return (f)
def f_interp_2d(self, dt): if(self.performance_test_flag == True): tic = af.time() # Defining a lambda function to perform broadcasting operations # This is done using af.broadcast, which allows us to perform # batched operations when operating on arrays of different sizes addition = lambda a, b:a + b # af.broadcast(function, *args) performs batched operations on # function(*args) q1_center_new = af.broadcast(addition, self.q1_center, - self._A_q1 * dt) q2_center_new = af.broadcast(addition, self.q2_center, - self._A_q2 * dt) # Reordering from (dof, N_q1, N_q2) --> (N_q1, N_q2, dof) self.f = af.approx2(af.reorder(self.f, 1, 2, 0), af.reorder(q1_center_new, 1, 2, 0), af.reorder(q2_center_new, 1, 2, 0), af.INTERP.BICUBIC_SPLINE, xp = af.reorder(self.q1_center, 1, 2, 0), yp = af.reorder(self.q2_center, 1, 2, 0) ) # Reordering from (N_q1, N_q2, dof) --> (dof, N_q1, N_q2) self.f = af.reorder(self.f, 2, 0, 1) af.eval(self.f) if(self.performance_test_flag == True): af.sync() toc = af.time() self.time_interp2 += toc - tic return
def yee_grid_to_cell_centered_grid(self): E1_yee = self.yee_grid_EM_fields[0] # (i + 1/2, j) E2_yee = self.yee_grid_EM_fields[1] # (i, j + 1/2) E3_yee = self.yee_grid_EM_fields[2] # (i, j) B1_yee = self.yee_grid_EM_fields[3] # (i, j + 1/2) B2_yee = self.yee_grid_EM_fields[4] # (i + 1/2, j) B3_yee = self.yee_grid_EM_fields[5] # (i + 1/2, j + 1/2) # Interpolating at the (i + 1/2, j + 1/2) point of the grid: self.cell_centered_EM_fields[0] = 0.5 * (E1_yee + af.shift(E1_yee, 0, 0, 0, -1)) self.cell_centered_EM_fields[1] = 0.5 * (E2_yee + af.shift(E2_yee, 0, 0, -1, 0)) self.cell_centered_EM_fields[2] = 0.25 * ( E3_yee + af.shift(E3_yee, 0, 0, 0, -1) + af.shift(E3_yee, 0, 0, -1, 0) + af.shift(E3_yee, 0, 0, -1, -1)) self.cell_centered_EM_fields[3] = 0.5 * (B1_yee + af.shift(B1_yee, 0, 0, -1, 0)) self.cell_centered_EM_fields[4] = 0.5 * (B2_yee + af.shift(B2_yee, 0, 0, 0, -1)) self.cell_centered_EM_fields[5] = B3_yee af.eval(self.cell_centered_EM_fields) return
def initialize_f(q1, q2, v1, v2, v3, params): m = params.mass k = params.boltzmann_constant n_b = params.density_background T_b = params.temperature_background k = params.boltzmann_constant v1_bulk = 0 # Assigning separate bulk velocities v2_bulk = params.amplitude * -1.7450858652952794e-15 * af.cos(params.k_q1 * q1) \ - params.amplitude * 0.5123323181646575 * af.sin(params.k_q1 * q1) v3_bulk = params.amplitude * 0.5123323181646597 * af.cos(params.k_q1 * q1) \ - params.amplitude * 0 * af.sin(params.k_q1 * q1) n = n_b + 0 * q1**0 f = n * (m / (2 * np.pi * k * T_b)) \ * af.exp(-m * (v2 - v2_bulk)**2 / (2 * k * T_b)) \ * af.exp(-m * (v3 - v3_bulk)**2 / (2 * k * T_b)) af.eval(f) return (f)
def fraction_finder(positions_x, positions_y, x_grid, y_grid, dx, dy): ''' function fraction_finder(positions_x, positions_y, x_grid, y_grid, dx, dy) ----------------------------------------------------------------------- Input variables: positions_x and length_domain_x positions_x: An one dimensional array of size equal to number of particles taken in the PIC code. It contains the positions of particles in x direction. positions_y: An one dimensional array of size equal to number of particles taken in the PIC code. It contains the positions of particles in y direction. x_grid, y_grid: This is an array denoting the position grid chosen in the PIC simulation in x and y directions respectively dx, dy: This is the distance between any two consecutive grid nodes of the position grid in x and y directions respectively ----------------------------------------------------------------------- returns: x_frac, y_frac This function returns the fractions of grid cells needed to perform the 2D charge deposition ''' x_frac = (positions_x - af.sum(x_grid[0])) / dx y_frac = (positions_y - af.sum(y_grid[0])) / dy af.eval(x_frac, y_frac) return x_frac, y_frac
def cell_centered_grid_to_yee_grid(self): E1 = self.cell_centered_EM_fields[0] E2 = self.cell_centered_EM_fields[1] E3 = self.cell_centered_EM_fields[2] B1 = self.cell_centered_EM_fields[3] B2 = self.cell_centered_EM_fields[4] B3 = self.cell_centered_EM_fields[5] self.yee_grid_EM_fields[0] = 0.5 * (E1 + af.shift(E1, 0, 0, 0, 1) ) # (i+1/2, j) self.yee_grid_EM_fields[1] = 0.5 * (E2 + af.shift(E2, 0, 0, 1, 0) ) # (i, j+1/2) self.yee_grid_EM_fields[2] = 0.25 * ( E3 + af.shift(E3, 0, 0, 1, 0) + af.shift(E3, 0, 0, 0, 1) + af.shift(E3, 0, 0, 1, 1)) # (i, j) self.yee_grid_EM_fields[3] = 0.5 * (B1 + af.shift(B1, 0, 0, 1, 0) ) # (i, j+1/2) self.yee_grid_EM_fields[4] = 0.5 * (B2 + af.shift(B2, 0, 0, 0, 1) ) # (i+1/2, j) self.yee_grid_EM_fields[5] = B3 # (i+1/2, j+1/2) af.eval(self.yee_grid_EM_fields) return
def calculate_dfdp_background(self): """ Calculates the derivative of the background distribution with respect to the variables p1, p2, p3. This is used to solve for the contribution from the fields """ f_b = af.moddims(self.f_background, self.N_p1, self.N_p2, self.N_p3) # Using a 4th order central difference stencil: dfdp1_background = (-af.shift(f_b, -2) + 8 * af.shift(f_b, -1) + af.shift( f_b, 2) - 8 * af.shift(f_b, 1)) / (12 * self.dp1) dfdp2_background = (-af.shift(f_b, 0, -2) + 8 * af.shift(f_b, 0, -1) + af.shift(f_b, 0, 2) - 8 * af.shift(f_b, 0, 1)) / (12 * self.dp2) dfdp3_background = (-af.shift(f_b, 0, 0, -2) + 8 * af.shift(f_b, 0, 0, -1) + af.shift(f_b, 0, 0, 2) - 8 * af.shift(f_b, 0, 0, 1)) / (12 * self.dp3) # Reordering such that the variations in velocity are along axis 2 self.dfdp1_background = af.reorder(af.flat(dfdp1_background), 2, 3, 0, 1) self.dfdp2_background = af.reorder(af.flat(dfdp2_background), 2, 3, 0, 1) self.dfdp3_background = af.reorder(af.flat(dfdp3_background), 2, 3, 0, 1) af.eval(self.dfdp1_background, self.dfdp2_background, self.dfdp3_background) return
def RK2(dx_dt, x_initial, dt, *args): """ Integrates x from x_initial(t = t0) to x(t = t0 + dt) by taking slope from dx_dt, and integrates it using the RK2 method. This method is second order accurate. Parameters ---------- dx_dt: function Returns the slope dx_dt which is used to evolve x x_initial: array The value of x at the beginning of the timestep. dt: double The timestep size. """ x = x_initial + dx_dt(x_initial, *args) * (dt / 2) args[1].time_elapsed += 0.5 * dt x = x_initial + dx_dt(x, *args) * dt args[1].time_elapsed += 0.5 * dt af.eval(x) return (x)
def compute_electrostatic_fields(self, rho_hat): """ Computes the electrostatic fields by making use of FFTs by solving the Poisson equation: div^2 phi = rho to return the FT of the fields. Parameters ---------- rho_hat : af.Array FT for the charge density for each of the species. shape:(1, N_s, N_q1, N_q2) """ # Summing over all the species: phi_hat = multiply(af.sum(rho_hat, 1), 1 / (self.k_q1**2 + self.k_q2**2)) # (1, 1, N_q1, N_q2) # Setting the background electric potential to zero: phi_hat[: , :, 0, 0] = 0 self.E1_hat = -phi_hat * 1j * self.k_q1 / self.params.eps self.E2_hat = -phi_hat * 1j * self.k_q2 / self.params.eps self.E3_hat = 0 * self.E1_hat self.B1_hat = 0 * self.E1_hat self.B2_hat = 0 * self.E1_hat self.B3_hat = 0 * self.E1_hat af.eval(self.E1_hat, self.E2_hat, self.E3_hat, self.B1_hat, self.B2_hat, self.B3_hat ) return
def initialize_f(q1, q2, p1, p2, p3, params): m = params.mass_particle k = params.boltzmann_constant pert_real = params.pert_real pert_imag = params.pert_imag k_q1 = params.k_q1 k_q2 = params.k_q2 # Calculating the perturbed density: rho = 1 + (pert_real * af.cos(k_q1 * q1 + k_q2 * q2) - pert_imag * af.sin(k_q1 * q1 + k_q2 * q2)) n_p = 0.9 / np.sqrt(2 * np.pi) n_b = 0.2 / np.sqrt(2 * np.pi) f = rho \ * ( n_p * af.exp(-0.5*p1**2) + n_b * af.exp(-0.5*((p1 - 4.5)/0.5)**2) ) af.eval(f) return (f)
def _calculate_p_center(self): """ Initializes the cannonical variables p1, p2 and p3 using a centered formulation. The size, and resolution are the same as declared under domain of the physical system object. """ p1_center = \ self.p1_start + (0.5 + np.arange(0, self.N_p1, 1)) * self.dp1 p2_center = \ self.p2_start + (0.5 + np.arange(0, self.N_p2, 1)) * self.dp2 p3_center = \ self.p3_start + (0.5 + np.arange(0, self.N_p3, 1)) * self.dp3 p2_center, p1_center, p3_center = np.meshgrid(p2_center, p1_center, p3_center ) # Flattening the obtained arrays: p1_center = af.flat(af.to_array(p1_center)) p2_center = af.flat(af.to_array(p2_center)) p3_center = af.flat(af.to_array(p3_center)) # Reordering such that variation in velocity is along axis 2: # This is done to be consistent with the positionsExpanded form: p1_center = af.reorder(p1_center, 2, 3, 0, 1) p2_center = af.reorder(p2_center, 2, 3, 0, 1) p3_center = af.reorder(p3_center, 2, 3, 0, 1) af.eval(p1_center, p2_center, p3_center) return(p1_center, p2_center, p3_center)
def initialize_f(q1, q2, v1, v2, v3, params): m = params.mass k = params.boltzmann_constant q2_minus = 0.5 q2_plus = 1.5 regulator = 20 # larger value makes the transition sharper n = 1 + 0.5 * (af.tanh((q2 - q2_minus) * regulator) - af.tanh( (q2 - q2_plus) * regulator)) v1_bulk = (af.tanh((q2 - q2_minus) * regulator) - af.tanh( (q2 - q2_plus) * regulator) - 1) v2_bulk = 0.01 * af.sin(2 * np.pi * q1) *\ ( af.exp(-25 * (q2 - q2_minus)**2) + af.exp(-25 * (q2 - q2_plus )**2) ) T = (10 / n) f = n * (m / (2 * np.pi * k * T)) \ * af.exp(-m * (v1 - v1_bulk)**2 / (2 * k * T)) \ * af.exp(-m * (v2 - v2_bulk)**2 / (2 * k * T)) af.eval(f) return (f)
def initialize_f(r, theta, rdot, thetadot, phidot, params): # Using a transformation to get the coordinates in the form used in regular cartesian coordinates: q1 = r * af.cos(theta) q2 = r * af.sin(theta) p1 = rdot * af.cos(theta) - r * af.sin(theta) * thetadot p2 = rdot * af.sin(theta) + r * af.cos(theta) * thetadot q10 = params.q10 q20 = params.q20 p10 = params.p10 p20 = params.p20 sigma_q = params.sigma_q sigma_p = params.sigma_p q_profile = (1 / sigma_q**2 / (2 * np.pi)) * \ af.exp(-0.5 * ((q1 - q10)**2 + (q2 - q20)**2) / sigma_q**2) p_profile = (1 / sigma_p**2 / (2 * np.pi)) * \ af.exp(-0.5 * ((p1 - p10)**2 + (p2 - p20)**2) / sigma_p**2) f = q_profile * p_profile af.eval(f) return (f)
def RK5(dx_dt, x_initial, dt, *args): k1 = dx_dt(x_initial, *args) x = x_initial + 0.25 * k1 * dt k2 = dx_dt(x, *args) x = x_initial + (3 / 32) * (k1 + 3 * k2) * dt k3 = dx_dt(x, *args) x = x_initial + (12 / 2197) * (161 * k1 - 600 * k2 + 608 * k3) * dt k4 = dx_dt(x, *args) x = x_initial + (1 / 4104) * (8341 * k1 - 32832 * k2 + 29440 * k3 - 845 * k4) * dt k5 = dx_dt(x, *args) x = x_initial + (-(8 / 27) * k1 + 2 * k2 - (3544 / 2565) * k3 + (1859 / 4104) * k4 - (11 / 40) * k5) * dt k6 = dx_dt(x, *args) x = x_initial + 1 / 5 * ((16 / 27) * k1 + (6656 / 2565) * k3 + (28561 / 11286) * k4 - (9 / 10) * k5 + (2 / 11) * k6) * dt af.eval(x) return (x)
def f_left(f, t, q1, q2, p1, p2, p3, params): k = params.boltzmann_constant E_upper = params.E_band T = params.initial_temperature mu = params.initial_mu t = params.current_time omega = 2. * np.pi * params.AC_freq vel_drift_x_in = params.vel_drift_x_in if (params.p_space_grid == 'cartesian'): p_x = p1 p_y = p2 elif (params.p_space_grid == 'polar2D'): p_x = p1 * af.cos(p2) p_y = p1 * af.sin(p2) else: raise NotImplementedError('Unsupported coordinate system in p_space') fermi_dirac_in = (1. / (af.exp( (E_upper - vel_drift_x_in * p_x - mu) / (k * T)) + 1.)) if params.zero_temperature: fermi_dirac_in = fermi_dirac_in - 0.5 if (params.contact_geometry == "straight"): # Contacts on either side of the device q2_contact_start = params.contact_start q2_contact_end = params.contact_end cond = ((params.y >= q2_contact_start) & \ (params.y <= q2_contact_end) \ ) cond_2 = ((params.y >= 0.) & \ (params.y <= 1.) \ ) print("boundaries.py : ") f_left = cond * fermi_dirac_in + (1 - cond) * f elif (params.contact_geometry == "turn_around"): # Contacts on the same side of the device vel_drift_x_out = -params.vel_drift_x_in * np.sin(omega * t) fermi_dirac_out = (1. / (af.exp( (E_upper - vel_drift_x_out * p_x - mu) / (k * T)) + 1.)) # TODO: set these parameters in params.py cond_in = ((q2 >= 3.5) & (q2 <= 4.5)) cond_out = ((q2 >= 5.5) & (q2 <= 6.5)) f_left = cond_in*fermi_dirac_in + cond_out*fermi_dirac_out \ + (1 - cond_in)*(1 - cond_out)*f af.eval(f_left) return (f_left)
def lax_friedrichs_flux(left_flux, right_flux, left_f, right_f, c_lax): """ Returns the flux, using the Local Lax Friedrichs Riemann solver. **NOT TESTED** Parameters ---------- left_flux : af.Array Array holding the values for the flux at the left edge of the cells. right_flux : af.Array Array holding the values for the flux at the right edge of the cells. left_f : af.Array Array holding the values for the distribution function at the left edge of the cells. right_f : af.Array Array holding the values for the distribution function at the right edge of the cells. c_lax : double c_lax which it to be used. """ flux = 0.5 * (left_flux + right_flux) - 0.5 * c_lax * (right_f - left_f) af.eval(flux) return (flux)
def BGK(f, q1, q2, p1, p2, p3, moments, params): """Return BGK operator -(f-f0)/tau.""" n = moments('density') # Floor used to avoid 0/0 limit: eps = 1e-15 p1_bulk = moments('mom_p1_bulk') / (n + eps) p2_bulk = moments('mom_p2_bulk') / (n + eps) p3_bulk = moments('mom_p3_bulk') / (n + eps) T = (1 / params.p_dim) \ * ( moments('energy') - n * p1_bulk**2 - n * p2_bulk**2 - n * p3_bulk**2 ) / (n + eps) + eps C_f = -( f - f0(p1, p2, p3, n, T, p1_bulk, p2_bulk, p3_bulk, params) ) / params.tau(q1, q2, p1, p2, p3) # When (f - f0) is NaN. Dividing by np.inf doesn't give 0 # WORKAROUND: # C_f = af.select(params.tau(q1, q2, p1, p2, p3) == np.inf, 0, C_f) af.eval(C_f) return(C_f)
def band_energy(p1, p2): # Note :This function is only meant to be called once to initialize E_band if (p_space_grid == 'cartesian'): p_x = p1 p_y = p2 elif (p_space_grid == 'polar2D'): # In polar2D coordinates, p1 = radius and p2 = theta r = p1 theta = p2 p_x = r * af.cos(theta) p_y = r * af.sin(theta) else: raise NotImplementedError('Unsupported coordinate system in p_space') p = af.sqrt(p_x**2. + p_y**2.) if (dispersion == 'linear'): E_upper = p * fermi_velocity elif (dispersion == 'quadratic'): m = effective_mass(p1, p2) E_upper = p**2 / (2. * m) if (zero_temperature): E_upper = initial_mu * p**0. af.eval(E_upper) return (E_upper)
def op_fvm(self, dt): """ Evolves the system defined using FVM. It does so by integrating the function df_dt using an RK2 stepping scheme. After the initial evaluation at the midpoint, we evaluate the currents(J^{n+0.5}) and pass it to the FDTD algo when an electrodynamic case needs to be evolved. The FDTD algo updates the field values, which are used at the next evaluation of df_dt. Parameters ---------- dt : double Time-step size to evolve the system """ self._communicate_f() self._apply_bcs_f() if (self.performance_test_flag == True): tic = af.time() if (self.physical_system.params.instantaneous_collisions == True): split.strang(self, timestep_fvm, update_for_instantaneous_collisions, dt) else: timestep_fvm(self, dt) if (self.performance_test_flag == True): af.sync() toc = af.time() self.time_fvm_solver += toc - tic af.eval(self.f) return
def f_initial(config): """ Returns the value of f_initial, depending on the parameters set in the config object Parameters: ----------- config : Object config which is obtained by set() is passed to this file Output: ------- f_initial : Array which contains the values of f_initial at different values of vel_x and x """ mass_particle = config.mass_particle boltzmann_constant = config.boltzmann_constant rho_background = config.rho_background temperature_background = config.temperature_background vel_x = calculate_vel_x(config) pert_x_real = config.pert_x_real pert_x_imag = config.pert_x_imag k_x = config.k_x x = calculate_x(config) rho = rho_background + (pert_x_real * af.cos(2*np.pi*x) - pert_x_imag * af.sin(2*np.pi*x)) f_initial = rho * np.sqrt(mass_particle/(2*np.pi*boltzmann_constant*temperature_background)) * \ af.exp(-mass_particle*vel_x**2/(2*boltzmann_constant*temperature_background)) af.eval(f_initial) return f_initial
def calculate_x(config): """ Returns the 2D array of x which is used in the computations of the Cheng-Knorr code. Parameters: ----------- config : Object config which is obtained by set() is passed to this file Output: ------- x : Array holding the values of x tiled along axis 1 """ N_x = config.N_x N_vel_x = config.N_vel_x N_ghost_x = config.N_ghost_x left_boundary = config.left_boundary right_boundary = config.right_boundary x = np.linspace(left_boundary, right_boundary, N_x) dx = x[1] - x[0] x_ghost_left = np.linspace(-(N_ghost_x)*dx + left_boundary, left_boundary - dx, N_ghost_x) x_ghost_right = np.linspace(right_boundary + dx, right_boundary + N_ghost_x*dx , N_ghost_x) x = np.concatenate([x_ghost_left, x, x_ghost_right]) x = af.Array.as_type(af.to_array(x), af.Dtype.f64) x = af.tile(x, 1, N_vel_x) af.eval(x) return x
def initialize_f(q1, q2, p1, p2, p3, params): m = params.mass_particle k = params.boltzmann_constant rho_b = params.rho_background T_b = params.temperature_background p1_bulk = params.p1_bulk_background p2_bulk = params.p2_bulk_background p3_bulk = params.p3_bulk_background pert_real = params.pert_real pert_imag = params.pert_imag k_q1 = params.k_q1 k_q2 = params.k_q2 # Calculating the perturbed density: rho = rho_b + (pert_real * af.cos(k_q1 * q1 + k_q2 * q2) - pert_imag * af.sin(k_q1 * q1 + k_q2 * q2)) f = rho * (m / (2 * np.pi * k * T_b))**(3 / 2) \ * af.exp(-m * (p1 - p1_bulk)**2 / (2 * k * T_b)) \ * af.exp(-m * (p2 - p2_bulk)**2 / (2 * k * T_b)) \ * af.exp(-m * (p3 - p3_bulk)**2 / (2 * k * T_b)) af.eval(f) return (f)
def f_background(config): """ Returns the value of f_background, depending on the parameters set in the config class Parameters: ----------- config : Class config which is obtained by set() is passed to this file Output: ------- f_background : Array which contains the values of f_background at different values of vel_x and x """ mass_particle = config.mass_particle boltzmann_constant = config.boltzmann_constant rho_background = config.rho_background temperature_background = config.temperature_background vel_x = calculate_vel_x(config) f_background = rho_background * np.sqrt(mass_particle/(2*np.pi*boltzmann_constant*temperature_background)) * \ af.exp(-mass_particle*vel_x**2/(2*boltzmann_constant*temperature_background)) af.eval(f_background) return f_background
def initialize_f(q1, q2, v1, v2, v3, params): m_e = params.mass[0, 0] m_i = params.mass[0, 1] k = params.boltzmann_constant n = params.n_background * q1**0 u_be = params.u_be u_bi = params.u_bi T = params.T_background f_e = n * (m_e / (2 * np.pi * k * T))**(3 / 2) \ * 0.5 * ( af.exp(-m_e * (v1[:, 0] - u_be)**2 / (2 * k * T)) + af.exp(-m_e * (v1[:, 0] + u_be)**2 / (2 * k * T)) ) \ * af.exp(-m_e * v2[:, 0]**2 / (2 * k * T)) \ * af.exp(-m_e * v3[:, 0]**2 / (2 * k * T)) f_i = n * (m_i / (2 * np.pi * k * T))**(3 / 2) \ * 0.5 * ( af.exp(-m_i * (v1[:, 1] - u_bi)**2 / (2 * k * T)) + af.exp(-m_i * (v1[:, 1] + u_bi)**2 / (2 * k * T)) ) \ * af.exp(-m_i * v2[:, 1]**2 / (2 * k * T)) \ * af.exp(-m_i * v3[:, 1]**2 / (2 * k * T)) f = af.join(1, f_e, f_i) af.eval(f) return (f)
def initialize_f(q1, q2, p1, p2, p3, params): m = params.mass_particle k = params.boltzmann_constant rho = af.select(af.abs(q2) > 0.25, q1**0, 2) # Seeding the instability p1_bulk = af.reorder(p1_bulk, 1, 2, 0, 3) p1_bulk += af.to_array( np.random.rand(1, q1.shape[1], q1.shape[2]) * np.random.choice([-1, 1], size=(1, q1.shape[1], q1.shape[2]))) * 0.005 p2_bulk = af.to_array( np.random.rand(1, q1.shape[1], q1.shape[2]) * np.random.choice([-1, 1], size=(1, q1.shape[1], q1.shape[2]))) * 0.005 p1_bulk = af.reorder(p1_bulk, 2, 0, 1, 3) p2_bulk = af.reorder(p2_bulk, 2, 0, 1, 3) T = (2.5 / rho) f = rho * (m / (2 * np.pi * k * T))**(3 / 2) \ * af.exp(-m * (p1 - p1_bulk)**2 / (2 * k * T)) \ * af.exp(-m * (p2 - p2_bulk)**2 / (2 * k * T)) \ * af.exp(-m * (p3)**2 / (2 * k * T)) af.eval(f) return (f)
def initialize_f(q1, q2, v1, v2, v3, params): m_e = params.mass[0, 0] m_p = params.mass[0, 1] k = params.boltzmann_constant n_b = params.density_background T_b = params.temperature_background k = params.boltzmann_constant v1_bulk_electron = params.v1_bulk_electron v1_bulk_positron = params.v1_bulk_positron n = n_b + 0.01 * af.exp(-10 * (q1 - 5)**2) f_e = n * (m_e / (2 * np.pi * k * T_b))**(1 / 2) \ * af.exp(-m_e * (v1[:, 0] - v1_bulk_electron)**2 / (2 * k * T_b)) \ f_p = n * (m_p / (2 * np.pi * k * T_b))**(1 / 2) \ * af.exp(-m_p * (v1[:, 1] - v1_bulk_positron)**2 / (2 * k * T_b)) \ f = af.join(1, f_e, f_p) af.eval(f) return (f)
def initialize_f(q1, q2, p1, p2, p3, params): m = params.mass_particle k = params.boltzmann_constant rho = af.select(af.abs(q2) > 0.25, q1**0, 2) try: p1_bulk = af.select( af.abs(q2) > 0.25, -0.5 - 0.01 * (af.randu(1, q1.shape[1], q2.shape[2], dtype=af.Dtype.f64) - 0.5), +0.5 + 0.01 * (af.randu(1, q1.shape[1], q2.shape[2], dtype=af.Dtype.f64) - 0.5)) p2_bulk = 0.01 * ( af.randu(1, q1.shape[1], q2.shape[2], dtype=af.Dtype.f64) - 0.5) except: p1_bulk = af.select( af.abs(q2) > 0.25, -0.5 - 0.01 * (af.randu(q1.shape[0], q2.shape[1], dtype=af.Dtype.f64) - 0.5), +0.5 + 0.01 * (af.randu(q1.shape[0], q2.shape[1], dtype=af.Dtype.f64) - 0.5)) p2_bulk = 0.01 * ( af.randu(q1.shape[0], q2.shape[1], dtype=af.Dtype.f64) - 0.5) T = (2.5 / rho) f = rho * (m / (2 * np.pi * k * T))**(3 / 2) \ * af.exp(-m * (p1 - p1_bulk)**2 / (2 * k * T)) \ * af.exp(-m * (p2 - p2_bulk)**2 / (2 * k * T)) \ * af.exp(-m * p3**2 / (2 * k * T)) af.eval(f) return (f)
def op_fvm_q(self, dt): self._communicate_f() self._apply_bcs_f() if (self.performance_test_flag == True): tic = af.time() fvm_timestep_RK2(self, dt) if (self.performance_test_flag == True): af.sync() toc = af.time() self.time_fvm_solver += toc - tic # Solving for tau = 0 systems if (af.any_true( self.physical_system.params.tau(self.q1_center, self.q2_center, self.p1, self.p2, self.p3) == 0)): if (self.performance_test_flag == True): tic = af.time() self.f = self._source(self.f, self.q1_center, self.q2_center, self.p1, self.p2, self.p3, self.compute_moments, self.physical_system.params, True) if (self.performance_test_flag == True): af.sync() toc = af.time() self.time_sourcets += toc - tic af.eval(self.f) return
def initialize_f(q1, q2, p1, p2, p3, params): m = params.mass k = params.boltzmann_constant q2_minus = 0.5 q2_plus = 1.5 regulator = 20 # larger value makes the transition sharper rho = 1 + 0.5 * ( af.tanh(( q2 - q2_minus)*regulator) - af.tanh(( q2 - q2_plus )*regulator) ) p1_bulk = ( af.tanh(( q2 - q2_minus)*regulator) - af.tanh(( q2 - q2_plus )*regulator) - 1 ) p2_bulk = 0.5 * af.sin(2*np.pi*q1) *\ ( af.exp(-25 * (q2 - q2_minus)**2) + af.exp(-25 * (q2 - q2_plus )**2) ) T = (10 / rho) f = rho * (m / (2 * np.pi * k * T))**(3 / 2) \ * af.exp(-m * (p1 - p1_bulk)**2 / (2 * k * T)) \ * af.exp(-m * (p2 - p2_bulk)**2 / (2 * k * T)) \ * af.exp(-m * (p3)**2 / (2 * k * T)) af.eval(f) return (f)
def calc_arrayfire(A, b, x0, maxiter=10): x = af.constant(0, b.dims()[0], dtype=af.Dtype.f32) r = b - af.matmul(A, x) p = r for i in range(maxiter): Ap = af.matmul(A, p) alpha_num = af.dot(r, r) alpha_den = af.dot(p, Ap) alpha = alpha_num/alpha_den r -= af.tile(alpha, Ap.dims()[0]) * Ap x += af.tile(alpha, Ap.dims()[0]) * p beta_num = af.dot(r, r) beta = beta_num/alpha_num p = r + af.tile(beta, p.dims()[0]) * p af.eval(x) res = x0 - x return x, af.dot(res, res)
def mandelbrot(data, it, maxval): C = data Z = data mag = af.constant(0, *C.dims()) for ii in range(1, 1 + it): # Doing the calculation Z = Z * Z + C # Get indices where abs(Z) crosses maxval cond = ((af.abs(Z) > maxval)).as_type(af.Dtype.f32) mag = af.maxof(mag, cond * ii) C = C * (1 - cond) Z = Z * (1 - cond) af.eval(C) af.eval(Z) return mag / maxval
def simple_device(verbose=False): display_func = _util.display_func(verbose) print_func = _util.print_func(verbose) print_func(af.device_info()) print_func(af.get_device_count()) print_func(af.is_dbl_supported()) af.sync() curr_dev = af.get_device() print_func(curr_dev) for k in range(af.get_device_count()): af.set_device(k) dev = af.get_device() assert(k == dev) print_func(af.is_dbl_supported(k)) af.device_gc() mem_info_old = af.device_mem_info() a = af.randu(100, 100) af.sync(dev) mem_info = af.device_mem_info() assert(mem_info['alloc']['buffers'] == 1 + mem_info_old['alloc']['buffers']) assert(mem_info[ 'lock']['buffers'] == 1 + mem_info_old[ 'lock']['buffers']) af.set_device(curr_dev) a = af.randu(10,10) display_func(a) dev_ptr = af.get_device_ptr(a) print_func(dev_ptr) b = af.Array(src=dev_ptr, dims=a.dims(), dtype=a.dtype(), is_device=True) display_func(b) c = af.randu(10,10) af.lock_array(c) af.unlock_array(c) a = af.constant(1, 3, 3) b = af.constant(2, 3, 3) af.eval(a) af.eval(b) print_func(a) print_func(b) c = a + b d = a - b af.eval(c, d) print_func(c) print_func(d) print_func(af.set_manual_eval_flag(True)) assert(af.get_manual_eval_flag() == True) print_func(af.set_manual_eval_flag(False)) assert(af.get_manual_eval_flag() == False) display_func(af.is_locked_array(a))
if __name__ == "__main__": if (len(sys.argv) > 1): af.set_device(int(sys.argv[1])) af.info() M = 4000 S = af.randu(M, 1) X = af.randu(M, 1) R = af.randu(M, 1) V = af.randu(M, 1) T = af.randu(M, 1) (C, P) = black_scholes(S, X, R, V, T) af.eval(C) af.eval(P) af.sync() num_iter = 100 for N in range(50, 501, 50): S = af.randu(M, N) X = af.randu(M, N) R = af.randu(M, N) V = af.randu(M, N) T = af.randu(M, N) af.sync() print("Input data size: %d elements" % (M * N)) start = time()
def simple_algorithm(verbose = False): display_func = _util.display_func(verbose) print_func = _util.print_func(verbose) a = af.randu(3, 3) k = af.constant(1, 3, 3, dtype=af.Dtype.u32) af.eval(k) print_func(af.sum(a), af.product(a), af.min(a), af.max(a), af.count(a), af.any_true(a), af.all_true(a)) display_func(af.sum(a, 0)) display_func(af.sum(a, 1)) display_func(af.product(a, 0)) display_func(af.product(a, 1)) display_func(af.min(a, 0)) display_func(af.min(a, 1)) display_func(af.max(a, 0)) display_func(af.max(a, 1)) display_func(af.count(a, 0)) display_func(af.count(a, 1)) display_func(af.any_true(a, 0)) display_func(af.any_true(a, 1)) display_func(af.all_true(a, 0)) display_func(af.all_true(a, 1)) display_func(af.accum(a, 0)) display_func(af.accum(a, 1)) display_func(af.scan(a, 0, af.BINARYOP.ADD)) display_func(af.scan(a, 1, af.BINARYOP.MAX)) display_func(af.scan_by_key(k, a, 0, af.BINARYOP.ADD)) display_func(af.scan_by_key(k, a, 1, af.BINARYOP.MAX)) display_func(af.sort(a, is_ascending=True)) display_func(af.sort(a, is_ascending=False)) b = (a > 0.1) * a c = (a > 0.4) * a d = b / c print_func(af.sum(d)); print_func(af.sum(d, nan_val=0.0)); display_func(af.sum(d, dim=0, nan_val=0.0)); val,idx = af.sort_index(a, is_ascending=True) display_func(val) display_func(idx) val,idx = af.sort_index(a, is_ascending=False) display_func(val) display_func(idx) b = af.randu(3,3) keys,vals = af.sort_by_key(a, b, is_ascending=True) display_func(keys) display_func(vals) keys,vals = af.sort_by_key(a, b, is_ascending=False) display_func(keys) display_func(vals) c = af.randu(5,1) d = af.randu(5,1) cc = af.set_unique(c, is_sorted=False) dd = af.set_unique(af.sort(d), is_sorted=True) display_func(cc) display_func(dd) display_func(af.set_union(cc, dd, is_unique=True)) display_func(af.set_union(cc, dd, is_unique=False)) display_func(af.set_intersect(cc, cc, is_unique=True)) display_func(af.set_intersect(cc, cc, is_unique=False))