Example #1
0
    def run_sim(self):

        self.sim.step(self.max_steps - self.diag_steps)
        callbacks.installafterstep(self._get_rho_ions)
        self.sim.step(self.diag_steps)

        if self.sim.extension.getMyProc() == 0:
            np.save('avg_ion_density.npy', self.ion_density_array)
Example #2
0
        def __init__(self, total_steps, diag_steps):
            """Diagnostic to record the electron velocity variance at every
            diagnostic step."""
            self.i = 0
            self.results_array = np.zeros((total_steps//diag_steps, 2))

            super(VarianceTracker, self).__init__(diag_steps)

            callbacks.installafterstep(self._record_variance)
    def __init__(self, diag_steps, name=None, species=None,
                 data_list=None, post_processing=False, plot_data_list=None,
                 plot_species=None, **kwargs):

        """Initializes the picmi.ParticleDiagnostic and adds the diagnostic to
        the simulation

        Arguments:
            diag_steps (int): Number of steps between each diagnostic output
            name (str): name of the diag output folder, defaults to
                ``particle_diag``
            species (:class:`mewarpx.mespecies.Species`): species in the
                simulation, if None then uses all particles in the simulation
            data_list (list str): list of attributes to be outputted by the
                diagnostic, default uses ``["position", "momentum", "weighting"]``
            post_process (bool): generate plots for each diagnostic data
                directory produced
            plot_data_list (list str): list of data to be plotted for each
                diagnostic step ("particle_position_x", "particle_position_y",
                "particle_position_z", "particle_momentum_x",
                "particle_momentum_y", "particle_momentum_z")
            plot_species (list str): list of species names to be plotted,
                defaults to all species if not specified. Name variable in
                :class:`mewarpx.mespecies.Species` must be set for each species
                in the simulation

        """
        self.name = name
        self.species = species
        self.data_list = data_list
        self.write_dir = os.path.join(self.DIAG_DIR, self.PARTICLE_DIAG_DIR)

        self.post_processing = post_processing
        self.plot_data_list = plot_data_list
        self.plot_species = plot_species

        if self.name is None:
            self.name = 'particle_diag'
        if self.species is None:
            self.species = mwxrun.simulation.species
        if self.data_list is None:
            self.data_list = ['position', 'momentum', 'weighting']
        if self.plot_species is None:
            self.plot_species = []
            for specimen in self.species:
                self.plot_species.append(specimen.name)

        super(ParticleDiagnostic, self).__init__(
            diag_steps=diag_steps, **kwargs)
        self.add_particle_diag()

        if self.post_processing:
            if self.plot_data_list is None:
                warnings.warn('Warning: post_process is True,'
                              'but plot_data_list is None!')
            else:
                callbacks.installafterstep(self.check_for_end_of_sim)
Example #4
0
    def run_sim(self):

        self.sim.step(self.max_steps - self.diag_steps)

        self.rho_wrapper = fields.RhoFPWrapper(0, False)
        callbacks.installafterstep(self._get_rho_ions)

        self.sim.step(self.diag_steps)

        if self.sim.extension.getMyProc() == 0:
            np.save(f'ion_density_case_{self.n+1}.npy', self.ion_density_array)
    def run_sim(self):

        if self.steps is not None:
            mwxrun.simulation.step(self.steps)
            self.text_diag.print_performance_summary()
        else:
            mwxrun.simulation.step(self.MAX_STEPS - self.DIAG_STEPS)
            callbacks.installafterstep(self._get_rho_ions)
            mwxrun.simulation.step(self.DIAG_STEPS)

            if mwxrun.me == 0:
                np.save('avg_rho_data.npy', self.rho_array)
Example #6
0
    def __init__(self,
                 electron_species,
                 ion_species,
                 log_lambda=None,
                 subcycling_steps=1):
        """
        Arguments:
            electron_species (:class:`mewarpx.mespecies.Species`): Electron
                species that will be scattered off the ion species.
            ion_species (:class:`mewarpx.mespecies.Species`): Ion species from
                which electrons will be scattered.
            log_lambda (float): If specified, a fixed value for the Coulomb
                logarithm. If not specified it will be calculated according to
                the NRL formulary.
            subcycling_steps (int): Number of steps between updating the grid
                quantities. Default 1.
        """
        self.collider = electron_species
        self.field = ion_species

        self.log_lambda = log_lambda
        self.subcycling_steps = subcycling_steps

        self.nu_coef = (
            self.collider.sq**2 * self.field.sq**2 /
            (4.0 * np.pi * constants.epsilon_0**2 * self.collider.sm**2))

        if mwxrun.geom_str not in ['Z', 'XZ']:
            raise NotImplementedError(
                "Currently LangevinElectronIonScattering is only implemented "
                "for Z and XZ geometries.")

        print_str = ("Initialized electron-ion Coulomb scattering for species "
                     f"{self.collider.name} and {self.field.name}.")
        if self.log_lambda is None:
            print_str += 'The Coulomb logarithm will be calculated.'
        else:
            print_str += ('The Coulomb logarithm is fixed at %.2f.' %
                          self.log_lambda)
        logger.info(print_str)

        callbacks.installafterstep(self.run_scattering_method)
Example #7
0
    def __init__(self, diag_steps, preset_string='default',
                 custom_string=None, install=True, **kwargs):
        """Generate and install function to write out step #.

        Arguments:
            diag_steps (int): Number of steps between each output
            simulation (mespecies.Simulation): Main simulation object
            preset_string (str): Defaults to choose between:

              - ``default`` - just the step number and total particle num
              - ``perfdebug`` - like particledebug, plus interval wall time,
                step rate, and particle-step rate
              - ``memdebug`` - print out verbose memory usage information

            custom_string (str): Overrides preset_string if not None. The full
                string to output, with:

              - ``{step}`` formatting symbol for where the step number should
                go
              - ``{wall_time}`` run time of the last diag_steps steps
              - ``{step_rate}`` diag_steps / wall_time
              - ``{particle_step_rate}`` nplive * diag_steps / wall_time
              - ``{nplive}`` for number of live particles (global).
              - ``{npperspecies}`` for number of particles per species
                (global).
              - ``{iproc}`` for the current processor number
              - ``{system_memory}`` for verbose information on system memory
                usage.
              - ``{memory_usage}`` for memory usage of the current process
                only.

            install (bool): If False, don't actually install this into WarpX.
                Use if you want to call manually for debugging.
            kwargs: See :class:`mewarpx.mewarpx.diags_store.diag_base.WarpXDiagnostic`
                for more timing options.
        """
        self.defaults_dict = {
            'default': "Step #{step:6d}; {nplive:8d} particles",
            'perfdebug': ("Step #{step:6d}; {nplive:8d} particles "
                          "{npperspecies} "
                          "{wall_time:6.1f} s wall time; "
                          "{step_rate:4.2f} steps/s; "
                          "{particle_step_rate:4.2f} particle*steps/s in the last {diag_steps} steps; "
                          "{particle_step_rate_total:4.2f} particle*steps/s overall"),
            'memdebug': ("{system_memory}\n"
                         "Proc {iproc} usage:\n{memory_usage}"),
        }
        if custom_string is not None:
            self.diag_string = custom_string
        else:
            if preset_string not in self.defaults_dict:
                logger.warning(("Preset {} not found for set_step_diag, "
                                "using default").format(preset_string))
                preset_string = 'default'
            self.diag_string = self.defaults_dict[preset_string]

        super(TextDiag, self).__init__(diag_steps=diag_steps, **kwargs)

        callbacks.installafterinit(self.init_timers_and_counters)

        if install:
            callbacks.installafterstep(self.text_diag)
Example #8
0
    def __init__(self, diag_steps, runinfo, overwrite=True,
                 history_maxlen=5000, sig_figs=6,
                 printed_qtys=None,
                 check_charge_conservation=True,
                 print_per_diagnostic=True, print_total=False,
                 plot=True, save_csv=False, profile_decorator=None,
                 **kwargs):
        """Generate and install function to write out fluxes.

        Arguments:
            diag_steps (int): Number of steps between each output
            runinfo (:class:`mewarpx.runinfo.RunInfo`): RunInfo object is used
                to get the species, injectors, surfaces, and system area.
            overwrite (bool): If True the dill pickled save file will overwrite
                the previous diagnostic period's saved file.
            history_maxlen (int): Maximum length of full history to keep. If
                this is exceeded, history is resampled to a 2x lower frequency.
                Default 5000.
            sig_figs (int): Number of significant figures in text output.
                Default 6.
            printed_qtys (dict): Override individual values of
                default_printed_qtys; same input format but keys can be omitted
                to use defaults.
            check_charge_conservation (bool): Whether to check if charge is
                conserved in simulation.
            print_per_diagnostic (bool): Whether to print current results for
                the latest diagnostic period.
            print_total (bool): Whether to print total history of fluxes after a
                diagnostic period.
            plot (bool): Whether to save a plot of fluxes after each diagnostic
                period.
            save_csv (bool): Whether to save csv files of scraped / injected
                particles.
            profile_decorator (decorator): A decorator used to profile the
                timeseries update methods and related functions.
            kwargs: See :class:`mewarpx.diags_store.diag_base.WarpXDiagnostic`
                for more timing options.
        """
        # Save input variables
        self.runinfo = runinfo
        self.history_maxlen = history_maxlen
        self.history_dt = mwxrun.get_dt()
        self.check_charge_conservation = check_charge_conservation
        self.print_per_diagnostic = print_per_diagnostic
        self.print_total = print_total
        self.plot = plot

        if save_csv:
            csv_write_dir = os.path.join(self.DIAG_DIR, self.FLUX_DIAG_DIR)
        else:
            csv_write_dir = None

        if profile_decorator is not None:
            self.update_ts_dict = profile_decorator(self.update_ts_dict)
            self.update_fullhist_dict = (
                profile_decorator(self.update_fullhist_dict)
            )
            self.print_fluxes = profile_decorator(self.print_fluxes)
            self.plot_fluxes = profile_decorator(self.plot_fluxes)

        self.injector_dict = runinfo.injector_dict
        self.surface_dict = runinfo.surface_dict

        self.diags_dict = collections.OrderedDict()

        for key, val in self.injector_dict.items():
            self.injector_dict[key] = mwxutil.return_iterable(val)
            self.diags_dict[('inject', key)] = [
                InjectorFluxDiag(diag_steps=diag_steps,
                                 injector=injector,
                                 write_dir=csv_write_dir,
                                 **kwargs)
                for injector in self.injector_dict[key]
            ]

        for key, val in self.surface_dict.items():
            self.surface_dict[key] = mwxutil.return_iterable(val)
            self.diags_dict[('scrape', key)] = [
                SurfaceFluxDiag(diag_steps=diag_steps,
                                surface=surface,
                                write_dir=csv_write_dir,
                                **kwargs)
                for surface in self.surface_dict[key]
            ]

        # Initialize other variables
        self.last_run_step = 0

        super(FluxDiagnostic, self).__init__(
            diag_steps=diag_steps,
            runinfo=runinfo,
            overwrite=overwrite,
            sig_figs=sig_figs,
            printed_qtys=printed_qtys,
            **kwargs
        )

        self.check_scraping()

        # if this run is from a restart, try to load flux data up to the
        # current point
        # mwxrun.restart isn't set until mwxrun.init_run is called, so the
        # lambda function is needed here
        callbacks.installafterinit(
            lambda _=None:
            self._load_checkpoint_flux() if mwxrun.restart else None
        )

        callbacks.installafterstep(self._flux_ana)
Example #9
0
    def __init__(self,
                 diag_steps,
                 process_phi=True,
                 process_E=False,
                 process_rho=True,
                 species_list=None,
                 plot=True,
                 barrier_slices=None,
                 max_dim=16.0,
                 min_dim=0.0,
                 dpi=300,
                 install_field_diagnostic=False,
                 post_processing=False,
                 **kwargs):
        """
        This class handles diagnostics for field quantities (output and
        plotting) typically of interest in Modern Electron simulations.
        Optionally a picmi FieldDiagnostic can also be installed.

        Arguments:
            diag_steps (int): Run the diagnostic with this period.
                Also plot on this period if enabled.
            process_phi (bool): If True, output phi. Default True.
            process_E (bool): If True, output E. Default False.
            process_rho (bool): If True, output rho. Default True.
            species_list (list): Optional list of picmi.Species objects for
                which output density. If not specified all species will be
                tabulated.
            plot (bool): If True, also generate plots. Default True.
            barrier_slices (list): If provided, also plot potential energy
                slices as a function of z for each value of x/r in the list.
                Units are in meters.
            max_dim (float): Maximum figure dimension in inches for field plots.
            min_dim (float): Minimum figure dimension in inches for field plots.
            dpi (int): Resolution to use for saved plots
            install_field_diagnostic (bool): If true, install a picmi
                FieldDiagnostic. All parameters for the diagnostic should be
                passed as keyword arguments.
            post_processing (bool): Whether or not to plot data after simulation
                ends from any yt files generated during the run.
            kwargs: For a list of valid keyword arguments see
                diag_base.WarpXDiagnostic
        """
        self.diag_steps = diag_steps
        self.write_dir = os.path.join(self.DIAG_DIR, self.FIELD_DIAG_DIR)
        # field quantities to process
        self.process_phi = process_phi
        self.process_E = process_E
        self.process_rho = process_rho
        self.species_list = species_list
        if self.species_list is None:
            self.species_list = mwxrun.simulation.species
        self.barrier_slices = barrier_slices

        self.plot = plot
        self.max_dim = max_dim
        self.min_dim = min_dim
        self.dpi = dpi
        self.a_ax = 'z'
        self.o_ax = 'x'

        super(FieldDiagnostic,
              self).__init__(diag_steps, kwargs.pop('diag_step_offset', 0),
                             kwargs.pop('extended_interval_level', None),
                             kwargs.pop('manual_timesteps', None))

        self.install_field_diagnostic = install_field_diagnostic
        self.post_processing = post_processing
        self.kwargs = kwargs

        callbacks.installafterstep(self.fields_diag)

        if self.install_field_diagnostic:
            self.add_field_diag()