Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
def report_results(ref_inversion, max_output_fluence, output_photon_counts, output_energy, rel_gain_decrease, inversion_rel_error, rel_errors):
    print output.div_line
    print "results:"
    
    active_medium = create_medium(ref_inversion)
    
    energy_rel_error = model.error.energy_rel_error(active_medium, inversion_rel_error, rel_errors)
    
    pump_energy = params.pump_duration * params.pump_power
    stored_energy = model.energy.energy(params.lasing_wavelen, ref_inversion * active_medium.volume)
    
    input_beam = 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
    
    energy_gain = output_energy / input_energy
    added_energy = output_energy - input_energy
    extraction_eff = added_energy / stored_energy
    total_eff = added_energy / pump_energy
    
    stored_energy_abs_error = inversion_rel_error * stored_energy
    output_energy_abs_error = energy_rel_error * output_energy
    energy_gain_abs_error = energy_rel_error * energy_gain
    
    extraction_eff_abs_error = (added_energy + output_energy_abs_error) / max(stored_energy - stored_energy_abs_error, 0.0) - extraction_eff
    total_eff_abs_error = output_energy_abs_error / pump_energy
    
    max_output_fluence_abs_error = max_output_fluence * energy_rel_error
    
    photon_count_first, photon_count_last = output_photon_counts[0], output_photon_counts[-1]
    photon_count_first_abs_error, photon_count_last_abs_error = photon_count_first * energy_rel_error, photon_count_last * energy_rel_error
    rel_gain_decrease_abs_error = 0.0
    if params.train_pulse_count > 1:
        rel_gain_decrease_abs_error = (photon_count_last + photon_count_last_abs_error) / max(photon_count_first - photon_count_first_abs_error, 0.0) - photon_count_last / photon_count_first
    
    unitconv.print_result("input energy [{}]: {}", ("mJ",), (input_energy,))
    unitconv.print_result("output energy [{}]: {} ~ {}", ("mJ",), (output_energy, output_energy_abs_error))
    unitconv.print_result("energy gain: {} ~ {}", (), (energy_gain, energy_gain_abs_error))
    unitconv.print_result("extraction efficiency [{}]: {} ~ {}", ("%",), (extraction_eff, extraction_eff_abs_error))
    unitconv.print_result("opt.-opt. efficiency [{}]: {} ~ {}", ("%",), (total_eff, total_eff_abs_error))
    unitconv.print_result("max. output fluence [{}]: {} ~ {}", ("J/cm^2",), (max_output_fluence, max_output_fluence_abs_error))
    unitconv.print_result("rel. gain decrease [{}]: {} ~ {}", ("%",), (rel_gain_decrease, rel_gain_decrease_abs_error))
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
 ref_pulse = core.create_pulse(active_medium, input_beam, input_beam.rho_ref, input_beam.phi_ref)
 
 (int_type, amp_type), (_, _, count_z, count_t) = num_types, counts
 
 integrator = model.integrator.DomainIntegrator(int_type)
 
 amp = amp_type(active_medium, count_z)
 amp_3 = model.amplifier.ExactOutputAmplifier(active_medium_3, count_z)
 amp_4 = model.amplifier.ExactOutputAmplifier(active_medium_4, count_z)
 amplify_args = (input_beam.rho_ref, input_beam.phi_ref, ref_pulse, count_t)
 
 print "zero"
 density_out_4, _ = amp_4.amplify(*amplify_args)
 fluence_out_4 = integrator.integrate(amp_4.T, density_out_4) * active_medium_4.light_speed
 fluence_gain_4 = fluence_out_4 / input_beam.ref_fluence
 unitconv.print_result("fluence gain: {}", (), (fluence_gain_4,))
 
 lsl_output_label = "finite"
 if lower_lifetime == 0.0:
     lsl_output_label = "zero"
 elif math.isinf(lower_lifetime):
     lsl_output_label = "infinite"
 print lsl_output_label
 density_out, _ = amp.amplify(*amplify_args)
 fluence_out = integrator.integrate(amp.T, density_out) * active_medium.light_speed
 fluence_gain = fluence_out / input_beam.ref_fluence
 unitconv.print_result("fluence gain: {}", (), (fluence_gain,))
 
 print "infinite"
 density_out_3, _ = amp_3.amplify(*amplify_args)
 fluence_out_3 = integrator.integrate(amp_3.T, density_out_3) * active_medium_3.light_speed