Exemple #1
0
    def add_laser(self, laser, injection_method):
        # Call method of parent class
        PICMI_Simulation.add_laser(self, laser, injection_method)

        # Handle injection method
        assert type(injection_method) == PICMI_LaserAntenna
        # Handle laser profile method
        if type(laser) == PICMI_GaussianLaser:
            assert laser.propagation_direction[0] == 0.
            assert laser.propagation_direction[1] == 0.
            assert (laser.zeta is None) or (laser.zeta == 0)
            assert (laser.beta is None) or (laser.beta == 0)
            phi2_chirp = laser.phi2
            if phi2_chirp is None:
                phi2_chirp = 0
            polarization_angle = np.arctan2(laser.polarization_direction[1],
                                            laser.polarization_direction[0])
            laser_profile = GaussianLaser(a0=laser.a0,
                                          waist=laser.waist,
                                          z0=laser.centroid_position[-1],
                                          zf=laser.focal_position[-1],
                                          tau=laser.duration,
                                          theta_pol=polarization_angle,
                                          phi2_chirp=phi2_chirp)
        else:
            raise ValueError('Unknown laser profile: %s' %
                             type(injection_method))

        # Inject the laser
        add_laser_pulse(self.fbpic_sim,
                        laser_profile,
                        method='antenna',
                        z0_antenna=injection_method.position[-1],
                        gamma_boost=self.gamma_boost)
Exemple #2
0
 def add_species(self, species, layout, initialize_self_field=False):
     # Call method of parent class
     PICMI_Simulation.add_species(self, species, layout,
                                  initialize_self_field)
     # Call generic method internally
     self._add_species_generic(species,
                               layout,
                               injection_plane_position=None,
                               injection_plane_normal_vector=None,
                               initialize_self_field=initialize_self_field)
Exemple #3
0
    def add_species(self, species, layout, initialize_self_field=False):
        # Call method of parent class
        PICMI_Simulation.add_species(self, species, layout,
                                     initialize_self_field)

        # Extract list of species
        if type(species) == PICMI_Species:
            species_instances_list = [species]
        elif type(species) == PICMI_MultiSpecies:
            species_instances_list = species.species_instances_list
        else:
            raise ValueError('Unknown type: %s' % type(species))

        # Loop over species and create FBPIC species
        for s in species_instances_list:

            # Get their charge and mass
            if s.particle_type is not None:
                s.charge = particle_charge[s.particle_type]
                s.mass = particle_mass[s.particle_type]
            # If `charge_state` is set, redefine the charge and mass
            if s.charge_state is not None:
                s.charge = s.charge_state * e
                s.mass -= s.charge_state * m_e

            # Add the species to the FBPIC simulation
            fbpic_species = self._create_new_fbpic_species(
                s, layout, initialize_self_field)

            # Register a pointer to the FBPIC species in the PICMI species itself
            # (Useful for particle diagnostics later on)
            s.fbpic_species = fbpic_species

        # Loop over species and handle ionization
        for s in species_instances_list:
            for interaction in s.interactions:
                assert interaction[0] == 'ionization'
                assert interaction[1] == 'ADK'
                picmi_target = interaction[2]
                if not hasattr(picmi_target, 'fbpic_species'):
                    raise RuntimeError(
                        'For ionization with PICMI+FBPIC:\n'
                        'You need to add the target species to the simulation,'
                        ' before the other species.')
                fbpic_target = picmi_target.fbpic_species
                fbpic_source = s.fbpic_species
                fbpic_source.make_ionizable(element=s.particle_type,
                                            level_start=s.charge_state,
                                            target_species=fbpic_target)
