Example #1
0
    def run(self, simulation):
        """Run tasks for post processing.

        Args:
            simulation (smuthi.simulation.Simulation):  simulation object containing input and solution of the problem
        """
        sys.stdout.write("Post processing ... ")
        sys.stdout.flush()

        particle_list = simulation.particle_list
        layer_system = simulation.layer_system
        initial_field = simulation.initial_field
        for item in self.tasks:
            if item['task'] == 'evaluate far field':
                outputdir = simulation.output_dir + '/far_field'
                if item.get('angle units', 'polar') == 'degree':
                    ang_fac = np.pi / 180
                else:
                    ang_fac = 1

                if type(initial_field).__name__ == 'PlaneWave':
                    self.scattering_cross_section, self.extinction_cross_section = evaluate_cross_section(
                        initial_field=initial_field,
                        particle_list=particle_list,
                        layer_system=layer_system,
                        outputdir=outputdir,
                        show_plots=item.get('show plots', False),
                        save_plots=item.get('save plots', False),
                        save_data=item.get('save data', False),
                        length_unit=simulation.length_unit)
                elif type(initial_field).__name__ == 'GaussianBeam':
                    self.total_far_field, self.initial_far_field, self.scattered_far_field = sf.total_far_field(
                        initial_field=initial_field,
                        particle_list=particle_list,
                        layer_system=layer_system)

                    go.show_far_field(far_field=self.total_far_field,
                                      save_plots=item.get('save plots', False),
                                      show_plots=item.get('show plots', False),
                                      save_data=item.get('save data', False),
                                      tag='total_far_field',
                                      outputdir=outputdir,
                                      flip_downward=True,
                                      split=True)
                    go.show_far_field(far_field=self.initial_far_field,
                                      save_plots=item.get('save plots', False),
                                      show_plots=item.get('show plots', False),
                                      save_data=item.get('save data', False),
                                      tag='initial_far_field',
                                      outputdir=outputdir,
                                      flip_downward=True,
                                      split=True)
                    go.show_far_field(far_field=self.scattered_far_field,
                                      save_plots=item.get('save plots', False),
                                      show_plots=item.get('show plots', False),
                                      save_data=item.get('save data', False),
                                      tag='scattered_far_field',
                                      outputdir=outputdir,
                                      flip_downward=True,
                                      split=True)

                    in_pow = sum(
                        initial_field.initial_intensity(
                            layer_system).integral()).real
                    if self.total_far_field.top() is not None:
                        top_pow = sum(
                            self.total_far_field.top().integral()).real
                    else:
                        top_pow = 0
                    if self.total_far_field.bottom() is not None:
                        bottom_pow = sum(
                            self.total_far_field.bottom().integral()).real
                    else:
                        bottom_pow = 0

                    print()
                    print(
                        '-------------------------------------------------------------------------'
                    )
                    print('Far field:')
                    print(
                        'Initial power:                                         ',
                        in_pow)
                    if initial_field.polar_angle < np.pi / 2:
                        if bottom_pow:
                            print(
                                'Radiation into bottom layer (total reflection):        ',
                                bottom_pow, ' or ',
                                round(bottom_pow / in_pow * 100, 2), '%')
                        if top_pow:
                            print(
                                'Radiation into top layer (total transmission):         ',
                                top_pow, ' or ',
                                round(top_pow / in_pow * 100, 2), '%')
                    else:
                        if bottom_pow:
                            print(
                                'Radiation into bottom layer (total transmission):      ',
                                bottom_pow, ' or ',
                                round(bottom_pow / in_pow * 100, 2), '%')
                        if top_pow:
                            print(
                                'Radiation into top layer (total reflection):           ',
                                top_pow, ' or ',
                                round(top_pow / in_pow * 100, 2), '%')
                    print(
                        'Absorption and incoupling into waveguide modes:        ',
                        in_pow - top_pow - bottom_pow, ' or ',
                        round((in_pow - top_pow - bottom_pow) / in_pow * 100,
                              2), '%')
                    print(
                        '-------------------------------------------------------------------------'
                    )
                elif (type(initial_field).__name__ == 'DipoleSource'
                      or type(initial_field).__name__ == 'DipoleCollection'):
                    self.total_far_field, self.initial_far_field, self.scattered_far_field = sf.total_far_field(
                        initial_field=initial_field,
                        particle_list=particle_list,
                        layer_system=layer_system)

                    go.show_far_field(far_field=self.total_far_field,
                                      save_plots=item.get('save plots', False),
                                      show_plots=item.get('show plots', False),
                                      save_data=item.get('save data', False),
                                      tag='total_far_field',
                                      outputdir=outputdir,
                                      flip_downward=True,
                                      split=True)
                    go.show_far_field(far_field=self.initial_far_field,
                                      save_plots=item.get('save plots', False),
                                      show_plots=item.get('show plots', False),
                                      save_data=item.get('save data', False),
                                      tag='initial_far_field',
                                      outputdir=outputdir,
                                      flip_downward=True,
                                      split=True)
                    go.show_far_field(far_field=self.scattered_far_field,
                                      save_plots=item.get('save plots', False),
                                      show_plots=item.get('show plots', False),
                                      save_data=item.get('save data', False),
                                      tag='scattered_far_field',
                                      outputdir=outputdir,
                                      flip_downward=True,
                                      split=True)

                    if type(initial_field).__name__ == 'DipoleSource':
                        diss_pow = initial_field.dissipated_power(
                            particle_list, layer_system)
                    else:
                        diss_pow = sum(
                            initial_field.dissipated_power(
                                particle_list, layer_system))

                    assert abs(diss_pow.imag / diss_pow) < 1e-8
                    diss_pow = diss_pow.real

                    if self.total_far_field.top() is not None:
                        top_pow = sum(
                            self.total_far_field.top().integral()).real
                    else:
                        top_pow = 0
                    if self.total_far_field.bottom() is not None:
                        bottom_pow = sum(
                            self.total_far_field.bottom().integral()).real
                    else:
                        bottom_pow = 0

                    print()
                    print(
                        '-------------------------------------------------------------------------'
                    )
                    print(
                        'Dissipated power:                                  ',
                        diss_pow)
                    print()
                    print('Far field:')
                    if bottom_pow:
                        print(
                            'Radiation into bottom layer (bottom outcoupling):  ',
                            bottom_pow, ' or ',
                            round(bottom_pow / diss_pow * 100, 2), '%')
                    if top_pow:
                        print(
                            'Radiation into top layer (top outcoupling):        ',
                            top_pow, ' or ', round(top_pow / diss_pow * 100,
                                                   2), '%')
                    print(
                        'Absorption and incoupling into waveguide modes:    ',
                        diss_pow - top_pow - bottom_pow, ' or ',
                        round(
                            (diss_pow - top_pow - bottom_pow) / diss_pow * 100,
                            2), '%')
                    print(
                        '-------------------------------------------------------------------------'
                    )

            elif item['task'] == 'evaluate near field':
                sys.stdout.write("\nEvaluate near fields ... ")
                sys.stdout.flush()

                quantities_to_plot = item['quantities to plot']

                if simulation.output_dir:
                    outputdir = simulation.output_dir + '/near_field'
                else:
                    outputdir = '.'

                go.show_near_field(
                    quantities_to_plot=quantities_to_plot,
                    show_plots=item.get('show plots', False),
                    save_plots=item.get('save plots', False),
                    save_data=item.get('save data', False),
                    save_animations=item.get('save animations', False),
                    outputdir=outputdir,
                    xmin=item.get('xmin', 0),
                    xmax=item.get('xmax', 0),
                    ymin=item.get('ymin', 0),
                    ymax=item.get('ymax', 0),
                    zmin=item.get('zmin', 0),
                    zmax=item.get('zmax', 0),
                    simulation=simulation,
                    max_field=item.get('maximal field strength'),
                    resolution_step=item.get('spatial resolution', 25),
                    max_particle_distance=item.get('maximal particle distance',
                                                   float('inf')),
                    interpolate_step=item.get(
                        'interpolation spatial resolution'))

                sys.stdout.write("done. \n")
                sys.stdout.flush()
