def main(): """ The main function of the module. It reads input parameters and runs the time-advancing loop. """ # == READ PARAMETERS == parser = argparse.ArgumentParser() parser.add_argument("input", help="Parameter input file") parser.add_argument("-o", "--output", help="Output file", default=None) args = parser.parse_args() ofile = args.output or (splitext(args.input)[0] + '.h5') params = Parameters() params.file_load(args.input) plugins = [import_object(s)(params) for s in params.plugins] # == INIT THE SIMULATION INSTANCE == box = CylBox(0, params.r * co.kilo, params.z0 * co.kilo, params.z1 * co.kilo) dim = CylDimensions(params.r_cells, params.z_cells) z = linspace(params.z0 * co.kilo, params.z1 * co.kilo, dim.nz + 1) sim = CylindricalLangevin(box, dim) # == LOAD FILES == sim.load_ngas(os.path.join(params.input_dir, params.gas_density_file)) sim.load_ne(os.path.join(params.input_dir, params.electron_density_file), cutoff=params.electron_density_cutoff * co.centi**-3) sim.load_ionization(os.path.join(params.input_dir, params.ionization_rate_file)) sim.set_mun(params.mu_N) # == SET BOUNDARY CONDITIONS == flt = ones((2, 2)) if params.lower_boundary != 0: # Set the lower boundary as a perfect conductor: flt[Z_, 0] = False # We also have to set a Neumann bc in hphi for a conductor sim.hphi.neumann_axes.append((Z_, 0, 1)) flt[R, 0] = False sim.add_cpml_boundaries(params.ncpml, filter=flt) # == SET SOURCE == # We set the sources by using a filter in x and y rsource = params.r_source * co.kilo z0source = params.z0_source * co.kilo z1source = params.z1_source * co.kilo r2 = sim.rf**2 source_s = pi * sim.rf[r2 <= rsource**2][-1]**2 source_zflt = logical_and(sim.zf[newaxis, :] <= z1source, sim.zf[newaxis, :] >= z0source) si0, si1 = [nonzero(source_zflt)[1][i] for i in (0, -1)] m = params.tau_f / params.tau_r # == PREPARE H5DF OUTPUT == fp = h5py.File(ofile, 'w') params.h5_dump(fp) sim.save_global(fp) gsteps = fp.create_group('steps') gtrack = fp.create_group('track') # == PREPARE THE MAIN LOOP == sim.set_dt(params.dt) sim.dens_update_lower = params.dens_update_lower * co.kilo insteps = 10 nsave = int(params.output_dt / (insteps * params.dt)) t = 0 for p in plugins: p.initialize(sim) # == THE MAIN LOOP == for i in range(int(params.end_t / (insteps * params.dt))): with ContextTimer("t = %f ms" % (t / co.milli)): for j in range(insteps): sim.update_e() for p in plugins: p.update_e(sim) sim.update_h() sim.j[:, si0:si1 + 1, Z_] = \ (exp(-r2/rsource**2) * peak(sim.th, params.Q / source_s, params.tau_f, m))[:, newaxis] for p in plugins: p.update_h(sim) t += params.dt # Save a coarser grid with higher time resolution if len(params.track_r) > 0 and len(params.track_z) > 0: step = "%.6d" % i g = gtrack.create_group(step) sim.track(g, params.track_r * co.kilo, params.track_z * co.kilo) fp.flush() if 0 == ((i - 1) % nsave): with ContextTimer("Saving step %d" % (i / nsave)): step = "%.4d" % (i / nsave) g = gsteps.create_group(step) sim.save(g) for p in plugins: p.save(sim, g) fp.flush()