Skip to content
3 changes: 3 additions & 0 deletions src/ImpactX.H
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ namespace impactx
//! Delete level data
void ClearLevel (int lev) override;

//! Resize the mesh, based on the extent of the bunch of particle
void ResizeMesh ();

/** these are the physical/beam particles of the simulation */
std::unique_ptr<ImpactXParticleContainer> m_particle_container;

Expand Down
25 changes: 25 additions & 0 deletions src/ImpactX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,24 @@ namespace impactx
amrex::ignore_unused(lev);
}

void ImpactX::ResizeMesh () {
// Extract the min and max of the particle positions
auto const [x_min, x_max, y_min, y_max, z_min, z_max] = m_particle_container->MinAndMaxPositions();
// Resize the domain size
// The box is expanded slightly beyond the min and max of particles.
// This controlled by the variable `frac` below.
const amrex::Real frac=0.1;
amrex::RealBox rb(
{x_min-frac*(x_max-x_min), y_min-frac*(y_max-y_min), z_min-frac*(z_max-z_min)}, // Low bound
{x_max+frac*(x_max-x_min), y_max+frac*(y_max-y_min), z_max+frac*(z_max-z_min)}); // High bound
amrex::Geometry::ResetDefaultProbDomain(rb);
for (int lev = 0; lev <= max_level; ++lev) {
amrex::Geometry g = Geom(lev);
g.ProbDomain(rb);
amrex::AmrMesh::SetGeometry(lev, g);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RemiLehe when compiling & running this in Debug, I get this error:

0::Assertion `hi > lo' failed, file "/home/axel/src/impactx/build/_deps/fetchedamrex-src/Src/Base/AMReX_Algorithm.H", line 107, Msg: "Error - calling bisect but lo and hi don't describe a reasonable interval." !!!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opened as #44 to track :)

Disabled temporarily in #43 until we can fix it.

}
}

void ImpactX::evolve (int num_steps)
{
BL_PROFILE("ImpactX::evolve");
Expand All @@ -106,6 +124,13 @@ namespace impactx
BL_PROFILE("ImpactX::evolve::step");
amrex::Print() << " ++++ Starting step=" << step << "\n";

// Note: The following operation assume that
// the particles are in x, y, z coordinates.
// Resize the mesh, based on `m_particle_container` extent
ResizeMesh();
// Redistribute particles in the new mesh
m_particle_container->Redistribute();

// push all particles
Push(*m_particle_container, m_lattice);

Expand Down
12 changes: 12 additions & 0 deletions src/particles/ImpactXParticleContainer.H
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include <AMReX_Vector.H>

#include <tuple>


namespace impactx
{
Expand Down Expand Up @@ -83,6 +85,16 @@ namespace impactx
amrex::Vector<amrex::ParticleReal> const & y,
amrex::Vector<amrex::ParticleReal> const & z);

/** Compute the min and max of the particle position in each dimension
*
* @returns x_min, x_max, y_min, y_max, z_min, z_max
*/
std::tuple<
amrex::ParticleReal, amrex::ParticleReal,
amrex::ParticleReal, amrex::ParticleReal,
amrex::ParticleReal, amrex::ParticleReal>
MinAndMaxPositions ();

}; // ImpactXParticleContainer

} // namespace impactx
Expand Down
39 changes: 39 additions & 0 deletions src/particles/ImpactXParticleContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,43 @@ namespace impactx
// Redistribute();

}

std::tuple<
amrex::ParticleReal, amrex::ParticleReal,
amrex::ParticleReal, amrex::ParticleReal,
amrex::ParticleReal, amrex::ParticleReal>
ImpactXParticleContainer::MinAndMaxPositions ()
{
using PType = ImpactXParticleContainer::SuperParticleType;

// Get min and max for the local rank
amrex::ReduceOps<amrex::ReduceOpMin, amrex::ReduceOpMin, amrex::ReduceOpMin, amrex::ReduceOpMax, amrex::ReduceOpMax, amrex::ReduceOpMax> reduce_ops;
auto r = amrex::ParticleReduce<amrex::ReduceData<amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal>>(
*this,
[=] AMREX_GPU_DEVICE(const PType& p) noexcept -> amrex::GpuTuple<amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal>
{
amrex::ParticleReal x = p.pos(0);
amrex::ParticleReal y = p.pos(1);
amrex::ParticleReal z = p.pos(2);
return {x, y, z, x, y, z};
},
reduce_ops);

// Get min and max across all ranks
std::vector<amrex::ParticleReal> xyz_min = {
amrex::get<0>(r),
amrex::get<1>(r),
amrex::get<2>(r)
};
amrex::ParallelDescriptor::ReduceRealMin(xyz_min.data(), xyz_min.size());
std::vector<amrex::ParticleReal> xyz_max = {
amrex::get<3>(r),
amrex::get<4>(r),
amrex::get<5>(r)
};
amrex::ParallelDescriptor::ReduceRealMax(xyz_max.data(), xyz_max.size());

return {xyz_min[0], xyz_min[1], xyz_min[2], xyz_max[0], xyz_max[1], xyz_max[2]};
}

} // namespace impactx