dipole = init.DipoleSource(vacuum_wavelength=ld, dipole_moment=D, position=rD)

# run simulation
simulation = simul.Simulation(layer_system=lay_sys,
                              particle_list=part_list,
                              initial_field=dipole)
simulation.run()

power_hom = dipole.dissipated_power_homogeneous_background(
    layer_system=simulation.layer_system)
power = dipole.dissipated_power(particle_list=simulation.particle_list,
                                layer_system=simulation.layer_system)
power2 = dipole.dissipated_power_alternative(
    particle_list=simulation.particle_list,
    layer_system=simulation.layer_system)
ff_tup = sf.total_far_field(simulation.initial_field, simulation.particle_list,
                            simulation.layer_system)


def test_energy_conservation():
    ff_power = sum(ff_tup[0].integral())
    err = abs((power - ff_power) / ff_power)
    print('ff power', ff_power)
    print('diss power', power)
    print('diss power old', power2)
    print('hom power', power_hom)
    print('error', err)
    assert err < 1e-4


def test_power_prototype():
    diss_pow_tspl = 8.5902975e+05
                             azimuthal_angle=beam_azimuthal_angle,
                             polarization=beam_polarization,
                             amplitude=beam_amplitude,
                             reference_point=beam_focal_point,
                             beam_waist=beam_waist,
                             k_parallel_array=beam_neff_array *
                             coord.angular_frequency(vacuum_wavelength))

# initialize simulation object
simulation = simul.Simulation(layer_system=lay_sys,
                              particle_list=particle_list,
                              initial_field=init_fld,
                              log_to_terminal=False)
simulation.run()

ttff, inff, scff = sf.total_far_field(initial_field=simulation.initial_field,
                                      particle_list=simulation.particle_list,
                                      layer_system=simulation.layer_system)


def test_power():
    relerr = abs(
        sum(ttff.integral()) /
        sum(init_fld.initial_intensity(lay_sys).integral()) - 1)
    print(relerr)
    assert relerr < 1e-4


if __name__ == '__main__':
    test_power()