Exemple #4
0
    def add_diagnostic(self, diagnostic):
        # Call method of parent class
        PICMI_Simulation.add_diagnostic(self, diagnostic)

        # Handle diagnostic
        if diagnostic.step_min is None:
            iteration_min = 0
        else:
            iteration_min = diagnostic.step_min
        if diagnostic.step_max is None:
            iteration_max = np.inf
        else:
            iteration_max = diagnostic.step_max
        # Register field diagnostic
        if type(diagnostic) == PICMI_FieldDiagnostic:
            if diagnostic.data_list is None:
                data_list = ['rho', 'E', 'B', 'J']
            else:
                data_list = diagnostic.data_list
            diag = FieldDiagnostic(period=diagnostic.period,
                                   fldobject=self.fbpic_sim.fld,
                                   comm=self.fbpic_sim.comm,
                                   fieldtypes=data_list,
                                   write_dir=diagnostic.write_dir,
                                   iteration_min=iteration_min,
                                   iteration_max=iteration_max)
        # Register particle diagnostic
        elif type(diagnostic) == PICMI_ParticleDiagnostic:
            species_dict = {}
            for s in diagnostic.species:
                if s.name is None:
                    raise ValueError('When using a species in a diagnostic, '
                                     'its name must be set.')
                species_dict[s.name] = s.fbpic_species
            if diagnostic.data_list is None:
                data_list = ['position', 'momentum', 'weighting']
            else:
                data_list = diagnostic.data_list
            diag = ParticleDiagnostic(period=diagnostic.period,
                                      species=species_dict,
                                      comm=self.fbpic_sim.comm,
                                      particle_data=data_list,
                                      write_dir=diagnostic.write_dir,
                                      iteration_min=iteration_min,
                                      iteration_max=iteration_max)

        # Add it to the FBPIC simulation
        self.fbpic_sim.diags.append(diag)
Exemple #5
0
    def add_applied_field(self, applied_field):
        # Call method of parent class
        PICMI_Simulation.add_applied_field(self, applied_field)

        if type(applied_field) == PICMI_Mirror:
            assert applied_field.z_front_location is not None
            mirror = Mirror(z_lab=applied_field.z_front_location,
                            n_cells=applied_field.number_of_cells,
                            gamma_boost=self.fbpic_sim.boost.gamma0)
            self.fbpic_sim.mirrors.append(mirror)

        elif type(applied_field) == PICMI_ConstantAppliedField:
            # TODO: Handle bounds
            for field_name in ['Ex', 'Ey', 'Ez', 'Bx', 'By', 'Bz']:
                field_value = getattr(applied_field, field_name)
                if field_value is None:
                    continue

                def field_func(F, x, y, z, t, amplitude, length_scale):
                    return (F + amplitude * field_value)

                # Pass it to FBPIC
                self.fbpic_sim.external_fields.append(
                    ExternalField(field_func, field_name, 1., 0.))

        elif type(applied_field) == PICMI_AnalyticAppliedField:
            # TODO: Handle bounds
            for field_name in ['Ex', 'Ey', 'Ez', 'Bx', 'By', 'Bz']:
                # Extract expression and execute it inside a function definition
                expression = getattr(applied_field, field_name + '_expression')
                if expression is None:
                    continue
                fieldfunc = None
                define_function_code = \
                """def fieldfunc( F, x, y, z, t, amplitude, length_scale ):\n    return( F + amplitude * %s )""" %expression
                # Take into account user-defined variables
                for k in applied_field.user_defined_kw:
                    define_function_code = \
                        "%s = %s\n" %(k,applied_field.user_defined_kw[k]) \
                        + define_function_code
                exec(define_function_code, globals())
                # Pass it to FBPIC
                self.fbpic_sim.external_fields.append(
                    ExternalField(fieldfunc, field_name, 1., 0.))

        else:
            raise ValueError("Unrecognized `applied_field` type.")
