Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moving Frame Field Probe Functionality #2996

Merged
merged 17 commits into from
Apr 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Docs/source/usage/parameters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2314,6 +2314,7 @@ Reduced Diagnostics
otherwise it is set to ``1``.
Integrated electric and magnetic field components can instead be obtained by specifying
``<reduced_diags_name>.integrate == true``.
In a *moving window* simulation, the FieldProbe can be set to follow the moving frame by specifying ``<reduced_diags_name>.do_moving_window_FP = 1`` (default 0).

.. warning::

Expand Down
12 changes: 12 additions & 0 deletions Examples/Physics_applications/laser_acceleration/inputs_1d
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,15 @@ diagnostics.diags_names = diag1
diag1.intervals = 100
diag1.diag_type = Full
diag1.fields_to_plot = Ex Ey Ez Bx By Bz jx jy jz rho

# Reduced Diagnostics
warpx.reduced_diags_names = FP

FP.type = FieldProbe
FP.intervals = 10
FP.integrate = 0
FP.probe_geometry = Line
FP.z_probe = -56e-6
FP.z1_probe = 12e-6
FP.resolution = 100
FP.do_moving_window_FP = 1
14 changes: 14 additions & 0 deletions Examples/Physics_applications/laser_acceleration/inputs_2d
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,17 @@ diagnostics.diags_names = diag1
diag1.intervals = 200
diag1.diag_type = Full
diag1.fields_to_plot = Ex Ey Ez Bx By Bz jx jy jz rho

# Reduced Diagnostics
warpx.reduced_diags_names = FP

FP.type = FieldProbe
FP.intervals = 10
FP.integrate = 0
FP.probe_geometry = Line
FP.x_probe = 0
FP.z_probe = -56e-6
FP.x1_probe = 0
FP.z1_probe = 12e-6
FP.resolution = 300
FP.do_moving_window_FP = 1
16 changes: 16 additions & 0 deletions Examples/Physics_applications/laser_acceleration/inputs_3d
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,19 @@ diagnostics.diags_names = diag1
diag1.intervals = 100
diag1.diag_type = Full
diag1.fields_to_plot = Ex Ey Ez Bx By Bz jx jy jz rho

# Reduced Diagnostics
warpx.reduced_diags_names = FP

FP.type = FieldProbe
FP.intervals = 10
FP.integrate = 0
FP.probe_geometry = Line
FP.x_probe = 0
FP.y_probe = 0
FP.z_probe = -56e-6
FP.x1_probe = 0
FP.y1_probe = 0
FP.z1_probe = 12e-6
FP.resolution = 300
FP.do_moving_window_FP = 1
6 changes: 6 additions & 0 deletions Source/Diagnostics/ReducedDiags/FieldProbe.H
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ private:
//! counts number of particles for all MPI ranks
long m_valid_particles {0};

//! remember the last time @see ComputeDiags was called to count the number of steps in between (for non-integrated detectors)
int m_last_compute_step = 0;

//! determines geometry of detector point distribution
DetectorGeometry m_probe_geometry = DetectorGeometry::Point;

Expand All @@ -100,6 +103,9 @@ private:
//! Judges whether to gather raw fields or interpolated data
bool raw_fields = false;

//! Judges whether to follow a moving window
bool do_moving_window_FP = false;

/**
* Built-in function in ReducedDiags to write out test data
*/
Expand Down
41 changes: 39 additions & 2 deletions Source/Diagnostics/ReducedDiags/FieldProbe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "FieldProbe.H"
#include "FieldProbeParticleContainer.H"
#include "Particles/Gather/FieldGather.H"
#include "Particles/Pusher/GetAndSetPosition.H"
#include "Particles/Pusher/UpdatePosition.H"

#include "Utils/IntervalsParser.H"
#include "Utils/TextMsg.H"
Expand Down Expand Up @@ -147,6 +149,7 @@ FieldProbe::FieldProbe (std::string rd_name)
pp_rd_name.query("integrate", m_field_probe_integrate);
pp_rd_name.query("raw_fields", raw_fields);
pp_rd_name.query("interp_order", interp_order);
pp_rd_name.query("do_moving_window_FP", do_moving_window_FP);

if (WarpX::gamma_boost > 1.0_rt)
{
Expand Down Expand Up @@ -385,6 +388,18 @@ void FieldProbe::ComputeDiags (int step)
{
const amrex::Geometry& gm = warpx.Geom(lev);
const auto prob_lo = gm.ProbLo();
amrex::Real const dt = WarpX::GetInstance().getdt(lev);
// Calculates particle movement in moving window sims
amrex::Real move_dist = 0.0;
bool const update_particles_moving_window =
do_moving_window_FP &&
step > warpx.start_moving_window_step &&
step <= warpx.end_moving_window_step;
if (update_particles_moving_window)
{
int step_diff = step - m_last_compute_step;
move_dist = dt*warpx.moving_window_v*step_diff;
}

// get MultiFab data at lev
const amrex::MultiFab &Ex = warpx.getEfield(lev, 0);
Expand Down Expand Up @@ -426,8 +441,30 @@ void FieldProbe::ComputeDiags (int step)
for (MyParIter pti(m_probe, lev); pti.isValid(); ++pti)
{
const auto getPosition = GetParticlePosition(pti);
auto const np = pti.numParticles();
auto setPosition = SetParticlePosition(pti);

auto const np = pti.numParticles();
if (update_particles_moving_window)
{
const auto temp_warpx_moving_window = warpx.moving_window_dir;
amrex::ParallelFor( np, [=] AMREX_GPU_DEVICE (long ip)
{
amrex::ParticleReal xp, yp, zp;
getPosition(ip, xp, yp, zp);
if (temp_warpx_moving_window == 0)
{
setPosition(ip, xp+move_dist, yp, zp);
}
if (temp_warpx_moving_window == 1)
{
setPosition(ip, xp, yp+move_dist, zp);
}
if (temp_warpx_moving_window == WARPX_ZINDEX)
{
setPosition(ip, xp, yp, zp+move_dist);
}
});
}
if( ProbeInDomain() )
{
const auto cell_size = gm.CellSizeArray();
Expand Down Expand Up @@ -479,7 +516,6 @@ void FieldProbe::ComputeDiags (int step)
const int temp_interp_order = interp_order;
const bool temp_raw_fields = raw_fields;
const bool temp_field_probe_integrate = m_field_probe_integrate;
amrex::Real const dt = WarpX::GetInstance().getdt(lev);

// Interpolating to the probe positions for each particle
amrex::ParallelFor( np, [=] AMREX_GPU_DEVICE (long ip)
Expand Down Expand Up @@ -614,6 +650,7 @@ void FieldProbe::ComputeDiags (int step)
}// end loop over refinement levels
// make sure data is in m_data on the IOProcessor
// TODO: In the future, we want to use a parallel I/O method instead (plotfiles or openPMD)
m_last_compute_step = step;
} // end void FieldProbe::ComputeDiags

void FieldProbe::WriteToFile (int step) const
Expand Down
4 changes: 3 additions & 1 deletion Source/Particles/Pusher/GetAndSetPosition.H
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ struct SetParticlePosition
#if defined(WARPX_DIM_RZ)
RType* AMREX_RESTRICT m_theta;
#endif
SetParticlePosition (WarpXParIter& a_pti, int a_offset = 0) noexcept

template <typename ptiType>
SetParticlePosition (const ptiType& a_pti, int a_offset = 0) noexcept
{
auto& aos = a_pti.GetArrayOfStructs();
m_structs = aos().dataPtr() + a_offset;
Expand Down