aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/Diagnostics/ReducedDiags/FieldProbe.H11
-rw-r--r--Source/Diagnostics/ReducedDiags/FieldProbe.cpp87
2 files changed, 53 insertions, 45 deletions
diff --git a/Source/Diagnostics/ReducedDiags/FieldProbe.H b/Source/Diagnostics/ReducedDiags/FieldProbe.H
index 655ebc2a0..4f72fc720 100644
--- a/Source/Diagnostics/ReducedDiags/FieldProbe.H
+++ b/Source/Diagnostics/ReducedDiags/FieldProbe.H
@@ -114,6 +114,17 @@ private:
/** Check if the probe is in the simulation domain boundary
*/
bool ProbeInDomain () const;
+
+ /**
+ * Simple utility function to normalize the components of a "vector"
+ */
+ void normalize(amrex::Real &AMREX_RESTRICT x, amrex::Real &AMREX_RESTRICT y,
+ amrex::Real &AMREX_RESTRICT z){
+ amrex::Real mag = std::sqrt(x*x + y*y + z*z);
+ x /= mag;
+ y /= mag;
+ z /= mag;
+ }
};
#endif // WARPX_DIAGNOSTICS_REDUCEDDIAGS_FIELDPROBE_H_
diff --git a/Source/Diagnostics/ReducedDiags/FieldProbe.cpp b/Source/Diagnostics/ReducedDiags/FieldProbe.cpp
index 17afcf62a..19643829e 100644
--- a/Source/Diagnostics/ReducedDiags/FieldProbe.cpp
+++ b/Source/Diagnostics/ReducedDiags/FieldProbe.cpp
@@ -240,31 +240,23 @@ FieldProbe::FieldProbe (std::string rd_name)
void FieldProbe::InitData ()
{
- if (m_probe_geometry == DetectorGeometry::Point)
- {
+ using namespace amrex::literals;
- // create 1D vector for X, Y, and Z of particles
- amrex::Vector<amrex::ParticleReal> xpos;
- amrex::Vector<amrex::ParticleReal> ypos;
- amrex::Vector<amrex::ParticleReal> zpos;
+ // create 1D vector for X, Y, and Z coordinates of "particles"
+ amrex::Vector<amrex::ParticleReal> xpos;
+ amrex::Vector<amrex::ParticleReal> ypos;
+ amrex::Vector<amrex::ParticleReal> zpos;
- // for now, only one MPI rank adds a probe particle
- if (ParallelDescriptor::IOProcessor())
+ // for now, only one MPI rank adds probe "particles"
+ if (ParallelDescriptor::IOProcessor())
+ {
+ if (m_probe_geometry == DetectorGeometry::Point)
{
xpos.push_back(x_probe);
ypos.push_back(y_probe);
zpos.push_back(z_probe);
}
-
- // add particles on lev 0 to m_probe
- m_probe.AddNParticles(0, xpos, ypos, zpos);
- }
- else if (m_probe_geometry == DetectorGeometry::Line)
- {
- amrex::Vector<amrex::ParticleReal> xpos;
- amrex::Vector<amrex::ParticleReal> ypos;
- amrex::Vector<amrex::ParticleReal> zpos;
- if (ParallelDescriptor::IOProcessor())
+ else if (m_probe_geometry == DetectorGeometry::Line)
{
xpos.reserve(m_resolution);
ypos.reserve(m_resolution);
@@ -282,66 +274,71 @@ void FieldProbe::InitData ()
zpos.push_back(z_probe + (DetLineStepSize[2] * step));
}
}
- m_probe.AddNParticles(0, xpos, ypos, zpos);
- }
- else if (m_probe_geometry == DetectorGeometry::Plane)
- {
- amrex::Vector<amrex::ParticleReal> xpos;
- amrex::Vector<amrex::ParticleReal> ypos;
- amrex::Vector<amrex::ParticleReal> zpos;
- if (ParallelDescriptor::IOProcessor())
+ else if (m_probe_geometry == DetectorGeometry::Plane)
{
std::size_t const res2 = std::size_t(m_resolution) * std::size_t(m_resolution);
xpos.reserve(res2);
ypos.reserve(res2);
zpos.reserve(res2);
+ // ensure that input vectors are normalized
+ normalize(target_normal_x, target_normal_y, target_normal_z);
+ normalize(target_up_x, target_up_y, target_up_z);
+
// create vector orthonormal to input vectors
amrex::Real orthotarget[3]{
target_normal_y * target_up_z - target_normal_z * target_up_y,
target_normal_z * target_up_x - target_normal_x * target_up_z,
target_normal_x * target_up_y - target_normal_y * target_up_x};
+
// find upper left and lower right bounds of detector
amrex::Real direction[3]{
orthotarget[0] - target_up_x,
orthotarget[1] - target_up_y,
orthotarget[2] - target_up_z};
- amrex::Real upperleft[3]{
+ normalize(direction[0], direction[1], direction[2]);
+ amrex::Real uppercorner[3]{
x_probe - (direction[0] * detector_radius),
y_probe - (direction[1] * detector_radius),
z_probe - (direction[2] * detector_radius)};
- amrex::Real lowerright[3]{
+ amrex::Real lowercorner[3]{
+ uppercorner[0] - (target_up_x * std::sqrt(2_rt) * detector_radius),
+ uppercorner[1] - (target_up_y * std::sqrt(2_rt) * detector_radius),
+ uppercorner[2] - (target_up_z * std::sqrt(2_rt) * detector_radius)};
+ amrex::Real loweropposite[3]{
x_probe + (direction[0] * detector_radius),
y_probe + (direction[1] * detector_radius),
z_probe + (direction[2] * detector_radius)};
+
// create array containing point-to-point step size
- amrex::Real DetPlaneStepSize[3]{
- (lowerright[0] - upperleft[0]) / (m_resolution - 1),
- (lowerright[1] - upperleft[1]) / (m_resolution - 1),
- (lowerright[2] - upperleft[2]) / (m_resolution - 1)};
+ amrex::Real SideStepSize[3]{
+ (loweropposite[0] - lowercorner[0]) / (m_resolution - 1),
+ (loweropposite[1] - lowercorner[1]) / (m_resolution - 1),
+ (loweropposite[2] - lowercorner[2]) / (m_resolution - 1)};
+ amrex::Real UpStepSize[3]{
+ (uppercorner[0] - lowercorner[0]) / (m_resolution - 1),
+ (uppercorner[1] - lowercorner[1]) / (m_resolution - 1),
+ (uppercorner[2] - lowercorner[2]) / (m_resolution - 1)};
+
amrex::Real temp_pos[3]{};
- // Target point on top of plane (arbitrarily top of plane perpendicular to yz)
- // For each point along top of plane, fill in YZ's beneath, then push back
- for ( int step = 0; step < m_resolution; step++)
+ // Starting at the lowercorner point, step sideways and up to form
+ // a grid of equally spaced coordinate points
+ for ( int sidestep = 0; sidestep < m_resolution; sidestep++)
{
- temp_pos[0] = upperleft[0] + (DetPlaneStepSize[0] * step);
- for ( int yzstep = 0; yzstep < m_resolution; yzstep++)
+ for ( int upstep = 0; upstep < m_resolution; upstep++)
{
- temp_pos[1] = upperleft[1] + (DetPlaneStepSize[1] * yzstep);
- temp_pos[2] = upperleft[2] + (DetPlaneStepSize[2] * yzstep);
+ temp_pos[0] = lowercorner[0] + SideStepSize[0] * sidestep + UpStepSize[0] * upstep;
+ temp_pos[1] = lowercorner[1] + SideStepSize[1] * sidestep + UpStepSize[1] * upstep;
+ temp_pos[2] = lowercorner[2] + SideStepSize[2] * sidestep + UpStepSize[2] * upstep;
xpos.push_back(temp_pos[0]);
ypos.push_back(temp_pos[1]);
zpos.push_back(temp_pos[2]);
}
}
}
- m_probe.AddNParticles(0, xpos, ypos, zpos);
- }
- else
- {
- amrex::Abort(Utils::TextMsg::Err(
- "Invalid probe geometry. Valid geometries are Point, Line, and Plane."));
}
+ // add particles on lev 0 to m_probe
+ m_probe.AddNParticles(0, xpos, ypos, zpos);
}
void FieldProbe::LoadBalance ()