Exemple #6
0
    def add_diagnostic(self, diagnostic):
        # Call method of parent class
        PICMI_Simulation.add_diagnostic(self, diagnostic)

        # Handle iteration_min/max in regular diagnostic
        if type(diagnostic) in [
                PICMI_FieldDiagnostic, PICMI_ParticleDiagnostic
        ]:
            if diagnostic.step_min is None:
                iteration_min = 0
            else:
                iteration_min = diagnostic.step_min
            if diagnostic.step_max is None:
                iteration_max = np.inf
            else:
                iteration_max = diagnostic.step_max

        # Register field diagnostic
        if type(diagnostic) in [
                PICMI_FieldDiagnostic, PICMI_LabFrameFieldDiagnostic
        ]:
            if diagnostic.data_list is None:
                data_list = ['rho', 'E', 'B', 'J']
            else:
                data_list = set()  # Use set to avoid redundancy
                for data in diagnostic.data_list:
                    if data in ['Ex', 'Ey', 'Ez', 'E']:
                        data_list.add('E')
                    elif data in ['Bx', 'By', 'Bz', 'B']:
                        data_list.add('B')
                    elif data in ['Jx', 'Jy', 'Jz', 'J']:
                        data_list.add('J')
                    elif data == 'rho':
                        data_list.add('rho')
                data_list = list(data_list)

        if type(diagnostic) == PICMI_FieldDiagnostic:

            diag = FieldDiagnostic(period=diagnostic.period,
                                   fldobject=self.fbpic_sim.fld,
                                   comm=self.fbpic_sim.comm,
                                   fieldtypes=data_list,
                                   write_dir=diagnostic.write_dir,
                                   iteration_min=iteration_min,
                                   iteration_max=iteration_max)

            # Register particle density diagnostic
            rho_density_list = []
            if diagnostic.data_list is not None:
                for data in diagnostic.data_list:
                    if data.startswith('rho_'):
                        # particle density diagnostics, rho_speciesname
                        rho_density_list.append(data)
            if rho_density_list:
                species_dict = {}
                for data in rho_density_list:
                    sname = data[4:]
                    for s in self.species:
                        if s.name == sname:
                            species_dict[s.name] = s.fbpic_species
                pdd_diag = ParticleChargeDensityDiagnostic(
                    period=diagnostic.period,
                    sim=self.fbpic_sim,
                    species=species_dict,
                    write_dir=diagnostic.write_dir,
                    iteration_min=iteration_min,
                    iteration_max=iteration_max)
                self.fbpic_sim.diags.append(pdd_diag)

        elif type(diagnostic) == PICMI_LabFrameFieldDiagnostic:
            diag = BackTransformedFieldDiagnostic(
                zmin_lab=diagnostic.grid.lower_bound[1],
                zmax_lab=diagnostic.grid.upper_bound[1],
                v_lab=c,
                dt_snapshots_lab=diagnostic.dt_snapshots,
                Ntot_snapshots_lab=diagnostic.num_snapshots,
                gamma_boost=self.gamma_boost,
                period=100,
                fldobject=self.fbpic_sim.fld,
                comm=self.fbpic_sim.comm,
                fieldtypes=diagnostic.data_list,
                write_dir=diagnostic.write_dir)
        # Register particle diagnostic
        elif type(diagnostic) in [
                PICMI_ParticleDiagnostic, PICMI_LabFrameParticleDiagnostic
        ]:
            species_dict = {}
            for s in diagnostic.species:
                if s.name is None:
                    raise ValueError('When using a species in a diagnostic, '
                                     'its name must be set.')
                species_dict[s.name] = s.fbpic_species
            if diagnostic.data_list is None:
                data_list = ['position', 'momentum', 'weighting']
            else:
                data_list = diagnostic.data_list
            if type(diagnostic) == PICMI_ParticleDiagnostic:
                diag = ParticleDiagnostic(period=diagnostic.period,
                                          species=species_dict,
                                          comm=self.fbpic_sim.comm,
                                          particle_data=data_list,
                                          write_dir=diagnostic.write_dir,
                                          iteration_min=iteration_min,
                                          iteration_max=iteration_max)
            else:
                diag = BackTransformedParticleDiagnostic(
                    zmin_lab=diagnostic.grid.lower_bound[1],
                    zmax_lab=diagnostic.grid.upper_bound[1],
                    v_lab=c,
                    dt_snapshots_lab=diagnostic.dt_snapshots,
                    Ntot_snapshots_lab=diagnostic.num_snapshots,
                    gamma_boost=self.gamma_boost,
                    period=100,
                    fldobject=self.fbpic_sim.fld,
                    species=species_dict,
                    comm=self.fbpic_sim.comm,
                    particle_data=data_list,
                    write_dir=diagnostic.write_dir)

        # Add it to the FBPIC simulation
        self.fbpic_sim.diags.append(diag)