def randomizePositions(self, scale=0.1): if not self.steps: self.positions = self.r0 return n = len(self.r0) rx = maxwell.rvs(size=n) ry = maxwell.rvs(size=n) rz = maxwell.rvs(size=n) r = np.array([rx, ry, rz]) sign = lambda x: math.copysign(1, x) r = np.transpose(r) self.positions = self.positions + r * scale
def add_particle(x, _id): p1 = ET.Element("Pt") p1.set("ID", str(_id)) x1 = ET.SubElement(p1, "P") x1.set("x", str(x[0])) x1.set("y", str(x[1])) x1.set("z", str(x[2])) v1 = ET.SubElement(p1, "V") v1.set("x", str(maxwell.rvs())) v1.set("y", str(maxwell.rvs())) v1.set("z", str(maxwell.rvs())) particle_data_tag.insert(_id, p1)
def sample_Vkick(Nsys, Vmin=0, Vmax=1000, method='maxwellian', sigma=265, samples=None): """ Samples velocity of SN2 natal kick Inputs in units km/s Possible methods: 'uniform': samples Vkick flat between Vmin and Vmax 'maxwellian': samples Vkick from a maxwellian distribution of scale parameter sigma 'fixed': uses fixed value for Vkick 'popsynth': Vkick is taken from popsynth model at path 'samples' """ if method=='uniform': Vkick_samp = np.random.uniform(Vmin, Vmax, size=Nsys) elif method=='maxwellian': Vkick = maxwell.rvs(loc=0, scale=sigma, size=Nsys) elif method=='fixed': if sigma==None: raise ValueError("No fixed Vkick specified!") Vkick = np.ones(Nsys)*sigma elif method=='popsynth': if 'Vkick' not in samples.columns: raise NameError("Series '{0:s}' not in popsynth table".format('Vkick')) Vkick = np.asarray(samples['Vkick']) else: raise ValueError("Undefined Vkick sampling method '{0:s}'.".format(method)) return Vkick*u.km/u.s
def MBdist( n, e_photon, thick ): # n: particle number, loct: start point(x-x0), scale: sigma, wl: wavelength,thick: thickness of the cathode assert e_photon > bandgap if e_photon - bandgap - 0.8 <= 0: scale = e_photon - bandgap loct = 0 else: scale = 0.8 loct = e_photon - bandgap - scale data = maxwell.rvs(loc=loct, scale=scale, size=n) data_ene = np.array(data) params = maxwell.fit(data, floc=0) data_v = np.sqrt(2 * data_ene * ec / me) * 10**9 p2D = [] wl = ((19.82 - 27.95 * e_photon + 11.15 * e_photon**2) * 10**-3)**-1 pens = expon.rvs(loc=0, scale=wl, size=n) penss = filter(lambda x: x <= thick, pens) params_exp = expon.fit(pens, floc=0) i = 0 for n in range(len(penss)): phi = random.uniform(0, 2 * math.pi) # initial angular poy = random.uniform(-1 * 10**6, 1 * 10**6) # initial y direction position p2D.append([ penss[i], poy, data_v[i] * math.cos(phi), data_v[i] * math.sin(phi), data_v[i], data[i] ]) #p2D: (z,y,vz,vy,v,ene) i += 1 p2D = np.array(p2D) return params, p2D, penss, params_exp
def rescale_velocities(self, temp): """Rescales atom velocities randomly according to maxwell boltzmann distribution.""" random.seed(None) for i, element in self.enumerate(): scale = math.sqrt(kb * temp / masses[element]) speed = maxwell.rvs(scale=scale, size=1)[0] self.velocities[i] *= speed / np.linalg.norm(self.velocities[i])
def maxwelian_v_dist(vt, vb, N): vel = maxwell.rvs(loc=vt, scale=vt, size=int(N)) #plt.figure(3) #plt.hist(vel,bins=100) cosi = np.zeros(N) sini = np.zeros(N) cosi, sini = angles(cosi, sini, N) return (vel * cosi + vb), vel * sini
def generate_initial_velocities(atoms, m, T): v = [] for n in range(len(atoms)): a = np.sqrt((k[0] * T) / m[n]) transl_vec = np.full(3, maxwell(scale=a).stats('m') / 2) distr = maxwell.rvs(scale=a, size=3) v.append((distr - transl_vec) * 2) return np.array(v)
def _calculate_scaling_factor(self): # pick new temperature randomly self._new_temperature = maxwell.rvs(loc=self.temperature - self.temperature_noise_range, scale=self.temperature_noise_range) self._currentTemperature = ( self.system._currentTemperature if (self.system._currentTemperature != 0) else 0.000001) self.system._currentTemperature = self._new_temperature # scaling factor self._lambda = self._new_temperature / self._currentTemperature # (1+(self.dt/self.tau)*((self.system.temperature/T_t)-1))**0.5
def random_velocity_init(self, amplitude: float): random_theta = np.random.random(size=self.N) * 2 * np.pi random_phi = np.random.random(size=self.N) * np. pi directions_x = np.cos(random_theta) * np.sin(random_phi) directions_y = np.sin(random_theta) * np.sin(random_phi) directions_z = np.cos(random_phi) amplitudes = maxwell.rvs(size=self.N, loc=amplitude) self.v[:,0] += amplitudes * directions_x self.v[:,1] += amplitudes * directions_y self.v[:,2] += amplitudes * directions_z
def mb_velocities(N, D, vmax): vel = np.zeros((N, D)) for i in range(N): for d in range(D): while True: v = maxwell.rvs(loc=0, scale=1) - vmax if abs(v) <= vmax: vel[i, d] = v break return vel
def genMomenta(self, masses, scale=0.01): if not self.steps: return n = len(masses) rx = maxwell.rvs(size=n) ry = maxwell.rvs(size=n) rz = maxwell.rvs(size=n) r = np.array([rx, ry, rz]) sign = lambda x: math.copysign(1, x) r = np.transpose(r) for i in range(len(r)): x = np.random.random_sample() - 0.5 y = np.random.random_sample() - 0.5 z = np.random.random_sample() - 0.5 r[i][0] = r[i][0] * sign(x) r[i][1] = r[i][1] * sign(y) r[i][2] = r[i][2] * sign(z) r = np.multiply(masses, r) r = np.multiply(r, scale) return r
def get_x_velocity(T, L, atom): ''' this gets average velocity (not even in x, y-axis), so need to fix ''' x_velocity_avg = ((3 * T * k_b) / (atom['M']))**(1 / 2) scale = get_scale_from_mu(x_velocity_avg) loc = get_loc_from_mu(x_velocity_avg) #print(scale, loc) x_velocity = maxwell.rvs(scale=scale, loc=loc) #print(x_velocity) return x_velocity
def generate_particles(n, box_x, box_y, box_z, particle_radius): #Generate balls in a grid like pattern starting from the bottom #of the box so that none of the balls are overlapping at the #start of the simulation array = [] box_length = box_x # since all 3 directions are the same length e = box_x / 100 # this is epsilon - the length that separates each ball num_balls = box_length / (2 * particle_radius + 2 * e) num_balls = int(num_balls) # round down to be on the safe side counter_y = 0 counter_z = 0 inc = particle_radius + e x_pos = -box_x / 2 y_pos = -box_x / 2 + inc z_pos = -box_x / 2 + inc x_vel_dist = maxwell.rvs(size=n) y_vel_dist = maxwell.rvs(size=n) z_vel_dist = maxwell.rvs(size=n) #The following loop generates particles that are evenly spaced for i in range(n): x_vel = x_vel_dist[i] y_vel = y_vel_dist[i] z_vel = z_vel_dist[i] x_pos += inc particle = sphere(pos=vector(x_pos, y_pos, z_pos), radius=particle_radius, color=color.white, velocity=vector(x_vel, y_vel, z_vel), mass=1) array.append(particle) counter_y += 1 counter_z += 1 if counter_z % num_balls == 0: z_pos += 2 * inc x_pos = -box_x / 2 - inc if counter_y % num_balls**2 == 0: y_pos += 2 * inc z_pos = -box_x / 2 + inc x_pos += inc return array
def init_velocities(self, temp): """Initializes velocies randomly according to maxwell boltzmann distribution. """ random.seed(None) for i, element in self.enumerate(): scale = math.sqrt(kb * temp / masses[element]) speed = maxwell.rvs(scale=scale, size=1)[0] theta = random.uniform(0, 360) phi = random.uniform(0, 180) vx = speed * math.sin(phi) * math.cos(theta) vy = speed * math.sin(phi) * math.sin(theta) vz = speed * math.cos(phi) self.velocities[i] = np.array((vx, vy, vz))
def get_v_kick(N, sigma=c.v_kick_sigma): """ Generate random kick velocities from a Maxwellian distribution. Args: N : int, number of random samples to generate sigma : float (default: constants.v_kick_sigma), Maxwellian dispersion velocity (km/s) Returns: v_kick : ndarray, array of random kick velocities (km/s) """ return maxwell.rvs(scale=sigma, size=N)
def get_v_k(sigma, N): """ Generate random kick velocities from a Maxwellian distribution Parameters ---------- sigma : float Maxwellian dispersion velocity (km/s) N : int Number of random samples to generate Returns ------- v_k : ndarray Array of random kick velocities """ return maxwell.rvs(scale = sigma, size = N)
def init_coords(layers=Device.layers, num_carr=Device.num_carr, mean_nrg=Device.mean_energy): #initialize positions (x, y, z) in angstroms # spread = 10E-9 # print ("Initializing carrier positions in nm.") #pos_mu, pos_sigma = 0, Device.dim[2]/6 x = np.random.uniform(0, np.max(Device.dim, axis=0)[0], int(num_carr)) y = np.random.uniform(0, np.max(Device.dim, axis=0)[1], int(num_carr)) z = np.random.uniform(0, np.max(Device.dim, axis=0)[2], int(num_carr)) # x = np.random.uniform(-spread, spread, int(num_carr)) # y = np.random.uniform(-spread, spread, int(num_carr)) # z = np.abs(np.random.normal(0, layers[0].lz, int(num_carr))) #z = abs(np.random.normal(pos_mu, pos_sigma, int(num_carr))) # print ("Sample position: (%0.3g, %0.3g, %0.3g)" %(x[0], y[0], z[0])) # initialize wave vectors, x1E9 m^-1 # print ("Initializing initial energy (eV).") mean, scale = mean_nrg, 1E-7 e = maxwell.rvs(loc=mean * Parameters.kT, scale=scale, size=num_carr) # print ("Initializing initial wave vectors (m^-1).") kx = [] ky = [] kz = [] for ndx, i in enumerate(e): mat = layers[where_am_i(layers, z[ndx])['current_layer']].matl k = np.sqrt(2 * mat.mass[0] * Parameters.q * convert_to_np(i, mat, 0) / Parameters.hbar**2) alpha = np.random.uniform(0, 2 * np.pi) cosb = 1 - 2 * np.random.uniform(0, 1) sinb = np.sqrt(1 - cosb**2) kx.append(k * np.cos(alpha) * sinb) ky.append(k * np.sin(alpha) * sinb) kz.append(k * cosb) coords = np.zeros((num_carr, 6)) # remove for loop for i in range(num_carr): coords[i][0] = kx[i] coords[i][1] = ky[i] coords[i][2] = kz[i] coords[i][3] = x[i] coords[i][4] = y[i] coords[i][5] = z[i] return coords
def set_initial_conditions(self): """ Sets initial conditions inside the box. It sets positions and velocities of each particles. """ i = 0 for x in np.arange(0, self.dim[0], 2.45*self.r_m): for y in np.arange(0, self.dim[1], 2.45*self.r_m): for z in np.arange(0, self.dim[2], 2.45*self.r_m): if i >= len(self.particles): break self.particles[i].set_position(np.array([x, y, z], dtype=float)) i += 1 # positions = np.random.uniform(0, self.dim, size=(self.num_particles, 3)) for i, particle in enumerate(self.particles): scale = math.sqrt(sconst.k * self.temperature / particle.mass) # particle.set_position(positions[i]) particle.set_velocity(maxwell.rvs(size=3, scale=scale)/math.sqrt(3)*np.random.choice([-1, 1], 3))
def boundaryCheck(self): self.contact = self.r // 1 if self.boundary == 'box': self.v -= 2 * self.v * np.abs(self.contact) elif self.boundary == 'box_w': is_out = (np.sum((self.contact != 0), axis=1)) != 0 is_out_n = np.sum(is_out) if is_out_n > 0: #print(f'{np.mean(np.abs(self.v)) = }') #print(f'{is_out = }\n{is_out_n = }') #print(f'{np.linalg.norm(self.v[is_out,:],axis=1).shape = }') #print(f'{np.linalg.norm(self.v[is_out,:],axis=1) = }\n{np.linalg.norm(self.v[is_out,:],axis=1)*np.linalg.norm(self.v[is_out,:],axis=1) = }') energy_out = np.sum( np.linalg.norm(self.v[is_out, :], axis=1) * np.linalg.norm( self.v[is_out, :], axis=1)) + self.reservoir_energy #print(f'{energy_out/(is_out_n+1) = }') #abs_v=1+np.random.standard_normal([is_out_n+1]) abs_v = maxwell.rvs(size=is_out_n + 1) abs_v *= np.sqrt(energy_out / np.sum(abs_v * abs_v)) #print(f'{abs_v*abs_v = }') self.reservoir_energy = abs_v[-1] * abs_v[-1] abs_v = abs_v[:-1] #print(f'{abs_v = }') #print(f'{self.reservoir_energy = }') ang = 2 * np.pi * np.random.rand(is_out_n) new_velocities = np.array([ np.multiply(abs_v, np.cos(ang)), np.multiply(abs_v, np.sin(ang)) ]).T #print(f'{new_velocities = }') #print(f'{self.contact[is_out] = }\n{self.contact[is_out] != 0 = }\n{self.contact[self.contact!=0] = }') new_velocities[self.contact[is_out] != 0] = -self.contact[self.contact != 0] * np.abs( new_velocities[self.contact[is_out] != 0]) #print(f'{self.v[is_out,:].shape = }') self.v[is_out, :] = new_velocities #self.v[self.contact!=0]=-self.contact*self.v[self.contact!=0] #print(f'{new_velocities = }\n{energy_rand = }') #self.v -= 2 * self.v * np.abs(self.contact) else: self.r -= self.contact
def init_vel(n_part, v_mean=[1, 0.062, 0.062]): """ Maxwell for radial and perpendicular (thermal) initial velocities. Since OX points to the Sun, vx should be negative. Since mean value = 2*scale*sqrt(2/pi), I'll put v_mean/1.59577 as scale. :param n_part: number of particles. :param v_mean: list of 3 mean velocities x, y, z. 0.062 = 35/(400*sqrt(2)) :return: array of velocities (n_part, 3). """ ret = np.zeros((n_part, 3)) for i in range(3): for j, el in enumerate( maxwell.rvs(scale=v_mean[i] / 1.59577, size=n_part)): ret[j][i] = el if i == 0: ret[j][i] *= -1 elif np.random.randint( 2): # some particles should have negative vy or vz or both ret[j][i] *= -1 return ret
def stern_gerlach(dB_dz=82, T=190, l=0.1, d=0.32, iterations=10000, blende=0.00): T = T + 273 mu_B = 9.72 * (10**(-24)) m_k = 6.492 * (10**(-26)) g_s = 2 defs = [] for i in range(iterations): if np.random.randint(1, 3) == 1: s = 0.5 else: s = -0.5 F = g_s * mu_B * s * dB_dz v = maxwell.rvs(scale=np.sqrt(c.k * T / m_k)) t = l / v z = 0.5 * F / m_k * t**2 angle = np.arctan((F / m_k * t) / (v)) angle += np.random.uniform(-3 * blende, 3 * blende) z_0 = np.random.uniform(-blende, blende) deflection = z_0 + z + d * (np.tan(angle)) defs.append(deflection) return defs
def vel_distribution(dm_p): #reads in particle class details (FROM ALAN AND CORRECT) vrange = 10.**(np.linspace(1.,3.,num=100000.)) * units.km/units.s print vrange mass =10.*units.GeV/const.c**2 temp = (0.5 * dm_p.mass* (230. * units.km/units.s)**2)/const.k_B print "Effective temp for DM particles moving at 230km/s ", temp.to(units.Kelvin) a = np.sqrt(const.k_B * temp/mass) print "Normalisation velocity ",a scale = a rv = maxwell.pdf(vrange, loc=0, scale=scale) plt.plot(vrange,rv,'-',color='b') #rv instead of 3000 plt.title('Velocity Distribution') #plt.show() plt.clf() #global v_values v_values_i = maxwell.rvs(size=10000, loc=0, scale=scale) *units.m/units.s v_values = ((v_values_i)*1000) / const.c print("Velocity Values", v_values) plt.hist(v_values,1000,color='b',normed=1) plt.title('Velocity Samples') #plt.show() plt.clf() return v_values
def crear_bolas(self): escala = np.sqrt(Constants.kBJ*self.T/self.m) bolas_grafica = [] bolas_visual = [] v = [] for i in range(self.n_graph): # PosiciĆ³n inicial pos = (rd.uniform(-1,1)*self.cubo.length/2+self.cubo.pos[0],rd.uniform(-1,1)*self.cubo.height/2+self.cubo.pos[1],rd.uniform(-1,1)*self.cubo.width/2+self.cubo.pos[2]) # Velocidad inicial cos_theta = rd.uniform(-1,1) phi = rd.uniform(0,2*np.pi) theta = np.arccos(cos_theta) v = maxwell.rvs(scale=escala)*Units.m/Units.s v_x = v*np.sin(theta)*np.cos(phi) v_y = v*np.sin(theta)*np.sin(phi) v_z = v*np.cos(theta) bola_grafica = Bola(pos=np.array(pos),v=np.array([v_x,v_y,v_z]),m=self.m) bolas_grafica.append(bola_grafica) if np.mod(i,self.n_graph/self.n_vis)==0: bola_visual = vs.sphere(pos=np.array(pos),radius=self.r,color=(0,1,0),v=np.array([v_x,v_y,v_z])) bolas_visual.append(bola_visual) return bolas_visual,bolas_grafica
def init_coords(layers=Device.layers, num_carr=Device.num_carr, mean_nrg=Device.mean_energy): #initialize positions (x, y, z) x = np.random.uniform(0, np.max(Device.dim, axis=0)[0], int(num_carr)) y = np.random.uniform(0, np.max(Device.dim, axis=0)[1], int(num_carr)) z = np.random.exponential(1 / layers[0].matl.alpha, int(num_carr)) # initialize wave vectors, x1E9 m^-1 # print ("Initializing initial energy (eV).") mean, scale = mean_nrg, 1E-7 e = maxwell.rvs(loc=mean * const.kT, scale=scale, size=num_carr) # print ("Initializing initial wave vectors (m^-1).") kx = [] ky = [] kz = [] for ndx, i in enumerate(e): mat = layers[where_am_i(layers, z[ndx])['current_layer']].matl k = np.sqrt(2 * mat.mass[0] * const.q * i / const.hbar**2) alpha = np.random.uniform(0, 2 * np.pi) beta = np.random.uniform(0, 2 * np.pi) kx.append(k * np.cos(alpha) * np.sin(beta)) ky.append(k * np.sin(alpha) * np.sin(beta)) kz.append(k * np.cos(beta)) coords = np.zeros((num_carr, 6)) # remove for loop for i in range(num_carr): coords[i][0] = kx[i] coords[i][1] = ky[i] coords[i][2] = kz[i] coords[i][3] = x[i] coords[i][4] = y[i] coords[i][5] = z[i] return coords
# v is a discretized velocity dim(v) = 3 x t v = np.array([[0,0,0]]*T, dtype = np.float) # This is the displacement matrix of dim(x) = 3 x t X = np.array([[0,0,0]]*T, np.float) #F is a discretized Lorentz Force dim(F) = 3 x t F = np.array([[0,0,0]]*T, np.float) # In[348]: for e in range(3): val = maxwell.rvs(size = T) for n in range(T): v[n][e] = val[n] # In[349]: #Initial Position X[(0,0)] = 0 X[(0,1)] = 0 X[(0,2)] = 0 # In[350]:
def sample_Vkick_maxwellian(self, scale=265, size=None): ''' sample kick velocity from Maxwellian (Hobbs 2005) ''' Vkick_samp = maxwell.rvs(loc=0, scale=scale, size=size) return Vkick_samp
out.write('Coords\n') for i in range(N): s='\t'.join(['{}']*4) fs = [types[i]] + [uniform(-limit, limit) for j in range(3)] out.write(s.format(*fs)+'\n') out.close() out = open('vels.xyz','w') out.write(str(N)) out.write('\n') out.write('Coords\n') for i in range(N): s='\t'.join(['{}']*4) direction = np.array([uniform(-limit, limit) for j in range(3)]) direction /= np.linalg.norm(direction) value = maxwell.rvs(loc=0, scale=(R*T/mols[types[i]])**0.5, size=1)[0] value *= meters_sec_to_units fs = [types[i]] + [value*i for i in direction] out.write(s.format(*fs)+'\n') out.close() out = open('tmp.xyz','w') out.write(str(3*N)) out.write('\n') out.write('tmp\n') alltypes = [i for i in moltypes] alltypes.append('N') for i in alltypes: for j in range(N): s = s='\t'.join(['{}']*4) s = s.format(i,0,0,0)
def setup(self): self.particles = [ Particle(np.array([x, y, z]), np.array(maxwell.rvs(size=3))) for x in range(self.size) for y in range(self.size) for z in range(self.size) ]
# Parallel energy plt.figure() plt.hist(np.random.normal(Kpar_mean, Tpar, size=10000), bins=1000) axes = plt.gca() for en in range(len(Kpar)): par_en = Kpar[en] plt.plot([par_en, par_en], axes.get_ylim(), c=colors[en], linestyle='--') plt.xlabel(r'v$_{||} [eV]$') plt.ylabel('Counts [a.u.]') # Perpendicular energy plt.figure() plt.hist(maxwell.rvs(loc=0.0, scale=Tperp, size=10000), bins=1000) axes = plt.gca() for en in range(len(Kperp)): perp_en = Kperp[en] plt.plot([perp_en, perp_en], axes.get_ylim(), c=colors[en], linestyle='--') plt.plot([perp_en, perp_en], axes.get_ylim(), 'r--') plt.xlabel(r'v$_{\perp} [eV]$') plt.ylabel('Counts [a.u.]') # ======================= Parallel running ============================== # pid = os.getpid() #multiprocessing.current_process().pid
x = np.linspace(maxwell.ppf(0.01), maxwell.ppf(0.99), 100) ax.plot(x, maxwell.pdf(x), 'r-', lw=5, alpha=0.6, label='maxwell pdf') # Alternatively, the distribution object can be called (as a function) # to fix the shape, location and scale parameters. This returns a "frozen" # RV object holding the given parameters fixed. # Freeze the distribution and display the frozen ``pdf``: rv = maxwell() ax.plot(x, rv.pdf(x), 'k-', lw=2, label='frozen pdf') # Check accuracy of ``cdf`` and ``ppf``: vals = maxwell.ppf([0.001, 0.5, 0.999]) np.allclose([0.001, 0.5, 0.999], maxwell.cdf(vals)) # True # Generate random numbers: r = maxwell.rvs(size=1000) # And compare the histogram: ax.hist(r, density=True, histtype='stepfilled', alpha=0.2) ax.legend(loc='best', frameon=False) plt.show()
initials.writelines ("time_step") initials.write("\n") initials.writelines (str('%.5e'%time_step)) initials.write("\n") initials.writelines ("targetT") initials.write("\n") initials.writelines (str('%.5e'%targetT)) initials.write("\n") initials.close() # setting initial values v = sqrt(K_B*targetT/Mass_Argon) vx_Array = maxwell.rvs(scale = sqrt(K_B*targetT/(3*Mass_Argon)),size = N_Particles ) vy_Array = maxwell.rvs(scale = sqrt(K_B*targetT/(3*Mass_Argon)),size = N_Particles ) vz_Array = maxwell.rvs(scale = sqrt(K_B*targetT/(3*Mass_Argon)),size = N_Particles ) vx_Array = np.asarray(vx_Array) vy_Array = np.asarray(vy_Array) vz_Array = np.asarray(vz_Array) # Calculation of Kinatic energy Vsquared = (vx_Array**2 + vy_Array**2 + vz_Array**2) KE = .5 * Mass_Argon * np.sum(Vsquared) # Calculation of system Temprature sysT = 2*KE/(3*N_Particles*K_B)
def init_particles_in_system(particles_types, particles_densities, particles_mean_number_per_cell, speed_type, speed_param1,\ speed_param2, size, resolution, zone = None, offsets = [0,0], verbose = False, debug = False, *args, **kwargs): list_particles=[] e = 1.6e-19 mean = 0 number_ = 1 for k in range(len(particles_densities)): if(debug): print(particles_types) type_ = particles_types[k] number_ = int(particles_mean_number_per_cell[k]*resolution[0]*resolution[1]) speed_init_type = speed_type[k] # uniform or maxwellian m, M = speed_param1[k], speed_param2[k] if(debug): print('Creating {} particles of type {}.'.format(number_, type_)) print('Speed type init is {} with params {}, {}.'.format(speed_init_type, m, M)) charge = available_particles[type_]['charge'] mass = available_particles[type_]['mass'] effective_diameter = available_particles[type_]['effective diameter'] # parameters of the maxwellian distribution # https://stackoverflow.com/questions/63300833/maxwellian-distribution-in-python-scipy if(speed_init_type == 'gaussian'): sigma = M mu = m elif(speed_init_type == 'maxwellian'): sigma = M mu = m a = sigma * np.sqrt(np.pi/(3.0*np.pi - 8.0)) m_ = 2.0*a*np.sqrt(2.0/np.pi) loc = mu - m_ elif(speed_init_type == 'uniform' or speed_init_type == 'uniform_norm'): # uniform distribution parameters min_speed_uniform_distribution = m max_speed_uniform_distribution = M else : print("/!\\ Unknown speed init type /!\\") return mean = 0 if(debug):print('Number : {}'.format(number_)) for k in range(number_): my_speed = 0 if(speed_init_type=='gaussian'): vx = norm.rvs(mu, sigma) vy = norm.rvs(mu, sigma) vz = norm.rvs(mu, sigma) elif(speed_init_type == 'maxwellian'): norm_speed = float(maxwell.rvs(loc, a)) theta = random()*2*np.pi cTheta = float(np.cos(theta)) sTheta = float(np.sin(theta)) phi = random()*2*np.pi cPhi = float(np.cos(phi)) sPhi = float(np.sin(phi)) vx, vy, vz = norm_speed*sTheta*cPhi, norm_speed*sTheta*sPhi, norm_speed*cTheta elif(speed_init_type=='uniform'): # norm_speed = min_speed_uniform_distribution+random()*\ # (max_speed_uniform_distribution-min_speed_uniform_distribution) # direction of the speed vx = min_speed_uniform_distribution+random()*(max_speed_uniform_distribution-min_speed_uniform_distribution) vy = min_speed_uniform_distribution+random()*(max_speed_uniform_distribution-min_speed_uniform_distribution) vz = min_speed_uniform_distribution+random()*(max_speed_uniform_distribution-min_speed_uniform_distribution) elif(speed_init_type=='uniform_norm'): norm_speed = min_speed_uniform_distribution+random()*\ (max_speed_uniform_distribution-min_speed_uniform_distribution) theta = random()*2*np.pi cTheta = float(np.cos(theta)) sTheta = float(np.sin(theta)) phi = random()*2*np.pi cPhi = float(np.cos(phi)) sPhi = float(np.sin(phi)) vx, vy, vz = norm_speed*sTheta*cPhi, norm_speed*sTheta*sPhi, norm_speed*cTheta # my_speed = MyVector(norm_speed*cTheta,norm_speed*sTheta,0) my_speed = MyVector(vx, vy, vz) x, y = get_correct_initial_positions(zone, offsets, size) list_particles.append(Particule(charge = charge, radius = effective_diameter/2.0, mass = mass, part_type = type_, \ speed=my_speed, \ pos=MyVector(x,y,0), \ verbose = verbose)) mean += my_speed.norm() if(debug): print(my_speed) if(debug): print("Mean speed init : {} m/s".format(round(mean/number_,2))) return np.array(list_particles), mean/number_ # we don't shuffle right now
print 'Usage: python test_maxwell_dist.py <temperature (in Kelvin)> <atom (H or C)> <num of random variables>' sys.exit(0) temperature = float(sys.argv[1]) * kAuPerKelvin atom = sys.argv[2] # 'H' or 'C' n = int(sys.argv[3]) # The number of generated random numbers. if atom == 'H': mass = mass_hydrogen elif atom == 'C': mass = mass_carbon else: assert(False) scale = numpy.sqrt(kBoltzmann * temperature / mass) speeds = [0.0] * n cumulations = [0.0] * n speeds[0] = maxwell.rvs(scale=scale) cumulations[0] = maxwell.cdf(speeds[0], scale=scale) for i in range(1, n): # bernoulli.rvs(p) = 1 in probability p, 0 in probability (1 - p). accelerate = (bernoulli.rvs(cumulations[i - 1]) == 0) if accelerate: speeds[i] = speeds[i - 1] * (1.0 + kDeltaTime * kAccelRatio) else: speeds[i] = max(0.0, speeds[i - 1] * (1.0 - kDeltaTime * kAccelRatio)) # Cumulative probability P(x < speeds[i]) where x is a random variable # from the Maxwell distribution. cumulations[i] = maxwell.cdf(speeds[i], scale=scale) energies = map(lambda s: 0.5 * mass * (s ** 2.0), speeds) print 'speed [a.u.] cumulation energy [a.u.]' for i in range(n): print speeds[i], cumulations[i], energies[i]
os.system("python setup.py build_ext --inplace") from matplotlib import pyplot as plt from monte_carlo import draw_maxwellian from monte_carlo import maxwellianPdf from monte_carlo import maxwellianComparison from scipy.stats import maxwell v_rms = 10.0**5.0 v_max = 10.0**1.0 * v_rms v_min = 10.0**(-1.0) * v_rms N = 10**6 max_dist = draw_maxwellian(v_rms, v_min, v_max, N) max_dist2 = maxwell.rvs(scale=v_rms, size=N) #Create velocity bins N_v = 1000 dv = (v_max - v_min) / N_v v_bins = np.array([v_min + i * dv for i in range(N_v)]) #Number of points in each bin p = np.zeros(N_v, dtype=int) for x in max_dist: i = int(np.floor((x - v_min) / dv)) p[i] += 1 p2 = np.zeros(N_v, dtype=int) for x in max_dist2: i = int(np.floor((x - v_min) / dv))
def BABAB_Ndim(r0, p0, t_max, dt, f, lam, thermal_noise: bool, periodic=None): if periodic is None: periodic = {'PBC': False, 'box_size': 0, 'closed': False} t = np.arange(0, t_max, dt) r = np.zeros([len(t), r0.shape[0], r0.shape[1]]) p = np.zeros([len(t), p0.shape[0], p0.shape[1]]) r[0] = r0 p[0] = p0 r_i = r0 p_i = p0 if thermal_noise: tn = int(1 / dt / 10) else: tn = np.nan for i in tqdm(range(len(t) - 1)): if i % tn == 0: # p_i = np.random.normal(loc=0.0, scale=1.0, size=r0.shape) p_i = maxwell.rvs(loc=0, scale=1.5, size=r0.shape) / np.sqrt(1.5) else: a1 = f(r_i, periodic={ 'PBC': periodic['PBC'], 'box_size': periodic['box_size'] }, closed=periodic['closed']) p_i += a1 * dt * lam r_i += p_i * dt / 2. if periodic['PBC']: r_i[np.where( r_i > periodic['box_size'] / 2.)] -= periodic['box_size'] r_i[np.where( r_i < -periodic['box_size'] / 2.)] += periodic['box_size'] a2 = f(r_i, periodic={ 'PBC': periodic['PBC'], 'box_size': periodic['box_size'] }, closed=periodic['closed']) p_i += a2 * dt * (1 - 2 * lam) r_i += p_i * dt / 2. if periodic['PBC']: r_i[np.where( r_i > periodic['box_size'] / 2.)] -= periodic['box_size'] r_i[np.where( r_i < -periodic['box_size'] / 2.)] += periodic['box_size'] a3 = f(r_i, periodic={ 'PBC': periodic['PBC'], 'box_size': periodic['box_size'] }, closed=periodic['closed']) p_i += a3 * dt * lam r[i + 1] = r_i p[i + 1] = p_i return r, p, t