def compute_geom_constraints(dirname, inversion_rdiffs, max_fluences): filename = lambda name: os.path.join(dirname, name) print output.div_line print "computing geometry parameters domain constraints" count_rm = params.ext_opt_geom_resolution[0] count_rb = params.ext_opt_geom_resolution[1] Rm = np.linspace(params.ext_opt_geom_mediumradius[0], params.ext_opt_geom_mediumradius[1], count_rm) Rb = np.linspace(params.ext_opt_geom_beamradius[0], params.ext_opt_geom_beamradius[1], count_rb) inversion_rdiff_max = params.ext_opt_inversion_rdiff_max fluence_max = params.ext_opt_fluence_max contours = [ (max_fluences.T, fluence_max, "damage"), ] contour_comps = [1.0] rm_depop = np.interp(inversion_rdiff_max, inversion_rdiffs[::-1], Rm[::-1]) xvals = [(rm_depop, "depopulation")] xval_comps = [-1.0] if params.graphs: print output.status_writing dirname = os.path.join(dirname, output.opt_geom_rel_path) dirname = output.init_dir(dirname) plot.plot_contour(filename("constraints"), "Geometry Parameters Domain Constraints", (Rm, None, None, output.medium_radius_label), (Rb, None, None, output.beam_radius_label), contours, xvals=xvals) return (contours, xvals, None), (contour_comps, xval_comps, None)
def compute_pump_constraints(dirname, inversion_rdiffs, max_fluences): filename = lambda name: os.path.join(dirname, name) print output.div_line print "computing pumping parameters domain constraints" active_medium = core.create_medium(None) count_tau = params.ext_opt_pump_resolution[0] count_pwr = params.ext_opt_pump_resolution[1] Tau = np.linspace(params.ext_opt_pump_duration[0], params.ext_opt_pump_duration[1], count_tau) Pwr = np.linspace(params.ext_opt_pump_power[0], params.ext_opt_pump_power[1], count_pwr) inversion_rdiff_max = params.ext_opt_inversion_rdiff_max fluence_max = params.ext_opt_fluence_max contours = [ (inversion_rdiffs.T, inversion_rdiff_max, "depopulation"), (max_fluences.T, fluence_max, "damage"), ] contour_comps = [1.0, 1.0] if params.graphs: print output.status_writing dirname = os.path.join(dirname, output.opt_pump_rel_path) graph_types = [ (dirname, Pwr,output. pump_power_label), (os.path.join(dirname, output.alt_plot_rel_path), Pwr * params.pump_efficiency / active_medium.volume, output.eff_power_density_label), ] for dirname, Y, ylabel in graph_types: dirname = output.init_dir(dirname) plot.plot_contour(filename("constraints"), "Pumping Parameters Domain Constraints", (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), contours) return (contours, None, None), (contour_comps, None, None)
def compute_inversion(dirname): print output.div_line print "computing population inversion" active_medium = create_medium(None) pump_system = model.pump.PumpSystem(params.pump_wavelen, params.pump_duration, params.pump_power, params.pump_efficiency) depop_model = create_depop_model(active_medium, params.depop_model_class) inv = params.inverter_class(active_medium, pump_system, depop_model) ref_inversion = inv.invert(params.inversion_rtol, params.inversion_min_count_t) rate_evals = (len(inv.inversion) - 1) * inv.evals_per_step pump_energy = params.pump_duration * params.pump_power stored_energy = model.energy.energy(params.lasing_wavelen, ref_inversion * active_medium.volume) if params.verbose: print "count_t:", len(inv.T) print "depopulation rate evaluation count:", rate_evals if params.inversion_validate: print "validating uniform ASE-induced depopulation rate approximation" ross_num_model = depop_model if isinstance(depop_model, model.depop.RossNumericalASEModel) else model.depop.RossNumericalASEModel(active_medium, params.depop_rate_rtol, params.depop_rate_min_samples) rate_rel_stddev = ross_num_model.rate_rel_stddev(ref_inversion) unitconv.print_result("depopulation rate rel. std. deviation [{}]: {}", ("%",), (rate_rel_stddev,)) if rate_rel_stddev > 10.0e-2: output.warn("uniform ASE-induced depopulation rate approximation is invalid") if isinstance(depop_model, model.depop.NumericalDepopulationModel): print "perturbing population inversion" perturb_depop_model = model.depop.PerturbedDepopulationModel(depop_model) perturb_inv = params.inverter_class(active_medium, pump_system, perturb_depop_model) perturb_ref_inversion = perturb_inv.invert(params.inversion_rtol, params.inversion_min_count_t) rel_error = model.error.perturbed_inversion_rel_error(ref_inversion, perturb_ref_inversion, params.inversion_rtol) else: rel_error = params.inversion_rtol gain_coef = ref_inversion * active_medium.doping_agent.xsection gain = math.exp(gain_coef * active_medium.length) ref_inversion_atol = ref_inversion * rel_error gain_atol = gain * (math.exp(ref_inversion_atol * active_medium.doping_agent.xsection * active_medium.length) - 1.0) stored_energy_atol = stored_energy * rel_error unitconv.print_result("pump energy [{}]: {}", ("mJ",), (pump_energy,)) unitconv.print_result("population inversion [{}]: {} ~ {}", ("cm^-3",), (ref_inversion, ref_inversion_atol)) unitconv.print_result("small signal gain: {} ~ {}", (), (gain, gain_atol)) unitconv.print_result("stored energy [{}]: {} ~ {}", ("mJ",), (stored_energy, stored_energy_atol)) if params.graphs: print output.status_writing dirname = output.init_dir(dirname) output.plot_inversion(dirname, inv) return ref_inversion, rel_error
def compute_inversion_pump_dependence(task_pool, dirname): filename = lambda name: os.path.join(dirname, name) print output.div_line print "computing inversion dependence on pumping parameters" active_medium = core.create_medium(None) count_tau = params.ext_opt_pump_resolution[0] count_pwr = params.ext_opt_pump_resolution[1] Tau = np.linspace(params.ext_opt_pump_duration[0], params.ext_opt_pump_duration[1], count_tau) Pwr = np.linspace(params.ext_opt_pump_power[0], params.ext_opt_pump_power[1], count_pwr) depop_model_class1 = params.depop_model_class depop_model_class2 = params.ext_alt_depop_model depop_model1 = core.create_depop_model(active_medium, params.depop_model_class) depop_model2 = core.create_depop_model(active_medium, params.ext_alt_depop_model) inversions1, inversions2, gains1, gains2, inversion_rdiffs, gain_rdiffs = task_pool.parallel_task(_inversion_pump_dependence_task, (Tau, Pwr), (), (active_medium, (depop_model1, depop_model2))) output.show_status((count_tau, count_pwr), params.extended_status_strides, True) pump_energies = np.prod(np.array(np.meshgrid(Tau, Pwr)), axis=0).T stored_energies1 = model.energy.energy(params.lasing_wavelen, inversions1 * active_medium.volume) stored_energies2 = model.energy.energy(params.lasing_wavelen, inversions2 * active_medium.volume) if params.graphs: print output.status_writing dirname = os.path.join(dirname, output.opt_pump_rel_path) inversion_rdiff_max = params.ext_opt_inversion_rdiff_max zlim = None #(0.0, inversion_rdiff_max) depop_contours = [inversion_rdiff_max] ref_pump_energy = params.pump_duration * params.pump_power ref_pump_contours = [(pump_energies.T, ref_pump_energy, "const. pump energy")] graph_types = [ (dirname, Pwr, output.pump_power_label), (os.path.join(dirname, output.alt_plot_rel_path), Pwr * params.pump_efficiency / active_medium.volume, output.eff_power_density_label), ] for dirname, Y, ylabel in graph_types: dirname = output.init_dir(dirname) plot.plot_color(filename("energy_pump"), "Pump Energy", (Tau, None, None, output. pump_duration_label), (Y, None, None, ylabel), (pump_energies.T, None, output.energy_abs_pump_label), params.out_num_auto_contours) plot.plot_color(filename("inversion"), "Inversion (%s)" % depop_model_class1.descr, (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (inversions1.T, None, output.inversion_abs_label), params.out_num_auto_contours, extra_contours=ref_pump_contours) plot.plot_color(filename("inversion_alt"), "Inversion (%s)" % depop_model_class2.descr, (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (inversions2.T, None, output.inversion_abs_label), params.out_num_auto_contours, extra_contours=ref_pump_contours) plot.plot_color(filename("ss_gain"), "Small Signal Gain (%s)" % depop_model_class1.descr, (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (gains1.T, None, output.gain_label), params.out_num_auto_contours, extra_contours=ref_pump_contours) plot.plot_color(filename("ss_gain_alt"), "Small Signal Gain (%s)" % depop_model_class2.descr, (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (gains2.T, None, output.gain_label), params.out_num_auto_contours, extra_contours=ref_pump_contours) plot.plot_color(filename("energy_stored"), "Stored Energy (%s)" % depop_model_class1.descr, (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (stored_energies1.T, None, output.energy_abs_stored_label), params.out_num_auto_contours, extra_contours=ref_pump_contours) plot.plot_color(filename("energy_stored_alt"), "Stored Energy (%s)" % depop_model_class2.descr, (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (stored_energies2.T, None, output.energy_abs_stored_label), params.out_num_auto_contours, extra_contours=ref_pump_contours) plot.plot_color(filename("inversion_rdiff"), "Inversion Relative Difference", (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (inversion_rdiffs.T, zlim, output.inversion_rdiff_label), params.out_num_auto_contours, depop_contours) plot.plot_color(filename("ss_gain_rdiff"), "Small Signal Gain Relative Difference", (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (gain_rdiffs.T, zlim, output.gain_rdiff_label), params.out_num_auto_contours, depop_contours) return inversions1, inversion_rdiffs
def compute_inversion_geom_dependence(task_pool, dirname): filename = lambda name: os.path.join(dirname, name) print output.div_line print "computing inversion dependence on geometry parameters" pump_system = model.pump.PumpSystem(params.pump_wavelen, params.pump_duration, params.pump_power, params.pump_efficiency) min_medium_radius = params.ext_opt_geom_mediumradius[0] count_rm = params.ext_opt_geom_resolution[0] Rm = np.linspace(min_medium_radius, params.ext_opt_geom_mediumradius[1], count_rm) depop_model_class1 = params.depop_model_class depop_model_class2 = params.ext_alt_depop_model inversions1, inversions2, gains1, gains2, stored_energies1, stored_energies2, inversion_rdiffs, gain_rdiffs = task_pool.parallel_task(_inversion_geom_dependence_task, (Rm,), (), (pump_system, (depop_model_class1, depop_model_class2))) output.show_status((count_rm, None), params.extended_status_strides, True) if params.graphs: print output.status_writing dirname = os.path.join(dirname, output.opt_geom_rel_path) dirname = output.init_dir(dirname) inversion_rdiff_max = params.ext_opt_inversion_rdiff_max pump_energy = params.pump_duration * params.pump_power energy_ylim = (0.0, pump_energy * 1.25) labels = [cls.descr for cls in [depop_model_class1, depop_model_class2]] plot.plot_data(filename("inversion"), "Inversion (%s)" % depop_model_class1.descr, (Rm, None, None, output.medium_radius_label), (inversions1, None, None, output.inversion_abs_label)) plot.plot_data(filename("inversion_alt"), "Inversion (%s)" % depop_model_class2.descr, (Rm, None, None, output.medium_radius_label), (inversions2, None, None, output.inversion_abs_label)) plot.plot_data(filename("inversions"), "Population Inversion", ([Rm]*2, None, None, output.medium_radius_label), ([inversions1, inversions2], None, None, output.inversion_abs_label), legend=labels) plot.plot_data(filename("ss_gain"), "Small Signal Gain (%s)" % depop_model_class1.descr, (Rm, None, None, output.medium_radius_label), (gains1, None, None, output.gain_label)) plot.plot_data(filename("ss_gain_alt"), "Small Signal Gain (%s)" % depop_model_class2.descr, (Rm, None, None, output.medium_radius_label), (gains2, None, None, output.gain_label)) plot.plot_data(filename("ss_gains"), "Small Signal Gain", ([Rm]*2, None, None, output.medium_radius_label), ([gains1, gains2], None, None, output.gain_label), legend=labels) plot.plot_data(filename("energy_stored"), "Stored Energy (%s)" % depop_model_class1.descr, (Rm, None, None, output.medium_radius_label), (stored_energies1, None, energy_ylim, output.energy_abs_stored_label), yvals=[(pump_energy, "pump energy")]) plot.plot_data(filename("energy_stored_alt"), "Stored Energy (%s)" % depop_model_class2.descr, (Rm, None, None, output.medium_radius_label), (stored_energies2, None, energy_ylim, output.energy_abs_stored_label), yvals=[(pump_energy, "pump energy")]) plot.plot_data(filename("energies_stored"), "Stored Energy", ([Rm]*2, None, None, output.medium_radius_label), ([stored_energies1, stored_energies2], None, energy_ylim, output.energy_abs_stored_label), legend=labels, yvals=[(pump_energy, "pump energy")]) plot.plot_data(filename("inversion_rdiff"), "Inversion Relative Difference", (Rm, None, None, output.medium_radius_label), (inversion_rdiffs, None, None, output.inversion_rdiff_label), yvals=[(inversion_rdiff_max, None)]) plot.plot_data(filename("ss_gain_rdiff"), "Small Signal Gain Relative Difference", (Rm, None, None, output.medium_radius_label), (gain_rdiffs, None, None, output.gain_rdiff_label), yvals=[(inversion_rdiff_max, None)]) return inversions1, inversion_rdiffs
def amplify_ref_pulse(dirname, num_types, counts, ref_inversion): print output.div_line print "amplifying ref. pulse" dirname = os.path.join(dirname, output.ref_pulse_rel_path) (int_type, amp_type), (_, _, count_z, count_t) = num_types, counts active_medium = create_medium(ref_inversion) input_beam = create_beam() rho, phi = input_beam.rho_ref, input_beam.phi_ref ref_pulse = create_pulse(active_medium, input_beam, rho, phi) integrator = model.integrator.DomainIntegrator(int_type) amp = amp_type(active_medium, count_z) num_density_out, _ = amp.amplify(rho, phi, ref_pulse, count_t) if active_medium.doping_agent.lower_lifetime in model.amplifier.ExactAmplifier.analytical_lower_lifetimes: exact_amp = model.amplifier.ExactOutputAmplifier(active_medium, count_z) exact_density_out, exact_population_final = exact_amp.amplify(rho, phi, ref_pulse, count_t) else: exact_density_out, exact_population_final = None, None fluence_out = integrator.integrate(amp.T, num_density_out) * active_medium.light_speed fluence_gain = fluence_out / input_beam.ref_fluence unitconv.print_result("fluence gain: {}", (), (fluence_gain,)) if params.graphs: count_z = len(amp.Z) fluences = np.empty(count_z) for l in range(count_z): fluences[l] = integrator.integrate(amp.T, amp.density[l]) * active_medium.light_speed print output.status_writing dirname = output.init_dir(dirname) output.plot_output(dirname, input_beam, ref_pulse, params.pulse_duration, amp, fluences, exact_density_out, exact_population_final)
def amplify_train(dirname, num_types, counts, ref_inversion, quiet=False): if not quiet: print output.div_line if not quiet or params.verbose: print "amplifying pulse train" active_medium = create_medium(ref_inversion) input_beam = create_beam() ref_pulse = create_pulse(active_medium, input_beam, input_beam.rho_ref, input_beam.phi_ref) pulse_train = create_train(ref_pulse) int_type, amp_type = num_types count_rho, count_phi, count_z, count_t = counts integrator = model.integrator.DomainIntegrator(int_type) amp = amp_type(active_medium, count_z) radius = min(active_medium.radius, input_beam.rho_trunc) Rho = np.linspace(0.0, radius, count_rho) Phi = np.linspace(0.0, 2.0*math.pi, count_phi) output_fluence = np.empty((count_rho, count_phi)) max_fluences = np.empty(params.train_pulse_count) output_photon_counts = np.empty(params.train_pulse_count) populations = [[None] * count_phi for _ in range(count_rho)] for m, rho in enumerate(Rho): for n, phi in enumerate(Phi): upper = np.vectorize(active_medium.initial_inversion.inversion)(rho, phi, amp.Z) lower = np.zeros(count_z) populations[m][n] = (upper, lower) norm_beam = params.beam_class(params.beam_radius, 1.0) norm_pulse = create_pulse(active_medium, norm_beam, norm_beam.rho_ref, norm_beam.phi_ref) amp._init_time(norm_pulse, count_t) norm_input_density = np.vectorize(norm_pulse.density)(amp.T) lower_decay = model.amplifier.lower_state_decay(active_medium, pulse_train) pulse_num_stride = params.pulse_num_stride for pnum in range(params.train_pulse_count): if not quiet or params.verbose: output.show_status((pnum, None), (pulse_num_stride, None), False) for m, rho in enumerate(Rho): for n, phi in enumerate(Phi): input_density = norm_input_density * input_beam.fluence(rho, phi) density_out, population_final = amp.amplify(rho, phi, None, None, T=amp.T, initial_population=populations[m][n], input_density=input_density) upper = np.copy(population_final[0]) lower = population_final[1] * lower_decay populations[m][n] = (upper, lower) fluence_out = integrator.integrate(amp.T, density_out) * active_medium.light_speed output_fluence[m, n] = fluence_out if pnum == 0: ref_idx = np.unravel_index(output_fluence.argmax(), output_fluence.shape) ref_output_fluence = np.copy(output_fluence) max_fluences[pnum] = output_fluence[ref_idx] output_photon_counts[pnum] = integrator.integrate_base(active_medium, input_beam, Rho, Phi, output_fluence) del input_density, density_out, population_final, upper, lower del amp, output_fluence, populations, norm_input_density if not quiet or params.verbose: output.show_status((pnum+1, None), (pulse_num_stride, None), True) if not quiet or params.verbose: print "processing results" max_output_fluence = max_fluences[::-1].sum() max_output_fluence = model.energy.energy(params.lasing_wavelen, max_output_fluence) del max_fluences train_output_photon_count = output_photon_counts[::-1].sum() train_output_energy = model.energy.energy(params.lasing_wavelen, train_output_photon_count) rel_gain_decrease = 1.0 - output_photon_counts[-1] / output_photon_counts[0] if not quiet: if params.graphs: print output.status_writing ref_pulse_dir = os.path.join(dirname, output.ref_pulse_rel_path) dirname = output.init_dir(dirname) ref_pulse_dir = output.init_dir(ref_pulse_dir) output.plot_beam(ref_pulse_dir, input_beam, Rho, Phi, ref_output_fluence) output.plot_train(dirname, input_beam, active_medium, output_photon_counts) return max_output_fluence, output_photon_counts, train_output_energy, rel_gain_decrease
def compare_depop_models(dirname): filename = lambda name: os.path.join(dirname, name) if not params.ext_depop_models: return print output.div_line print "comparing depopulation models" active_medium = core.create_medium(None) pump_system = model.pump.PumpSystem(params.pump_wavelen, params.pump_duration, params.pump_power, params.pump_efficiency) data = [] for depop_model_class in params.ext_depop_models: depop_model_label = depop_model_class.descr print depop_model_label depop_model = core.create_depop_model(active_medium, depop_model_class) inv = params.inverter_class(active_medium, pump_system, depop_model) inv.invert(params.inversion_rtol, params.inversion_min_count_t) depop_rate = np.vectorize(depop_model.rate)(inv.inversion) / active_medium.volume data.append((inv.T, inv.inversion, depop_rate, depop_model_class.descr, depop_model_class)) ref_inversion = inv.inversion[-1] unitconv.print_result("population inversion [{}]: {}", ("cm^-3",), (ref_inversion,)) unitconv.print_result("depopulation rate [{}]: {}", ("cm^-3 s^-1",), (depop_rate[-1],)) if params.graphs: print output.status_writing dirname = os.path.join(dirname, output.models_rel_path) dirname = output.init_dir(dirname) data.sort(key = lambda x: x[1][-1], reverse=True) Ts, inversions, depop_rates, labels, depop_model_classes = zip(*data) plot.plot_data(filename("inversions_evo"), "Population Inversion Evolution", (Ts, None, None, output.t_pump_label), (inversions, None, None, output.inversion_abs_label), labels) pump_rate = pump_system.effective_pump_rate / active_medium.volume abs_rate_ylim = None #(0.0, pump_rate * 1.25) non_zero_Ts = [T[1:] for T in Ts] non_zero_inversions = [inversion[1:] for inversion in inversions] non_zero_rates = [depop_rate[1:] for depop_rate in depop_rates] rel_depop_rates = [depop_rate / inversion for depop_rate, inversion in zip(non_zero_rates, non_zero_inversions)] plot.plot_data(filename("depop_rates"), "Depopulation Rate", (inversions, None, None, output.inversion_abs_label), (depop_rates, None, abs_rate_ylim, output.rate_label), labels, yvals=[(pump_rate, "pump rate")]) plot.plot_data(filename("depop_rates_alt"), "Depopulation Rate to Inversion Ratio", (non_zero_inversions, None, None, output.inversion_abs_label), (rel_depop_rates, None, None, output.rate_rel_label), labels) plot.plot_data(filename("depop_rates_evo"), "Depopulation Rate Evolution", (Ts, None, None, output.t_pump_label), (depop_rates, None, abs_rate_ylim, output.rate_label), labels, yvals=[(pump_rate, "pump rate")]) plot.plot_data(filename("depop_rates_alt_evo"), "Depopulation Rate to Inversion Ratio Evolution", (non_zero_Ts, None, None, output.t_pump_label), (rel_depop_rates, None, None, output.rate_rel_label), labels) if params.ext_alt_depop_model not in depop_model_classes: return alt_model_idx = depop_model_classes.index(params.ext_alt_depop_model) alt_T = Ts[alt_model_idx] alt_inversion = inversions[alt_model_idx] altinvs = [] aTs = [] altinv_inversion_rdiffs = [] for cls, T, inversion in zip(depop_model_classes, Ts, inversions): if cls is params.ext_alt_depop_model: continue uT = set(list(T) + list(alt_T)) aT = np.array(sorted(list(uT))) altinv = np.interp(aT, alt_T, alt_inversion)[1:] inv = np.interp(aT, T, inversion)[1:] rdiff = np.fabs(inv - altinv) / np.fmin(inv, altinv) aTs.append(aT[1:]) altinvs.append(altinv) altinv_inversion_rdiffs.append(rdiff) non_alt_labels = [label for i, label in enumerate(labels) if i != alt_model_idx] plot.plot_data(filename("inversions_rdiff_inv"), "Inversion Relative Difference", (altinvs, None, None, output.inversion_abs_label), (altinv_inversion_rdiffs, None, None, output.inversion_rdiff_label), non_alt_labels) plot.plot_data(filename("inversions_rdiff_evo"), "Inversion Relative Difference Evolution", (aTs, None, None, output.t_pump_label), (altinv_inversion_rdiffs, None, None, output.inversion_rdiff_label), non_alt_labels)
def compute_energy_geom_dependence(task_pool, dirname, inversions, constraints, num_types, counts): filename = lambda name: os.path.join(dirname, name) print output.div_line print "computing energy dependence on geometry parameters" min_medium_radius = params.ext_opt_geom_mediumradius[0] min_beam_radius = params.ext_opt_geom_beamradius[0] count_rm = params.ext_opt_geom_resolution[0] count_rb = params.ext_opt_geom_resolution[1] Rm = np.linspace(min_medium_radius, params.ext_opt_geom_mediumradius[1], count_rm) Rb = np.linspace(min_beam_radius, params.ext_opt_geom_beamradius[1], count_rb) inversions = np.meshgrid(inversions, Rb)[0].T stored_energies, input_energies, output_energies, rel_gain_decreases = task_pool.parallel_task(_energy_geom_dependence_task, (Rm, Rb), (inversions,), (num_types, counts)) output.show_status((count_rm, count_rb), params.extended_status_strides, True) pump_energy = params.pump_duration * params.pump_power energy_gains = output_energies / input_energies added_energies = output_energies - input_energies extraction_effs = added_energies / stored_energies total_effs = added_energies / pump_energy limits, comparisons = constraints price = lambda rm, rb: 1.0 / (rm * rb) optimum = optimize_output((Rm, Rb), output_energies, limits, comparisons, price) output_energy_optimum_params = (Rm[optimum[0]], Rb[optimum[1]]) if optimum else (None, None) unitconv.print_result("max. output energy [{}]: {}", ("mJ",), (output_energies[optimum] if optimum else None,)) unitconv.print_result("optimum geometry parameters (medium diameter [{}], beam diameter [{}]): ({}, {})", ("mm", "mm"), output_energy_optimum_params) optimum = optimize_output((Rm, Rb), energy_gains, limits, comparisons, price) energy_gain_optimum_params = (Rm[optimum[0]], Rb[optimum[1]]) if optimum else (None, None) unitconv.print_result("max. energy gain: {}", (), (energy_gains[optimum] if optimum else None,)) unitconv.print_result("optimum geometry parameters (medium diameter [{}], beam diameter [{}]): ({}, {})", ("mm", "mm"), energy_gain_optimum_params) optimum = optimize_output((Rm, Rb), extraction_effs, limits, comparisons, price) extraction_eff_optimum_params = (Rm[optimum[0]], Rb[optimum[1]]) if optimum else (None, None) unitconv.print_result("max. extraction efficiency [{}]: {}", ("%",), (extraction_effs[optimum] if optimum else None,)) unitconv.print_result("optimum geometry parameters (medium diameter [{}], beam diameter [{}]): ({}, {})", ("mm", "mm"), extraction_eff_optimum_params) optimum = optimize_output((Rm, Rb), total_effs, limits, comparisons, price) total_eff_optimum_params = (Rm[optimum[0]], Rb[optimum[1]]) if optimum else (None, None) unitconv.print_result("max. opt.-opt. efficiency [{}]: {}", ("%",), (total_effs[optimum] if optimum else None,)) unitconv.print_result("optimum geometry parameters (medium diameter [{}], beam diameter [{}]): ({}, {})", ("mm", "mm"), total_eff_optimum_params) optimum = optimize_output((Rm, Rb), -rel_gain_decreases, limits, comparisons, price) rel_gain_decrease_optimum_params = (Rm[optimum[0]], Rb[optimum[1]]) if optimum else (None, None) unitconv.print_result("min. rel. gain decrease [{}]: {}", ("%",), (rel_gain_decreases[optimum] if optimum else None,)) unitconv.print_result("optimum geometry parameters (medium diameter [{}], beam diameter [{}]): ({}, {})", ("mm", "mm"), rel_gain_decrease_optimum_params) if params.graphs: print output.status_writing extra_contours, xvals, yvals = limits dirname = os.path.join(dirname, output.opt_geom_rel_path) dirname = output.init_dir(dirname) plot.plot_color(filename("energy_in"), "Input Energy", (Rm, None, None, output.medium_radius_label), (Rb, None, None, output.beam_radius_label), (input_energies.T, None, output.energy_abs_pulse_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals) plot.plot_color(filename("energy_out"), "Output Energy", (Rm, None, None, output.medium_radius_label), (Rb, None, None, output.beam_radius_label), (output_energies.T, None, output.energy_abs_pulse_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals) plot.plot_color(filename("energy_gain"), "Energy Gain", (Rm, None, None, output.medium_radius_label), (Rb, None, None, output.beam_radius_label), (energy_gains.T, None, output.energy_rel_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals) plot.plot_color(filename("efficiency_extr"), "Extraction Efficiency", (Rm, None, None, output.medium_radius_label), (Rb, None, None, output.beam_radius_label), (extraction_effs.T, None, output.extraction_eff_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals) plot.plot_color(filename("efficiency_opt2"), "Optical to Optical Efficiency", (Rm, None, None, output.medium_radius_label), (Rb, None, None, output.beam_radius_label), (total_effs.T, None, output.total_eff_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals) if params.train_pulse_count > 1: plot.plot_color(filename("gain_decrease"), "Gain Decrease", (Rm, None, None, output.medium_radius_label), (Rb, None, None, output.beam_radius_label), (rel_gain_decreases.T, None, output.rel_gain_decrease_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals)
def compute_energy_pump_dependence(task_pool, dirname, inversions, constraints, num_types, counts): filename = lambda name: os.path.join(dirname, name) print output.div_line print "computing energy dependence on pumping parameters" active_medium = core.create_medium(None) input_beam = core.create_beam() input_photon_count = input_beam.fluence_integral(active_medium.radius) input_energy = model.energy.energy(params.lasing_wavelen, input_photon_count) input_energy *= params.train_pulse_count count_tau = params.ext_opt_pump_resolution[0] count_pwr = params.ext_opt_pump_resolution[1] Tau = np.linspace(params.ext_opt_pump_duration[0], params.ext_opt_pump_duration[1], count_tau) Pwr = np.linspace(params.ext_opt_pump_power[0], params.ext_opt_pump_power[1], count_pwr) output_energies, rel_gain_decreases = task_pool.parallel_task(_energy_pump_dependence_task, (Tau, Pwr), (inversions,), (num_types, counts)) output.show_status((count_tau, count_pwr), params.extended_status_strides, True) pump_energies = np.prod(np.array(np.meshgrid(Tau, Pwr)), axis=0).T stored_energies = model.energy.energy(params.lasing_wavelen, inversions * active_medium.volume) energy_gains = output_energies / input_energy added_energies = output_energies - input_energy extraction_effs = added_energies / stored_energies total_effs = added_energies / pump_energies limits, comparisons = constraints price = lambda tau, pwr: tau * pwr unitconv.print_result("input energy [{}]: {}", ("mJ",), (input_energy,)) optimum = optimize_output((Tau, Pwr), output_energies, limits, comparisons, price) output_energy_optimum_params = (Tau[optimum[0]], Pwr[optimum[1]]) if optimum else (None, None) unitconv.print_result("max. output energy [{}]: {}", ("mJ",), (output_energies[optimum] if optimum else None,)) unitconv.print_result("optimum pumping parameters (duration [{}], power [{}]): ({}, {})", ("us", "W"), output_energy_optimum_params) optimum = optimize_output((Tau, Pwr), energy_gains, limits, comparisons, price) energy_gain_optimum_params = (Tau[optimum[0]], Pwr[optimum[1]]) if optimum else (None, None) unitconv.print_result("max. energy gain: {}", (), (energy_gains[optimum] if optimum else None,)) unitconv.print_result("optimum pumping parameters (duration [{}], power [{}]): ({}, {})", ("us", "W"), energy_gain_optimum_params) optimum = optimize_output((Tau, Pwr), extraction_effs, limits, comparisons, price) extraction_eff_optimum_params = (Tau[optimum[0]], Pwr[optimum[1]]) if optimum else (None, None) unitconv.print_result("max. extraction efficiency [{}]: {}", ("%",), (extraction_effs[optimum] if optimum else None,)) unitconv.print_result("optimum pumping parameters (duration [{}], power [{}]): ({}, {})", ("us", "W"), extraction_eff_optimum_params) optimum = optimize_output((Tau, Pwr), total_effs, limits, comparisons, price) total_eff_optimum_params = (Tau[optimum[0]], Pwr[optimum[1]]) if optimum else (None, None) unitconv.print_result("max. opt.-opt. efficiency [{}]: {}", ("%",), (total_effs[optimum] if optimum else None,)) unitconv.print_result("optimum pumping parameters (duration [{}], power [{}]): ({}, {})", ("us", "W"), total_eff_optimum_params) optimum = optimize_output((Tau, Pwr), -rel_gain_decreases, limits, comparisons, price) rel_gain_decrease_optimum_params = (Tau[optimum[0]], Pwr[optimum[1]]) if optimum else (None, None) unitconv.print_result("min. rel. gain decrease [{}]: {}", ("%",), (rel_gain_decreases[optimum] if optimum else None,)) unitconv.print_result("optimum pumping parameters (duration [{}], power [{}]): ({}, {})", ("us", "W"), rel_gain_decrease_optimum_params) if params.graphs: print output.status_writing extra_contours, xvals, yvals = limits dirname = os.path.join(dirname, output.opt_pump_rel_path) graph_types = [ (dirname, Pwr, output.pump_power_label), (os.path.join(dirname, output.alt_plot_rel_path), Pwr * params.pump_efficiency / active_medium.volume, output.eff_power_density_label), ] for dirname, Y, ylabel in graph_types: dirname = output.init_dir(dirname) plot.plot_color(filename("energy_out"), "Output Energy", (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (output_energies.T, None, output.energy_abs_pulse_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals) plot.plot_color(filename("energy_gain"), "Energy Gain", (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (energy_gains.T, None, output.energy_rel_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals) plot.plot_color(filename("efficiency_extr"), "Extraction Efficiency", (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (extraction_effs.T, None, output.extraction_eff_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals) plot.plot_color(filename("efficiency_opt2"), "Optical to Optical Efficiency", (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (total_effs.T, None, output.total_eff_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals) if params.train_pulse_count > 1: plot.plot_color(filename("gain_decrease"), "Gain Decrease", (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (rel_gain_decreases.T, None, output.rel_gain_decrease_label), params.out_num_auto_contours, extra_contours=extra_contours, xvals=xvals, yvals=yvals)
fluences = task_pool.parallel_task(_fluence_pump_dependence_task, (Tau, Pwr), (inversions,), (active_medium, (rho, phi), (int_type, amp_type), (count_z, count_t), ref_pulse, lower_decay)) output.show_status((count_tau, count_pwr), params.extended_status_strides, True) if params.graphs: print output.status_writing dirname = os.path.join(dirname, output.opt_pump_rel_path) fluence_max = params.ext_opt_fluence_max zlim = None #(0.0, fluence_max) contours = [fluence_max] graph_types = [ (dirname, Pwr, output.pump_power_label), (os.path.join(dirname, output.alt_plot_rel_path), Pwr * params.pump_efficiency / active_medium.volume, output.eff_power_density_label), ] for dirname, Y, ylabel in graph_types: dirname = output.init_dir(dirname) plot.plot_color(filename("fluence_out_max"), "Maximum Output Fluence", (Tau, None, None, output.pump_duration_label), (Y, None, None, ylabel), (fluences.T, zlim, output.fluence_abs_label_energy), params.out_num_auto_contours, contours) return fluences def _fluence_geom_dependence_task((i, j), (rm, rb), inversion, (int_type, amp_type), (count_z, count_t)): output.show_status((i, j), params.extended_status_strides, False) orig_geom = _set_geom(rm, rb) try: active_medium = core.create_medium(inversion) input_beam = core.create_beam() rho, phi = input_beam.rho_ref, input_beam.phi_ref ref_pulse = core.create_pulse(active_medium, input_beam, rho, phi) pulse_train = core.create_train(ref_pulse)