diff options
40 files changed, 401 insertions, 188 deletions
diff --git a/Docs/source/building/rzgeometry.rst b/Docs/source/building/rzgeometry.rst index 79bb1edc0..1c4df9ea3 100644 --- a/Docs/source/building/rzgeometry.rst +++ b/Docs/source/building/rzgeometry.rst @@ -8,4 +8,6 @@ To select RZ geometry, set the flag USE_RZ = TRUE when compiling: make -j 4 USE_RZ=TRUE -Note that this sets DIM=2, which is required with USE_RZ=TRUE. The executable produced will have "RZ" as a suffix. +Note that this sets DIM=2, which is required with USE_RZ=TRUE. +The executable produced will have "RZ" as a suffix. Currently +does not work with USE_PSATD. diff --git a/Docs/source/building/spectral.rst b/Docs/source/building/spectral.rst index 50c67d4a9..55a402c87 100644 --- a/Docs/source/building/spectral.rst +++ b/Docs/source/building/spectral.rst @@ -20,3 +20,5 @@ In order to run the code with a spectral solver, you need to: :: make -j 4 USE_PSATD=TRUE + +Note that this is not compatible with USE_RZ yet.
\ No newline at end of file diff --git a/Docs/source/running_cpp/parameters.rst b/Docs/source/running_cpp/parameters.rst index 624aeaf84..076e39ce6 100644 --- a/Docs/source/running_cpp/parameters.rst +++ b/Docs/source/running_cpp/parameters.rst @@ -178,6 +178,11 @@ Particle initialization * ``NRandomPerCell``: injection with a fixed number of randomly-distributed particles per cell. This requires the additional parameter ``<species_name>.num_particles_per_cell``. +* ``<species_name>.do_continuous_injection`` (`0` or `1`) + Whether to inject particles during the simulation, and not only at + initialization. This can be required whith a moving window and/or when + running in a boosted frame. + * ``<species_name>.profile`` (`string`) Density profile for this species. The options are: @@ -432,6 +437,17 @@ Laser initialization Temporal chirp at focus. See definition in Akturk et al., Opt Express, vol 12, no 19 (2014). +* ``<laser_name>.do_continuous_injection`` (`0` or `1`) optional (default `0`). + Whether or not to use continuous injection (`0` or not `0`). + If the antenna starts outside of the simulation domain but enters it + at some point (due to moving window or moving antenna in the boosted + frame), use this so that the laser antenna is injected when it reaches + the box boundary. If running in a boosted frame, this requires the + boost direction, moving window direction and laser propagation direction + to be along `z`. If not running in a boosted frame, this requires the + moving window and laser propagation directions to be the same (`x`, `y` + or `z`) + * ``warpx.num_mirrors`` (`int`) optional (default `0`) Users can input perfect mirror condition inside the simulation domain. The number of mirrors is given by ``warpx.num_mirrors``. The mirrors are diff --git a/Docs/source/visualization/advanced.rst b/Docs/source/visualization/advanced.rst index 9747eec91..157f8a8e0 100644 --- a/Docs/source/visualization/advanced.rst +++ b/Docs/source/visualization/advanced.rst @@ -1,22 +1,22 @@ -Advanced visualization (for developers) -======================================= +Advanced yt visualization, for developers (for plotfiles) +========================================================= This sections contains yt commands for advanced users. The Particle-In-Cell methods uses a -staggered grid (see :doc:`../theory/picsar_theory`), so that the x, y, and z components of the +staggered grid (see :doc:`../theory/picsar_theory`), so that the x, y, and z components of the electric and magnetic fields are all defined at different locations in space. Regular output -(see the :doc:`yt` page, or the notebook at ``WarpX/Tools/Visualization.ipynb`` for an example) -returns cell-centered data for convenience, which involves an additional operation. It is sometimes -useful to access the raw data directly. Furthermore, -the WarpX implementation for mesh refinement contains a number of grids for each level (coarse, -fine and auxilary, see -:doc:`../theory/warpx_theory` for more details), and it is sometimes useful to access each of -them (regular output return the auxiliary grid only). This page provides information to read +(see the :doc:`yt` page, or the notebook at ``WarpX/Tools/Visualization.ipynb`` for an example) +returns cell-centered data for convenience, which involves an additional operation. It is sometimes +useful to access the raw data directly. Furthermore, +the WarpX implementation for mesh refinement contains a number of grids for each level (coarse, +fine and auxilary, see +:doc:`../theory/warpx_theory` for more details), and it is sometimes useful to access each of +them (regular output return the auxiliary grid only). This page provides information to read raw data of all grids. Dump additional data -------------------- -In order to dump additional data in WarpX (mostly for debugging purpose), run the simulation +In order to dump additional data in WarpX (mostly for debugging purpose), run the simulation with parameters :: @@ -27,13 +27,13 @@ with parameters warpx.plot_dive = 1 warpx.plot_rho = 1 -see :doc:`../running_cpp/parameters` for more information on these parameters. +see :doc:`../running_cpp/parameters` for more information on these parameters. Read raw data ------------- -Meta-data -relevant to this topic (number and locations of grids in the simulation) are accessed to +Meta-data +relevant to this topic (number and locations of grids in the simulation) are accessed to with :: @@ -51,13 +51,13 @@ with # List available fields ds.field_list -When ``warpx.plot_raw_fields=1`` and ``warpx.plot_finepatch=1``, here are some useful +When ``warpx.plot_raw_fields=1`` and ``warpx.plot_finepatch=1``, here are some useful commands to access properties of a grid and the Ex field on the fine patch: :: # store grid number 2 into my_grid - my_grid = ds.index.grids[2] + my_grid = ds.index.grids[2] # Get left and right edges of my_grid my_grid.LeftEdge my_grid.RightEdge @@ -71,15 +71,14 @@ Return the ``Ex`` field on the fine patch of grid ``my_grid``: :: my_field = my_grid['raw', 'Ex_fp'].squeeze().v - -For a 2D plotfile, ``my_field`` has shape ``(nx,nz,2)``. The last component stands for the -two values on the edges of each cell for the electric field, due to field staggering. Numpy -function ``squeeze`` removes empty components. While ``yt`` arrays are unit-aware, it is -sometimes useful to extract the data into unitless numpy arrays. This is achieved with ``.v``. -In the case of ``Ex_fp``, the staggering is on direction ``x``, so that -``my_field[:,:-1,1] == my_field[:,1:,0]``. - -All combinations of the fields (``E`` or ``B``), the component (``x``, ``y`` or ``z``) and the -grid (``_fp`` for fine, ``_cp`` for coarse and ``_aux`` for auxiliary) can be accessed in this -way, i.e., ``my_grid['raw', 'Ey_aux']`` or ``my_grid['raw', 'Bz_cp']`` are valid queries. +For a 2D plotfile, ``my_field`` has shape ``(nx,nz,2)``. The last component stands for the +two values on the edges of each cell for the electric field, due to field staggering. Numpy +function ``squeeze`` removes empty components. While ``yt`` arrays are unit-aware, it is +sometimes useful to extract the data into unitless numpy arrays. This is achieved with ``.v``. +In the case of ``Ex_fp``, the staggering is on direction ``x``, so that +``my_field[:,:-1,1] == my_field[:,1:,0]``. + +All combinations of the fields (``E`` or ``B``), the component (``x``, ``y`` or ``z``) and the +grid (``_fp`` for fine, ``_cp`` for coarse and ``_aux`` for auxiliary) can be accessed in this +way, i.e., ``my_grid['raw', 'Ey_aux']`` or ``my_grid['raw', 'Bz_cp']`` are valid queries. diff --git a/Docs/source/visualization/inputs.2d b/Docs/source/visualization/inputs.2d index 83daa2da5..f392ac3c9 100644 --- a/Docs/source/visualization/inputs.2d +++ b/Docs/source/visualization/inputs.2d @@ -45,9 +45,6 @@ interpolation.noz = 3 particles.nspecies = 3
particles.species_names = plasma_e beam driver
particles.use_fdtd_nci_corr = 1
-warpx.do_plasma_injection = 1
-warpx.num_injected_species = 1
-warpx.injected_plasma_species = 0
driver.charge = -q_e
driver.mass = m_e
@@ -82,6 +79,7 @@ plasma_e.momentum_distribution_type = "constant" plasma_e.ux = 0.0
plasma_e.uy = 0.0
plasma_e.uz = 0.0
+plasma_e.do_continuous_injection = 1
beam.charge = -q_e
beam.mass = m_e
diff --git a/Docs/source/visualization/openpmdviewer.rst b/Docs/source/visualization/openpmdviewer.rst new file mode 100644 index 000000000..4d41ba00f --- /dev/null +++ b/Docs/source/visualization/openpmdviewer.rst @@ -0,0 +1,53 @@ +Visualization with openPMD-viewer (for openPMD data) +==================================================== + +openPMD-viewer is an open-source Python package to access openPMD data. + +It allows to: +- Quickly browse through the data, with a GUI-type interface in the Jupyter notebook +- Have access to the data numpy array, for more detailed analysis + +Installation +------------ + +openPMD-viewer can be installed via ``conda`` or ``pip``: + +:: + + conda install -c rlehe openpmd_viewer + +:: + + pip install openPMD-viewer + +Usage +----- + +openPMD-viewer can be used either in simple Python scripts, or in a Jupyter +notebook. In both cases, you can import openPMD-viewer, and load the data +with the following commands: + +:: + + from opmd_viewer import OpenPMDTimeSeries + ts = OpenPMDTimeSeries('./diags/hdf5') + +.. note:: + + If you are using the Jupyter notebook, then you can start a pre-filled + notebook, which already contains the above lines, by typing in a terminal: + + :: + + openPMD_notebook + +When using the Jupyter notebook, you can quickly browse through the data +by using the command: + +:: + + ts.slider() + +You can also access the particle and field data as numpy arrays with the +methods ``ts.get_field`` and ``ts.get_particle``. See the openPMD-viewer +tutorials `here <https://github.com/openPMD/openPMD-viewer/tree/master/tutorials>`_ for more info. diff --git a/Docs/source/visualization/picviewer.rst b/Docs/source/visualization/picviewer.rst index b29faddaa..3b5832238 100644 --- a/Docs/source/visualization/picviewer.rst +++ b/Docs/source/visualization/picviewer.rst @@ -1,5 +1,5 @@ -PyQt-based visualization GUI: PICViewer -========================================= +PyQt-based visualization GUI: PICViewer (for both plotfiles and openPMD) +======================================================================== .. figure:: sample_image.png :alt: picture diff --git a/Docs/source/visualization/visit.rst b/Docs/source/visualization/visit.rst index 50f0be978..153d44734 100644 --- a/Docs/source/visualization/visit.rst +++ b/Docs/source/visualization/visit.rst @@ -1,5 +1,11 @@ -Visualization with Visit -======================== +Visualization with Visit (for plotfiles) +======================================== + +.. note:: + + The openPMD format can also be visualized with Visit, but requires the + installation of a specific plugin: see + `this link <https://github.com/openPMD/openPMD-visit-plugin>`_. WarpX results can also be visualized by VisIt, an open source visualization and analysis software. VisIT can be downloaded and installed from https://wci.llnl.gov/simulation/computer-codes/visit. diff --git a/Docs/source/visualization/visualization.rst b/Docs/source/visualization/visualization.rst index 29c299798..0c9c56837 100644 --- a/Docs/source/visualization/visualization.rst +++ b/Docs/source/visualization/visualization.rst @@ -1,12 +1,33 @@ Visualizing the simulation results ================================== +WarpX can write data either in `plotfile` format (AMReX's native format), or +in `openPMD format <https://www.openpmd.org/>`_ (a common data format for +Particle-In-Cell codes). + +.. note:: + + This is controlled by the parameters ``warpx.dump_plotfiles`` and + ``warpx.dump_openpmd`` in the section :doc:`../running_cpp/parameters`. + +This section describes some of the tools available to visualize the data: + .. toctree:: :maxdepth: 1 yt visit picviewer - sensei - ascent + openpmdviewer advanced + + +In addition, WarpX also has In-Situ Visualization capabilities (i.e. +visualizing the data directly from the simulation, without dumping data +files to disk). + +.. toctree:: + :maxdepth: 1 + + sensei + ascent diff --git a/Docs/source/visualization/yt.rst b/Docs/source/visualization/yt.rst index 9317a3579..d52080458 100644 --- a/Docs/source/visualization/yt.rst +++ b/Docs/source/visualization/yt.rst @@ -1,5 +1,5 @@ -Visualization with yt -===================== +Visualization with yt (for plotfiles) +===================================== `yt <http://yt-project.org/>`__ is a Python package that can help in analyzing and visualizing WarpX data (among other data formats). It is convenient @@ -18,12 +18,12 @@ or with the `Anaconda distribution <https://anaconda.org/>`__ of python (recomme :: - conda install -c atmyers yt + conda install yt Visualizing the data -------------------- -Once data ("plot files") has been created by the simulation, open a Jupyter notebook from +Once data ("plotfiles") has been created by the simulation, open a Jupyter notebook from the terminal: :: @@ -36,7 +36,13 @@ and load the first plot file: :: import yt - ds = yt.load('./plt00000/') + ds = yt.load('./diags/plotfiles/plt00000/') + +The list of field data and particle data stored can be seen with: + +:: + + ds.field_list Field data ~~~~~~~~~~ @@ -50,6 +56,18 @@ For instance, in order to plot the field ``Ex`` in a slice orthogonal to ``y`` ( yt.SlicePlot( ds, 1, 'Ex', origin='native' ) +.. note:: + + `yt.SlicePlot` creates a 2D plot with the same aspect ratio as the physical + size of the simulation box. Sometimes this can lead to very elongated plots + that are difficult to read. You can modify the aspect ratio with the + `aspect` argument ; for instance: + + :: + + yt.SlicePlot( ds, 1, 'Ex', aspect=1./10 ) + + Alternatively, the data can be obtained as a `numpy <http://www.numpy.org/>`__ array. For instance, in order to obtain the field `jz` (on level 0) as a numpy array: diff --git a/Examples/Modules/RigidInjection/inputs b/Examples/Modules/RigidInjection/inputs index b6a62d0bd..d7e3b77e8 100644 --- a/Examples/Modules/RigidInjection/inputs +++ b/Examples/Modules/RigidInjection/inputs @@ -90,8 +90,3 @@ warpx.moving_window_v = 1.0 # in units of the speed of light # Boosted frame warpx.gamma_boost = 1.5 warpx.boost_direction = z - -# Particle Injection -warpx.do_plasma_injection = 0 -warpx.num_injected_species = 0 -warpx.injected_plasma_species = 0 diff --git a/Examples/Modules/boosted_diags/inputs.2d b/Examples/Modules/boosted_diags/inputs.2d index 6315d34cb..33eee5392 100644 --- a/Examples/Modules/boosted_diags/inputs.2d +++ b/Examples/Modules/boosted_diags/inputs.2d @@ -51,11 +51,6 @@ warpx.do_boosted_frame_diagnostic = 1 warpx.num_snapshots_lab = 20; warpx.dt_snapshots_lab = 7.0e-14; -# Particle Injection -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 2 -warpx.injected_plasma_species = 0 1 - # Species particles.nspecies = 2 particles.species_names = electrons ions @@ -72,6 +67,7 @@ electrons.num_particles_per_cell_each_dim = 1 1 2 electrons.profile = constant electrons.density = 1. electrons.momentum_distribution_type = "constant" +electrons.do_continuous_injection = 1 ions.charge = q_e ions.mass = m_p @@ -85,6 +81,7 @@ ions.num_particles_per_cell_each_dim = 1 1 2 ions.profile = constant ions.density = 1. ions.momentum_distribution_type = "constant" +ions.do_continuous_injection = 1 # Laser lasers.nlasers = 1 diff --git a/Examples/Modules/boosted_diags/inputs.3d b/Examples/Modules/boosted_diags/inputs.3d index 6315d34cb..33eee5392 100644 --- a/Examples/Modules/boosted_diags/inputs.3d +++ b/Examples/Modules/boosted_diags/inputs.3d @@ -51,11 +51,6 @@ warpx.do_boosted_frame_diagnostic = 1 warpx.num_snapshots_lab = 20; warpx.dt_snapshots_lab = 7.0e-14; -# Particle Injection -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 2 -warpx.injected_plasma_species = 0 1 - # Species particles.nspecies = 2 particles.species_names = electrons ions @@ -72,6 +67,7 @@ electrons.num_particles_per_cell_each_dim = 1 1 2 electrons.profile = constant electrons.density = 1. electrons.momentum_distribution_type = "constant" +electrons.do_continuous_injection = 1 ions.charge = q_e ions.mass = m_p @@ -85,6 +81,7 @@ ions.num_particles_per_cell_each_dim = 1 1 2 ions.profile = constant ions.density = 1. ions.momentum_distribution_type = "constant" +ions.do_continuous_injection = 1 # Laser lasers.nlasers = 1 diff --git a/Examples/Modules/gaussian_beam/inputs b/Examples/Modules/gaussian_beam/inputs index 23eca9bdc..0cab8d140 100644 --- a/Examples/Modules/gaussian_beam/inputs +++ b/Examples/Modules/gaussian_beam/inputs @@ -102,8 +102,3 @@ warpx.do_pml = 0 warpx.do_moving_window = 0 warpx.moving_window_dir = z warpx.moving_window_v = 1.0 # in units of the speed of light - -# Particle Injection -warpx.do_plasma_injection = 0 -warpx.num_injected_species = 1 -warpx.injected_plasma_species = 1 0 diff --git a/Examples/Physics_applications/laser_acceleration/inputs.2d b/Examples/Physics_applications/laser_acceleration/inputs.2d index 733ea6b86..11ddc6b0b 100644 --- a/Examples/Physics_applications/laser_acceleration/inputs.2d +++ b/Examples/Physics_applications/laser_acceleration/inputs.2d @@ -53,6 +53,7 @@ electrons.zmin = 10.e-6 electrons.profile = constant electrons.density = 2.e23 # number of electrons per m^3 electrons.momentum_distribution_type = "constant" +electrons.do_continuous_injection = 1 beam.charge = -q_e beam.mass = m_e @@ -74,10 +75,6 @@ beam.uz_m = 500. beam.ux_th = 2. beam.uy_th = 2. beam.uz_th = 50. -# Particle Injection -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 1 -warpx.injected_plasma_species = 0 ################################# ############ PLASMA ############# diff --git a/Examples/Physics_applications/laser_acceleration/inputs.2d.boost b/Examples/Physics_applications/laser_acceleration/inputs.2d.boost index 3b452851e..b1fb28126 100644 --- a/Examples/Physics_applications/laser_acceleration/inputs.2d.boost +++ b/Examples/Physics_applications/laser_acceleration/inputs.2d.boost @@ -66,6 +66,7 @@ electrons.profile = "predefined" electrons.predefined_profile_name = "parabolic_channel" # predefined_profile_params = z_start ramp_up plateau ramp_down rc n0 electrons.predefined_profile_params = .5e-3 .5e-3 2.e-3 .5e-3 50.e-6 3.5e24 +electrons.do_continuous_injection = 1 ions.charge = q_e ions.mass = m_p @@ -80,6 +81,7 @@ ions.profile = "predefined" ions.predefined_profile_name = "parabolic_channel" # predefined_profile_params = z_start ramp_up plateau ramp_down rc n0 ions.predefined_profile_params = .5e-3 .5e-3 2.e-3 .5e-3 50.e-6 3.5e24 +ions.do_continuous_injection = 1 beam.charge = -q_e beam.mass = m_e @@ -106,11 +108,6 @@ beam.rigid_advance = true beam.projected = true beam.focused = false -# Particle Injection -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 2 -warpx.injected_plasma_species = 0 1 - ################################# ############# LASER ############# ################################# diff --git a/Examples/Physics_applications/laser_acceleration/inputs.3d b/Examples/Physics_applications/laser_acceleration/inputs.3d index 91837b23c..8e854cbf4 100644 --- a/Examples/Physics_applications/laser_acceleration/inputs.3d +++ b/Examples/Physics_applications/laser_acceleration/inputs.3d @@ -55,11 +55,7 @@ electrons.zmin = 10.e-6 electrons.profile = constant electrons.density = 2.e23 # number of electrons per m^3 electrons.momentum_distribution_type = "constant" - -# Particle Injection -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 1 -warpx.injected_plasma_species = 0 +electrons.do_continuous_injection = 1 ################################# ############ PLASMA ############# diff --git a/Examples/Physics_applications/plasma_acceleration/inputs.2d b/Examples/Physics_applications/plasma_acceleration/inputs.2d index c6115182b..e092cf932 100644 --- a/Examples/Physics_applications/plasma_acceleration/inputs.2d +++ b/Examples/Physics_applications/plasma_acceleration/inputs.2d @@ -40,9 +40,6 @@ interpolation.noz = 3 particles.nspecies = 3 particles.species_names = plasma_e beam driver particles.use_fdtd_nci_corr = 1 -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 1 -warpx.injected_plasma_species = 0 driver.charge = -q_e driver.mass = m_e @@ -77,6 +74,7 @@ plasma_e.momentum_distribution_type = "constant" plasma_e.ux = 0.0 plasma_e.uy = 0.0 plasma_e.uz = 0.0 +plasma_e.do_continuous_injection = 1 beam.charge = -q_e beam.mass = m_e diff --git a/Examples/Physics_applications/plasma_acceleration/inputs.2d.boost b/Examples/Physics_applications/plasma_acceleration/inputs.2d.boost index adeedaba9..59e7c432b 100644 --- a/Examples/Physics_applications/plasma_acceleration/inputs.2d.boost +++ b/Examples/Physics_applications/plasma_acceleration/inputs.2d.boost @@ -54,9 +54,6 @@ particles.nspecies = 4 particles.species_names = driver plasma_e plasma_p beam particles.use_fdtd_nci_corr = 1 particles.rigid_injected_species = driver beam -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 2 -warpx.injected_plasma_species = 1 2 driver.charge = -q_e driver.mass = m_e @@ -95,6 +92,7 @@ plasma_e.momentum_distribution_type = "constant" plasma_e.ux = 0.0 plasma_e.uy = 0.0 plasma_e.uz = 0.0 +plasma_e.do_continuous_injection = 1 plasma_p.charge = q_e plasma_p.mass = m_p @@ -110,6 +108,7 @@ plasma_p.momentum_distribution_type = "constant" plasma_p.ux = 0.0 plasma_p.uy = 0.0 plasma_p.uz = 0.0 +plasma_p.do_continuous_injection = 1 beam.charge = -q_e beam.mass = m_e diff --git a/Examples/Physics_applications/plasma_acceleration/inputs.3d.boost b/Examples/Physics_applications/plasma_acceleration/inputs.3d.boost index 5f1ef1a2e..275cf6335 100644 --- a/Examples/Physics_applications/plasma_acceleration/inputs.3d.boost +++ b/Examples/Physics_applications/plasma_acceleration/inputs.3d.boost @@ -53,9 +53,6 @@ particles.nspecies = 5 particles.species_names = driver plasma_e plasma_p beam driverback particles.use_fdtd_nci_corr = 1 particles.rigid_injected_species = driver beam -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 2 -warpx.injected_plasma_species = 1 2 driver.charge = -q_e driver.mass = 1.e10 @@ -122,6 +119,7 @@ plasma_e.momentum_distribution_type = "constant" plasma_e.ux = 0.0 plasma_e.uy = 0.0 plasma_e.uz = 0.0 +plasma_e.do_continuous_injection = 1 plasma_p.charge = q_e plasma_p.mass = m_p @@ -141,6 +139,7 @@ plasma_p.momentum_distribution_type = "constant" plasma_p.ux = 0.0 plasma_p.uy = 0.0 plasma_p.uz = 0.0 +plasma_p.do_continuous_injection = 1 beam.charge = -q_e beam.mass = m_e diff --git a/Examples/Tests/Larmor/inputs b/Examples/Tests/Larmor/inputs index 265a43383..729d315e9 100644 --- a/Examples/Tests/Larmor/inputs +++ b/Examples/Tests/Larmor/inputs @@ -79,7 +79,4 @@ interpolation.noz = 3 # Moving window warpx.do_moving_window = 0 -# Particle Injection -warpx.do_plasma_injection = 0 - warpx.do_dive_cleaning = 1 diff --git a/Examples/Tests/Larmor/inputs.ml b/Examples/Tests/Larmor/inputs.ml index 9adb655fb..9a0c9eb3d 100644 --- a/Examples/Tests/Larmor/inputs.ml +++ b/Examples/Tests/Larmor/inputs.ml @@ -79,7 +79,4 @@ interpolation.noz = 3 # Moving window warpx.do_moving_window = 0 -# Particle Injection -warpx.do_plasma_injection = 0 - warpx.do_dive_cleaning = 1 diff --git a/Examples/Tests/PML/inputs2d b/Examples/Tests/PML/inputs2d index ff64f68a8..c84cf0555 100644 --- a/Examples/Tests/PML/inputs2d +++ b/Examples/Tests/PML/inputs2d @@ -38,11 +38,6 @@ warpx.do_moving_window = 0 warpx.maxwell_fdtd_solver = yee -# Particle Injection -warpx.do_plasma_injection = 0 -warpx.num_injected_species = 0 -warpx.injected_plasma_species = 0 - # Laser lasers.nlasers = 1 lasers.names = laser1 diff --git a/Examples/Tests/laser_on_fine/inputs b/Examples/Tests/laser_on_fine/inputs index a9bf8bf8c..8fc8876cb 100644 --- a/Examples/Tests/laser_on_fine/inputs +++ b/Examples/Tests/laser_on_fine/inputs @@ -57,11 +57,6 @@ warpx.do_moving_window = 0 warpx.moving_window_dir = z warpx.moving_window_v = 1.0 # in units of the speed of light -# Particle Injection -warpx.do_plasma_injection = 0 -warpx.num_injected_species = 1 -warpx.injected_plasma_species = 0 - # Laser lasers.nlasers = 1 lasers.names = laser1 diff --git a/Examples/Tests/laser_on_fine/inputs.2d b/Examples/Tests/laser_on_fine/inputs.2d index 34f174cf9..c4af2df56 100644 --- a/Examples/Tests/laser_on_fine/inputs.2d +++ b/Examples/Tests/laser_on_fine/inputs.2d @@ -57,11 +57,6 @@ warpx.do_moving_window = 0 warpx.moving_window_dir = z warpx.moving_window_v = 1.0 # in units of the speed of light -# Particle Injection -warpx.do_plasma_injection = 0 -warpx.num_injected_species = 1 -warpx.injected_plasma_species = 0 - # Laser lasers.nlasers = 1 lasers.names = laser1 diff --git a/Examples/Tests/self_force_test/inputs b/Examples/Tests/self_force_test/inputs index 9da7d5675..1e55c1174 100644 --- a/Examples/Tests/self_force_test/inputs +++ b/Examples/Tests/self_force_test/inputs @@ -69,6 +69,3 @@ interpolation.noz = 1 # Moving window warpx.do_moving_window = 0 - -# Particle Injection -warpx.do_plasma_injection = 0 diff --git a/Examples/Tests/subcycling/inputs.2d b/Examples/Tests/subcycling/inputs.2d index f1e2951c9..9790ee973 100644 --- a/Examples/Tests/subcycling/inputs.2d +++ b/Examples/Tests/subcycling/inputs.2d @@ -125,7 +125,7 @@ plasma_e.momentum_distribution_type = "constant" plasma_e.ux = 0.0 plasma_e.uy = 0.0 plasma_e.uz = 0.0 - +plasma_e.do_continuous_injection = 1 plasma_p.charge = q_e plasma_p.mass = m_p @@ -142,13 +142,9 @@ plasma_p.momentum_distribution_type = "constant" plasma_p.ux = 0.0 plasma_p.uy = 0.0 plasma_p.uz = 0.0 +plasma_p.do_continuous_injection = 1 # Moving window warpx.do_moving_window = 1 warpx.moving_window_dir = z warpx.moving_window_v = 1. # in units of the speed of light - -# Particle Injection -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 2 -warpx.injected_plasma_species = 2 3 diff --git a/Python/pywarpx/picmi.py b/Python/pywarpx/picmi.py index a5d9fba87..a439205a7 100644 --- a/Python/pywarpx/picmi.py +++ b/Python/pywarpx/picmi.py @@ -113,6 +113,9 @@ class GaussianBunchDistribution(picmistandard.PICMI_GaussianBunchDistribution): species.uy = self.centroid_velocity[1] species.uz = self.centroid_velocity[2] + if self.fill_in: + species.do_continuous_injection = 1 + class UniformDistribution(picmistandard.PICMI_UniformDistribution): def initialize_inputs(self, species_number, layout, species): @@ -153,14 +156,6 @@ class UniformDistribution(picmistandard.PICMI_UniformDistribution): species.uy = self.directed_velocity[1] species.uz = self.directed_velocity[2] - if self.fill_in: - pywarpx.warpx.do_plasma_injection = 1 - if not hasattr(pywarpx.warpx, 'injected_plasma_species'): - pywarpx.warpx.injected_plasma_species = [] - - pywarpx.warpx.injected_plasma_species.append(species_number) - pywarpx.warpx.num_injected_species = len(pywarpx.warpx.injected_plasma_species) - class AnalyticDistribution(picmistandard.PICMI_AnalyticDistribution): def initialize_inputs(self, species_number, layout, species): @@ -205,12 +200,7 @@ class AnalyticDistribution(picmistandard.PICMI_AnalyticDistribution): species.uz = self.directed_velocity[2] if self.fill_in: - pywarpx.warpx.do_plasma_injection = 1 - if not hasattr(pywarpx.warpx, 'injected_plasma_species'): - pywarpx.warpx.injected_plasma_species = [] - - pywarpx.warpx.injected_plasma_species.append(species_number) - pywarpx.warpx.num_injected_species = len(pywarpx.warpx.injected_plasma_species) + species.do_continuous_injection = 1 class ParticleListDistribution(picmistandard.PICMI_ParticleListDistribution): diff --git a/Source/Laser/LaserParticleContainer.H b/Source/Laser/LaserParticleContainer.H index 5dd94d0c7..516e368ab 100644 --- a/Source/Laser/LaserParticleContainer.H +++ b/Source/Laser/LaserParticleContainer.H @@ -84,11 +84,19 @@ private: std::string field_function; // laser particle domain - amrex::RealBox prob_domain; - + amrex::RealBox laser_injection_box; + // Theoretical position of the antenna. Used if do_continuous_injection=1. + // Track the position of the antenna until it enters the simulation domain. + amrex::Vector<amrex::Real> updated_position; + void ComputeSpacing (int lev, amrex::Real& Sx, amrex::Real& Sy) const; void ComputeWeightMobility (amrex::Real Sx, amrex::Real Sy); void InitData (int lev); + // Inject the laser antenna during the simulation, if it started + // outside of the simulation domain and enters it. + void ContinuousInjection(const amrex::RealBox& injection_box) override; + // Update position of the antenna + void UpdateContinuousInjectionPosition(amrex::Real dt) override; }; #endif diff --git a/Source/Laser/LaserParticleContainer.cpp b/Source/Laser/LaserParticleContainer.cpp index 2b56c3cfd..8a2590e5e 100644 --- a/Source/Laser/LaserParticleContainer.cpp +++ b/Source/Laser/LaserParticleContainer.cpp @@ -49,6 +49,7 @@ LaserParticleContainer::LaserParticleContainer (AmrCore* amr_core, int ispecies, pp.query("pusher_algo", pusher_algo); pp.get("wavelength", wavelength); pp.get("e_max", e_max); + pp.query("do_continuous_injection", do_continuous_injection); if ( profile == laser_t::Gaussian ) { // Parse the properties of the Gaussian profile @@ -148,16 +149,94 @@ LaserParticleContainer::LaserParticleContainer (AmrCore* amr_core, int ispecies, u_Y = {0., 1., 0.}; #endif - prob_domain = Geometry::ProbDomain(); + laser_injection_box= Geometry::ProbDomain(); { Vector<Real> lo, hi; if (pp.queryarr("prob_lo", lo)) { - prob_domain.setLo(lo); + laser_injection_box.setLo(lo); } if (pp.queryarr("prob_hi", hi)) { - prob_domain.setHi(hi); + laser_injection_box.setHi(hi); } } + + if (do_continuous_injection){ + // If laser antenna initially outside of the box, store its theoretical + // position in z_antenna_th + updated_position = position; + + // Sanity checks + int dir = WarpX::moving_window_dir; + std::vector<Real> windir(3, 0.0); +#if (AMREX_SPACEDIM==2) + windir[2*dir] = 1.0; +#else + windir[dir] = 1.0; +#endif + AMREX_ALWAYS_ASSERT_WITH_MESSAGE( + (nvec[0]-windir[0]) + (nvec[1]-windir[1]) + (nvec[2]-windir[2]) + < 1.e-12, "do_continous_injection for laser particle only works" + + " if moving window direction and laser propagation direction are the same"); + if ( WarpX::gamma_boost>1 ){ + AMREX_ALWAYS_ASSERT_WITH_MESSAGE( + (WarpX::boost_direction[0]-0)*(WarpX::boost_direction[0]-0) + + (WarpX::boost_direction[1]-0)*(WarpX::boost_direction[1]-0) + + (WarpX::boost_direction[2]-1)*(WarpX::boost_direction[2]-1) < 1.e-12, + "do_continous_injection for laser particle only works if " + + "warpx.boost_direction = z. TODO: all directions."); + } + } +} + +/* \brief Check if laser particles enter the box, and inject if necessary. + * \param injection_box: a RealBox where particles should be injected. + */ +void +LaserParticleContainer::ContinuousInjection (const RealBox& injection_box) +{ + // Input parameter injection_box contains small box where injection + // should occur. + // So far, LaserParticleContainer::laser_injection_box contains the + // outdated full problem domain at t=0. + + // Convert updated_position to Real* to use RealBox::contains(). +#if (AMREX_SPACEDIM == 3) + const Real* p_pos = updated_position.dataPtr(); +#else + const Real p_pos[2] = {updated_position[0], updated_position[2]}; +#endif + if ( injection_box.contains(p_pos) ){ + // Update laser_injection_box with current value + laser_injection_box = injection_box; + // Inject laser particles. LaserParticleContainer::InitData + // is called only once, when the antenna enters the simulation + // domain. + InitData(); + } +} + +/* \brief update position of the antenna if running in boosted frame. + * \param dt time step (level 0). + * The up-to-date antenna position is stored in updated_position. + */ +void +LaserParticleContainer::UpdateContinuousInjectionPosition(Real dt) +{ + int dir = WarpX::moving_window_dir; + if (do_continuous_injection and (WarpX::gamma_boost > 1)){ + // In boosted-frame simulations, the antenna has moved since the last + // call to this function, and injection position needs to be updated +#if ( AMREX_SPACEDIM == 3 ) + updated_position[dir] -= WarpX::beta_boost * + WarpX::boost_direction[dir] * PhysConst::c * dt; +#elif ( AMREX_SPACEDIM == 2 ) + // In 2D, dir=0 corresponds to x and dir=1 corresponds to z + // This needs to be converted in order to index `boost_direction` + // which has 3 components, for both 2D and 3D simulations. + updated_position[2*dir] -= WarpX::beta_boost * + WarpX::boost_direction[2*dir] * PhysConst::c * dt; +#endif + } } void @@ -175,6 +254,13 @@ LaserParticleContainer::InitData (int lev) ComputeSpacing(lev, S_X, S_Y); ComputeWeightMobility(S_X, S_Y); + // LaserParticleContainer::position contains the initial position of the + // laser antenna. In the boosted frame, the antenna is moving. + // Update its position with updated_position. + if (do_continuous_injection){ + position = updated_position; + } + auto Transform = [&](int i, int j) -> Vector<Real>{ #if (AMREX_SPACEDIM == 3) return { position[0] + (S_X*(i+0.5))*u_X[0] + (S_Y*(j+0.5))*u_Y[0], @@ -210,8 +296,8 @@ LaserParticleContainer::InitData (int lev) plane_hi[1] = std::max(plane_hi[1], j); }; - const Real* prob_lo = prob_domain.lo(); - const Real* prob_hi = prob_domain.hi(); + const Real* prob_lo = laser_injection_box.lo(); + const Real* prob_hi = laser_injection_box.hi(); #if (AMREX_SPACEDIM == 3) compute_min_max(prob_lo[0], prob_lo[1], prob_lo[2]); compute_min_max(prob_hi[0], prob_lo[1], prob_lo[2]); @@ -272,7 +358,7 @@ LaserParticleContainer::InitData (int lev) #else const Real x[2] = {pos[0], pos[2]}; #endif - if (prob_domain.contains(x)) + if (laser_injection_box.contains(x)) { for (int k = 0; k<2; ++k) { particle_x.push_back(pos[0]); diff --git a/Source/Particles/MultiParticleContainer.H b/Source/Particles/MultiParticleContainer.H index f3fd522a9..0c5e49c04 100644 --- a/Source/Particles/MultiParticleContainer.H +++ b/Source/Particles/MultiParticleContainer.H @@ -169,7 +169,15 @@ public: const amrex::Real z_old, const amrex::Real z_new, const amrex::Real t_boost, const amrex::Real t_lab, const amrex::Real dt, amrex::Vector<WarpXParticleContainer::DiagnosticParticleData>& parts) const; - + + // Inject particles during the simulation (for particles entering the + // simulation domain after some iterations, due to flowing plasma and/or + // moving window). + void ContinuousInjection(const amrex::RealBox& injection_box) const; + // Update injection position for continuously-injected species. + void UpdateContinuousInjectionPosition(amrex::Real dt) const; + int doContinuousInjection() const; + // // Parameters for the Cherenkov corrector in the FDTD solver. // Both stencils are calculated ar runtime. diff --git a/Source/Particles/MultiParticleContainer.cpp b/Source/Particles/MultiParticleContainer.cpp index a4df1f83a..440906348 100644 --- a/Source/Particles/MultiParticleContainer.cpp +++ b/Source/Particles/MultiParticleContainer.cpp @@ -414,3 +414,48 @@ MultiParticleContainer } } } + +/* \brief Continuous injection for particles initially outside of the domain. + * \param injection_box: Domain where new particles should be injected. + * Loop over all WarpXParticleContainer in MultiParticleContainer and + * calls virtual function ContinuousInjection. + */ +void +MultiParticleContainer::ContinuousInjection(const RealBox& injection_box) const +{ + for (int i=0; i<nspecies+nlasers; i++){ + auto& pc = allcontainers[i]; + if (pc->do_continuous_injection){ + pc->ContinuousInjection(injection_box); + } + } +} + +/* \brief Update position of continuous injection parameters. + * \param dt: simulation time step (level 0) + * All classes inherited from WarpXParticleContainer do not have + * a position to update (PhysicalParticleContainer does not do anything). + */ +void +MultiParticleContainer::UpdateContinuousInjectionPosition(Real dt) const +{ + for (int i=0; i<nspecies+nlasers; i++){ + auto& pc = allcontainers[i]; + if (pc->do_continuous_injection){ + pc->UpdateContinuousInjectionPosition(dt); + } + } +} + +int +MultiParticleContainer::doContinuousInjection() const +{ + int warpx_do_continuous_injection = 0; + for (int i=0; i<nspecies+nlasers; i++){ + auto& pc = allcontainers[i]; + if (pc->do_continuous_injection){ + warpx_do_continuous_injection = 1; + } + } + return warpx_do_continuous_injection; +} diff --git a/Source/Particles/PhysicalParticleContainer.H b/Source/Particles/PhysicalParticleContainer.H index 362683879..4f365768b 100644 --- a/Source/Particles/PhysicalParticleContainer.H +++ b/Source/Particles/PhysicalParticleContainer.H @@ -101,8 +101,6 @@ public: const amrex::Real t_lab, const amrex::Real dt, DiagnosticParticles& diagnostic_particles) final; - bool injected = false; - protected: std::string species_name; @@ -122,6 +120,9 @@ protected: int GetRefineFac(const amrex::Real x, const amrex::Real y, const amrex::Real z); std::unique_ptr<amrex::IArrayBox> m_refined_injection_mask = nullptr; + // Inject particles during the whole simulation + void ContinuousInjection(const amrex::RealBox& injection_box) override; + }; #endif diff --git a/Source/Particles/PhysicalParticleContainer.cpp b/Source/Particles/PhysicalParticleContainer.cpp index 17e6d98d9..2fa39d87d 100644 --- a/Source/Particles/PhysicalParticleContainer.cpp +++ b/Source/Particles/PhysicalParticleContainer.cpp @@ -24,7 +24,7 @@ NumParticlesToAdd(const Box& overlap_box, const RealBox& overlap_realbox, for (IntVect iv = overlap_box.smallEnd(); iv <= overlap_box.bigEnd(); overlap_box.next(iv)) { int fac; - if (injected) { + if (do_continuous_injection) { #if ( AMREX_SPACEDIM == 3 ) Real x = overlap_corner[0] + (iv[0] + 0.5)*dx[0]; Real y = overlap_corner[1] + (iv[1] + 0.5)*dx[1]; @@ -81,6 +81,7 @@ PhysicalParticleContainer::PhysicalParticleContainer (AmrCore* amr_core, int isp pp.query("do_backward_propagation", do_backward_propagation); pp.query("do_splitting", do_splitting); pp.query("split_type", split_type); + pp.query("do_continuous_injection", do_continuous_injection); } PhysicalParticleContainer::PhysicalParticleContainer (AmrCore* amr_core) @@ -361,7 +362,7 @@ PhysicalParticleContainer::AddPlasmaCPU (int lev, RealBox part_realbox) for (IntVect iv = overlap_box.smallEnd(); iv <= overlap_box.bigEnd(); overlap_box.next(iv)) { int fac; - if (injected) { + if (do_continuous_injection) { #if ( AMREX_SPACEDIM == 3 ) Real x = overlap_corner[0] + (iv[0] + 0.5)*dx[0]; Real y = overlap_corner[1] + (iv[1] + 0.5)*dx[1]; @@ -602,7 +603,7 @@ PhysicalParticleContainer::AddPlasmaGPU (int lev, RealBox part_realbox) for (IntVect iv = overlap_box.smallEnd(); iv <= overlap_box.bigEnd(); overlap_box.next(iv)) { int fac; - if (injected) { + if (do_continuous_injection) { #if ( AMREX_SPACEDIM == 3 ) Real x = overlap_corner[0] + (iv[0] + 0.5)*dx[0]; Real y = overlap_corner[1] + (iv[1] + 0.5)*dx[1]; @@ -2004,3 +2005,14 @@ int PhysicalParticleContainer::GetRefineFac(const Real x, const Real y, const Re return ref_fac; } + +/* \brief Inject particles during the simulation + * \param injection_box: domain where particles should be injected. + */ +void +PhysicalParticleContainer::ContinuousInjection(const RealBox& injection_box) +{ + // Inject plasma on level 0. Paticles will be redistributed. + const int lev=0; + AddPlasma(lev, injection_box); +} diff --git a/Source/Particles/WarpXParticleContainer.H b/Source/Particles/WarpXParticleContainer.H index 275554cd8..6fa02b824 100644 --- a/Source/Particles/WarpXParticleContainer.H +++ b/Source/Particles/WarpXParticleContainer.H @@ -183,7 +183,18 @@ public: int thread_num, int lev, amrex::Real dt ); - + + // If particles start outside of the domain, ContinuousInjection + // makes sure that they are initialized when they enter the domain, and + // NOT before. Virtual function, overriden by derived classes. + // Current status: + // PhysicalParticleContainer: implemented. + // LaserParticleContainer: implemented. + // RigidInjectedParticleContainer: not implemented. + virtual void ContinuousInjection(const amrex::RealBox& injection_box) {} + // Update optional sub-class-specific injection location. + virtual void UpdateContinuousInjectionPosition(amrex::Real dt) {} + /// /// This returns the total charge for all the particles in this ParticleContainer. /// This is needed when solving Poisson's equation with periodic boundary conditions. @@ -248,6 +259,12 @@ protected: static int do_not_push; + // Whether to allow particles outside of the simulation domain to be + // initialized when they enter the domain. + // This is currently required because continuous injection does not + // support all features allowed by direct injection. + int do_continuous_injection = 0; + amrex::Vector<amrex::FArrayBox> local_rho; amrex::Vector<amrex::FArrayBox> local_jx; amrex::Vector<amrex::FArrayBox> local_jy; @@ -258,6 +275,7 @@ protected: private: virtual void particlePostLocate(ParticleType& p, const amrex::ParticleLocData& pld, const int lev) override; + }; #endif diff --git a/Source/Utils/WarpXMovingWindow.cpp b/Source/Utils/WarpXMovingWindow.cpp index 05e171f22..18d89951d 100644 --- a/Source/Utils/WarpXMovingWindow.cpp +++ b/Source/Utils/WarpXMovingWindow.cpp @@ -9,7 +9,7 @@ WarpX::UpdatePlasmaInjectionPosition (Real dt) { int dir = moving_window_dir; // Continuously inject plasma in new cells (by default only on level 0) - if (WarpX::do_plasma_injection and (WarpX::gamma_boost > 1)){ + if (WarpX::warpx_do_continuous_injection and (WarpX::gamma_boost > 1)){ // In boosted-frame simulations, the plasma has moved since the last // call to this function, and injection position needs to be updated current_injection_position -= WarpX::beta_boost * @@ -33,7 +33,16 @@ WarpX::MoveWindow (bool move_j) // and of the plasma injection moving_window_x += moving_window_v * dt[0]; int dir = moving_window_dir; + + // Update warpx.current_injection_position + // PhysicalParticleContainer uses this injection position UpdatePlasmaInjectionPosition( dt[0] ); + if (WarpX::warpx_do_continuous_injection){ + // Update injection position for WarpXParticleContainer in mypc. + // Nothing to do for PhysicalParticleContainers + // For LaserParticleContainer, need to update the antenna position. + mypc->UpdateContinuousInjectionPosition( dt[0] ); + } // compute the number of cells to shift on the base level Real new_lo[AMREX_SPACEDIM]; @@ -134,7 +143,7 @@ WarpX::MoveWindow (bool move_j) } // Continuously inject plasma in new cells (by default only on level 0) - if (WarpX::do_plasma_injection) { + if (WarpX::warpx_do_continuous_injection) { const int lev = 0; @@ -162,15 +171,11 @@ WarpX::MoveWindow (bool move_j) particleBox.setLo( dir, new_injection_position ); particleBox.setHi( dir, current_injection_position ); } - // Perform the injection of new particles in particleBox + if (particleBox.ok() and (current_injection_position != new_injection_position)){ - for (int i = 0; i < num_injected_species; ++i) { - int ispecies = injected_plasma_species[i]; - WarpXParticleContainer& pc = mypc->GetParticleContainer(ispecies); - auto& ppc = dynamic_cast<PhysicalParticleContainer&>(pc); - ppc.AddPlasma(lev, particleBox); - } - // Update the injection position + // Performs continuous injection of all WarpXParticleContainer + // in mypc. + mypc->ContinuousInjection(particleBox); current_injection_position = new_injection_position; } } diff --git a/Source/WarpX.H b/Source/WarpX.H index 6cec8e5be..44e84033f 100644 --- a/Source/WarpX.H +++ b/Source/WarpX.H @@ -476,10 +476,10 @@ private: amrex::Real current_injection_position = 0; // Plasma injection parameters - int do_plasma_injection = 0; + int warpx_do_continuous_injection = 0; int num_injected_species = -1; amrex::Vector<int> injected_plasma_species; - + int do_electrostatic = 0; int n_buffer = 4; amrex::Real const_dt = 0.5e-11; diff --git a/Source/WarpX.cpp b/Source/WarpX.cpp index 47ead98df..a3a24897a 100644 --- a/Source/WarpX.cpp +++ b/Source/WarpX.cpp @@ -145,13 +145,14 @@ WarpX::WarpX () // Particle Container mypc = std::unique_ptr<MultiParticleContainer> (new MultiParticleContainer(this)); - - if (do_plasma_injection) { - for (int i = 0; i < num_injected_species; ++i) { - int ispecies = injected_plasma_species[i]; - WarpXParticleContainer& pc = mypc->GetParticleContainer(ispecies); - auto& ppc = dynamic_cast<PhysicalParticleContainer&>(pc); - ppc.injected = true; + warpx_do_continuous_injection = mypc->doContinuousInjection(); + if (warpx_do_continuous_injection){ + if (moving_window_v >= 0){ + // Inject particles continuously from the right end of the box + current_injection_position = geom[0].ProbHi(moving_window_dir); + } else { + // Inject particles continuously from the left end of the box + current_injection_position = geom[0].ProbLo(moving_window_dir); } } @@ -300,21 +301,6 @@ WarpX::ReadParameters () moving_window_v *= PhysConst::c; } - pp.query("do_plasma_injection", do_plasma_injection); - if (do_plasma_injection) { - pp.get("num_injected_species", num_injected_species); - injected_plasma_species.resize(num_injected_species); - pp.getarr("injected_plasma_species", injected_plasma_species, - 0, num_injected_species); - if (moving_window_v >= 0){ - // Inject particles continuously from the right end of the box - current_injection_position = geom[0].ProbHi(moving_window_dir); - } else { - // Inject particles continuously from the left end of the box - current_injection_position = geom[0].ProbLo(moving_window_dir); - } - } - pp.query("do_boosted_frame_diagnostic", do_boosted_frame_diagnostic); if (do_boosted_frame_diagnostic) { diff --git a/Tools/Visualization.ipynb b/Tools/Visualization.ipynb index f5946a3de..5ac03f931 100644 --- a/Tools/Visualization.ipynb +++ b/Tools/Visualization.ipynb @@ -991,21 +991,21 @@ "metadata": { "anaconda-cloud": {}, "kernelspec": { - "display_name": "Python 2", + "display_name": "Python 3", "language": "python", - "name": "python2" + "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", - "version": 2 + "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.14" + "pygments_lexer": "ipython3", + "version": "3.7.1" }, "widgets": { "state": { diff --git a/Tools/performance_tests/automated_test_4_labdiags_2ppc b/Tools/performance_tests/automated_test_4_labdiags_2ppc index 866bb68d1..f762c9b8c 100644 --- a/Tools/performance_tests/automated_test_4_labdiags_2ppc +++ b/Tools/performance_tests/automated_test_4_labdiags_2ppc @@ -45,11 +45,6 @@ warpx.do_boosted_frame_diagnostic = 1 warpx.num_snapshots_lab = 20 warpx.dt_snapshots_lab = 7.0e-14 -# Particle Injection -warpx.do_plasma_injection = 1 -warpx.num_injected_species = 2 -warpx.injected_plasma_species = 0 1 - # Species particles.nspecies = 2 particles.species_names = electrons ions @@ -66,6 +61,7 @@ electrons.num_particles_per_cell_each_dim = 1 1 1 electrons.profile = constant electrons.density = 1. electrons.momentum_distribution_type = "constant" +electrons.do_continuous_injection = 1 ions.charge = q_e ions.mass = m_p @@ -79,6 +75,7 @@ ions.num_particles_per_cell_each_dim = 1 1 1 ions.profile = constant ions.density = 1. ions.momentum_distribution_type = "constant" +ions.do_continuous_injection = 1 # Laser warpx.use_laser = 1 |