diff options
-rw-r--r-- | Source/Diagnostics/ReducedDiags/FieldProbe.H | 11 | ||||
-rw-r--r-- | Source/Diagnostics/ReducedDiags/FieldProbe.cpp | 87 |
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 () |