Beispiel #1
0
    def _run_solve(self):
        """Function run on every step to perform the required steps to solve
        Poisson's equation."""
        if not mwxrun.initialized:
            return

        # get rho from WarpX
        self.rho_data = mwxrun.get_gathered_rho_grid()[:,:,0]
        # run superLU solver to get phi
        self.solve()
        # write phi to WarpX
        mwxrun.set_phi_grid(self.phi)
Beispiel #2
0
    def get_grid_quantities(self):
        """Function to return ion and electron density at the electron
        positions. Will also return the electron temperature if needed to
        calculate the Coulomb logarithm."""

        self.ion_density_grid = mwxrun.get_gathered_rho_grid(self.field.name)
        if mwxrun.geom_str == 'Z':
            self.ion_density_grid = self.ion_density_grid[:, 0] / self.field.sq
        elif mwxrun.geom_str == 'XZ':
            self.ion_density_grid = self.ion_density_grid[:, :,
                                                          0] / self.field.sq

        if self.log_lambda is None:
            raise NotImplementedError(
                "Calculation of the Coulomb logarithm is not yet supported.")
            # Instantiate a particle processor for the electron species used
            # to get the electron density and temperature on grid if the
            # Coulomb logarithm needs to be calculated. Note that the
            # temperature is given in eV.
            '''
 def _get_rho_ions(self):
     rho_data = mwxrun.get_gathered_rho_grid('he_ions', False)
     if mwxrun.me == 0:
         self.rho_array += (np.mean(rho_data[:, :, 0], axis=0) /
                            constants.q_e / self.DIAG_STEPS)
    def fields_diag(self):
        """Function to process (get, plot and save) field quantities. This
        function is called on every step, but only executes if check_timestep()
        evaluated to True.
        """
        if (self.post_processing
                and (mwxrun.get_it() == mwxrun.simulation.max_steps)):
            self.do_post_processing()

        if not self.check_timestep():
            return

        logger.info("Analyzing fields...")
        self.it = mwxrun.get_it()

        if self.process_phi:
            data = mwxrun.get_gathered_phi_grid(include_ghosts=False)
            self.process_field(data=data,
                               titlestr='Electrostatic potential',
                               plottype='phi',
                               draw_image=True,
                               default_ticks=True,
                               draw_contourlines=False)
            # Optionally generate barrier index plot if requested
            if self.plot and (self.barrier_slices is not None):
                self.plot_barrier_slices(data, self.barrier_slices)
        if self.process_E:
            raise NotImplementedError(
                "E-field processing not yet implemented.")
            self.process_field(data=None,
                               titlestr='Electric field strength',
                               plottype='E',
                               draw_image=True,
                               default_ticks=True,
                               draw_contourlines=False)
        if self.process_rho:
            # assume that rho_fp still holds the net charge density
            data = mwxrun.get_gathered_rho_grid(include_ghosts=False) * 1e-6
            if mwxrun.dim == 1:
                data = data[:, 0]
            elif mwxrun.dim == 2:
                data = data[:, :, 0]

            self.process_field(data=data,
                               titlestr='Net charge density',
                               plottype='rho',
                               draw_image=True,
                               default_ticks=True,
                               draw_contourlines=False)

            # deposit the charge density for each species
            for species in self.species_list:
                data = (mwxrun.get_gathered_rho_grid(species_name=species.name,
                                                     include_ghosts=False) /
                        species.sq * 1e-6)
                if mwxrun.dim == 1:
                    data = data[:, 0]
                elif mwxrun.dim == 2:
                    data = data[:, :, 0]

                self.process_field(data=data,
                                   titlestr=f'{species.name} particle density',
                                   plottype='n',
                                   draw_image=True,
                                   default_ticks=True,
                                   draw_contourlines=False)

        logger.info("Finished analyzing fields")
Beispiel #5
0
def test_two_embedded_cylinders_scraping():
    name = "two_embedded_cylinders_scraping"
    # Include a random run number to allow parallel runs to not collide. Using
    # python randint prevents collisions due to numpy rseed below
    testing_util.initialize_testingdir(name)

    # Initialize each run with consistent, randomly-chosen, rseed. Use a random
    # seed instead for initial dataframe generation.
    # np.random.seed()
    np.random.seed(42147820)

    # Specific numbers match older run for consistency
    D_CA = 0.025  # m
    run = diode_setup.DiodeRun_V1(
        GEOM_STR='XZ',
        #V_ANODE_CATHODE=VOLTAGE,
        D_CA=D_CA,
        NX=64,
        NZ=64,
        DT=1e-10,
        TOTAL_TIMESTEPS=15,
        DIAG_STEPS=15,
        FIELD_DIAG_DATA_LIST=['phi'],
        # FIELD_DIAG_PLOT=True,
        INERT_GAS_TYPE='positron')
    # Only the functions we change from defaults are listed here
    run.setup_run(init_conductors=False,
                  init_scraper=False,
                  init_electrons=True,
                  init_inert_gas=True,
                  init_solver=False,
                  init_injectors=False,
                  init_field_diag=True,
                  init_simcontrol=True,
                  init_simulation=False)

    # Install the embedded boundaries
    cylinder1 = assemblies.InfCylinderY(center_x=-0.25 * D_CA,
                                        center_z=0.5 * D_CA,
                                        radius=0.1 * D_CA,
                                        V=-0.5,
                                        T=300,
                                        WF=4.7,
                                        name="Cylinder1")
    cylinder2 = assemblies.InfCylinderY(center_x=0.25 * D_CA,
                                        center_z=0.5 * D_CA,
                                        radius=0.1 * D_CA,
                                        V=0.2,
                                        T=300,
                                        WF=4.7,
                                        name="Cylinder2")

    # Initialize solver
    run.init_solver()
    run.init_conductors()
    run.electrons.save_particles_at_eb = 1
    run.ions.save_particles_at_eb = 1

    # Inject particles in the simulation
    volemitter = emission.ZSinDistributionVolumeEmitter(
        T=3000,
        zmin=0,
        zmax=run.D_CA,
    )
    emission.PlasmaInjector(
        emitter=volemitter,
        species1=run.electrons,
        species2=run.ions,
        npart=4000,
        plasma_density=1e14,
    )

    # Initialize the simulation
    run.init_simulation()
    run.init_warpx()

    # Run the main WARP loop
    while run.control.check_criteria():
        mwxrun.simulation.step()

    #######################################################################
    # Check flux on each cylinder                                         #
    #######################################################################

    cylinder1.init_scrapedparticles(cylinder1.fields)
    cylinder1.record_scrapedparticles()
    cyl1_scraped = cylinder1.get_scrapedparticles()

    cylinder2.init_scrapedparticles(cylinder2.fields)
    cylinder2.record_scrapedparticles()
    cyl2_scraped = cylinder2.get_scrapedparticles()

    assert np.allclose(cyl1_scraped['n'], np.array([2, 0]))
    assert np.allclose(cyl2_scraped['n'], np.array([1, 2]))

    #######################################################################
    # Check rho results against reference data                            #
    #######################################################################

    rho = mwxrun.get_gathered_rho_grid(include_ghosts=False)[:, :, 0]
    # np.save('two_embedded_cylinders_rho.npy', rho)
    ref_rho = np.load(
        os.path.join(testing_util.test_dir, 'embedded_boundary',
                     'two_embedded_cylinders_rho.npy'))
    assert np.allclose(rho, ref_rho)