def set_timestep(vel): gyperiod = (2*np.pi) / const.gyfreq # Gyroperiod within uniform field (s) ion_ts = const.orbit_res * gyperiod # Timestep to resolve gyromotion vel_ts = const.dx / (2 * np.max(vel[0, :])) # Timestep to satisfy CFL condition: Fastest particle doesn't traverse more than half a cell in one time step DT = min(ion_ts, vel_ts) max_time = const.max_rev * gyperiod # Total runtime in seconds max_inc = int(max_time / DT) + 1 # Total number of time steps if const.part_res == 0: part_save_iter = 1 else: part_save_iter = int(const.part_res*gyperiod / DT) if const.field_res == 0: field_save_iter = 1 else: field_save_iter = int(const.field_res*gyperiod / DT) print('Timestep: %.4fs, %d iterations total' % (DT, max_inc)) if const.adaptive_subcycling == True: k_max = np.pi / const.dx dispfreq = (k_max ** 2) * const.B0 / (const.mu0 * const.ne * const.q) # Dispersion frequency dt_sc = const.freq_res * 1./dispfreq subcycles = int(DT / dt_sc + 1) print('Number of subcycles required: {}'.format(subcycles)) else: subcycles = const.subcycles print('Number of subcycles set at default: {}'.format(subcycles)) if const.save_fields == 1 or const.save_particles == 1: save.store_run_parameters(DT, part_save_iter, field_save_iter) return DT, max_inc, part_save_iter, field_save_iter, subcycles
def set_timestep(vel): gyperiod = (2 * np.pi) / const.gyfreq # Gyroperiod within uniform field (s) k_max = np.pi / const.dx ion_ts = const.orbit_res * gyperiod # Timestep to resolve gyromotion vel_ts = 0.5 * const.dx / np.max( vel[0, :] ) # Timestep to satisfy CFL condition: Fastest particle doesn't traverse more than half a cell in one time step if const.account_for_dispersion == True: dispfreq = (k_max**2) * (const.B0 / (const.mu0 * const.ne) ) # Dispersion frequency disp_ts = const.dispersion_allowance * const.freq_res / dispfreq else: disp_ts = ion_ts DT = min(ion_ts, vel_ts, disp_ts) max_time = const.max_rev * gyperiod # Total runtime in seconds max_inc = int(max_time / DT) + 1 # Total number of time steps if const.part_res == 0: part_save_iter = 1 else: part_save_iter = int(const.part_res * gyperiod / DT) if const.field_res == 0: field_save_iter = 1 else: field_save_iter = int(const.field_res * gyperiod / DT) if const.save_fields == 1 or const.save_particles == 1: save.store_run_parameters(DT, part_save_iter, field_save_iter) return DT, max_inc, part_save_iter, field_save_iter
def set_timestep(vel, Te0): ''' INPUT: vel -- Initial particle velocities OUTPUT: DT -- Maximum allowable timestep (seconds) max_inc -- Number of integer timesteps to get to end time part_save_iter -- Number of timesteps between particle data saves field_save_iter -- Number of timesteps between field data saves Note : Assumes no dispersion effects or electric field acceleration to be initial limiting factor. This may change for inhomogenous loading of particles or initial fields. ''' ion_ts = const.orbit_res / const.gyfreq # Timestep to resolve gyromotion vel_ts = 0.5 * const.dx / np.max( np.abs(vel[0, :]) ) # Timestep to satisfy CFL condition: Fastest particle doesn't traverse more than half a cell in one time step # ============================================================================= # if E[:, 0].max() != 0: # elecfreq = qm_ratios.max()*(np.abs(E[:, 0] / np.abs(vel).max()).max()) # Electron acceleration "frequency" # Eacc_ts = freq_res / elecfreq # else: # Eacc_ts = ion_ts # ============================================================================= gyperiod = 2 * np.pi / const.gyfreq DT = min(ion_ts, vel_ts) max_time = const.max_rev * 2 * np.pi / const.gyfreq_eq # Total runtime in seconds max_inc = int(max_time / DT) + 1 # Total number of time steps if const.part_res == 0: part_save_iter = 1 else: part_save_iter = int(const.part_res * gyperiod / DT) if const.field_res == 0: field_save_iter = 1 else: field_save_iter = int(const.field_res * gyperiod / DT) if const.save_fields == 1 or const.save_particles == 1: save.store_run_parameters(DT, part_save_iter, field_save_iter, Te0) B_damping_array = np.ones(NC + 1, dtype=float) E_damping_array = np.ones(NC, dtype=float) set_damping_array(B_damping_array, E_damping_array, DT) print('Timestep: %.4fs, %d iterations total\n' % (DT, max_inc)) return DT, max_inc, part_save_iter, field_save_iter, B_damping_array, E_damping_array
def set_timestep(vel, Te0): ion_ts = const.orbit_res / const.gyfreq # Timestep to resolve gyromotion vel_ts = 0.5 * const.dx / np.max(np.abs(vel[0, :])) # Timestep to satisfy CFL condition: Fastest particle doesn't traverse more than half a cell in one time step gyperiod = 2 * np.pi / const.gyfreq DT = min(ion_ts, vel_ts) max_time = const.max_rev * 2 * np.pi / const.gyfreq_eq # Total runtime in seconds max_inc = int(max_time / DT) + 1 # Total number of time steps if const.part_res == 0: part_save_iter = 1 else: part_save_iter = int(const.part_res*gyperiod / DT) if const.save_fields == 1 or const.save_particles == 1: save.store_run_parameters(DT, part_save_iter) print('Timestep: %.6fs, %d iterations total\n' % (DT, max_inc)) return DT, max_inc, part_save_iter
def set_timestep(vel): ''' INPUT: vel -- Initial particle velocities OUTPUT: DT -- Maximum allowable timestep (seconds) max_inc -- Number of integer timesteps to get to end time part_save_iter -- Number of timesteps between particle data saves field_save_iter -- Number of timesteps between field data saves Note : Assumes no dispersion effects or electric field acceleration to be initial limiting factor. This may change for inhomogenous loading of particles or initial fields. ''' gyperiod = ( 2 * np.pi ) / const.gyfreq # Gyroperiod within uniform field, initial B0 (s) ion_ts = const.orbit_res * gyperiod # Timestep to resolve gyromotion vel_ts = 0.5 * const.dx / np.max( vel[0, :] ) # Timestep to satisfy CFL condition: Fastest particle doesn't traverse more than half a cell in one time step DT = min(ion_ts, vel_ts) max_time = const.max_rev * gyperiod # Total runtime in seconds max_inc = int(max_time / DT) + 1 # Total number of time steps if const.part_res == 0: part_save_iter = 1 else: part_save_iter = int(const.part_res * gyperiod / DT) if const.field_res == 0: field_save_iter = 1 else: field_save_iter = int(const.field_res * gyperiod / DT) if const.save_fields == 1 or const.save_particles == 1: save.store_run_parameters(DT, part_save_iter, field_save_iter) print('Timestep: %.4fs, %d iterations total\n' % (DT, max_inc)) return DT, max_inc, part_save_iter, field_save_iter
def main(): pos, vel, Ie, W_elec, idx, B, E_int, q_dens, Ji, Ve, Te, DT, max_inc, data_iter = initialize( ) if generate_data == 1: save.store_run_parameters(DT, data_iter) print 'Timestep: %.4fs, %d iterations total' % (DT, max_inc) print 'Initial source term check:' print 'Average cell density: {}cc'.format(q_dens[1:NX + 1].mean()) print 'Average cell current: {}A/m'.format(Ji[1:NX + 1].mean()) xx = 0 ch_flag = 0 real_time = 0. max_inc = 50 data_iter = 25 while xx < max_inc: xx += data_iter # Iterate now before data_iter changed in numerical_loop # If dt has changed, it will still have 'done' this many iterations DT, ch_flag, max_inc, data_iter, real_time = numerical_loop( real_time, pos, vel, Ie, W_elec, idx, B, E_int, q_dens, Ji, Ve, Te, DT, max_inc, data_iter, ch_flag) if ch_flag != 0: print 'Timestep changed by factor of {}. New DT = {}'.format( 2**(ch_flag), DT) if generate_data == 1: if xx % data_iter == 0: save.save_data(real_time, DT, data_iter, xx, pos, vel, Ji, E_int, B, Ve, Te, q_dens) print 'Timestep {} of {} complete'.format(xx, max_inc) return
import fields_1D as fields import sources_1D as sources import save_routines as save from simulation_parameters_1D import generate_data, NX if __name__ == '__main__': start_time = timer() pos, vel, Ie, W_elec, idx = init.initialize_particles() B, E_int = init.initialize_fields() DT, max_inc, data_iter = aux.set_timestep(vel) print 'Timestep: %.4fs, %d iterations total' % (DT, max_inc) if generate_data == 1: save.store_run_parameters(DT, data_iter) q_dens, Ji = sources.collect_moments(vel, Ie, W_elec, idx) E_int, Ve, Te = fields.calculate_E(B, Ji, q_dens) vel = particles.velocity_update(pos, vel, Ie, W_elec, idx, B, E_int, -0.5 * DT) qq = 0 while qq < max_inc: # Check timestep vel, qq, DT, max_inc, data_iter, ch_flag \ = aux.check_timestep(qq, DT, pos, vel, B, E_int, q_dens, Ie, W_elec, max_inc, data_iter, idx) if ch_flag == 1: print 'Timestep halved. Syncing particle velocity with DT = {}'.format(