1#ifndef OPAL_LOAD_BALANCER_H
2#define OPAL_LOAD_BALANCER_H
8template <
typename T,
unsigned Dim>
9using ORB = ippl::OrthogonalRecursiveBisection<Field<double, Dim>,
T>;
11template <
typename T,
unsigned Dim>
13 using Base = ippl::ParticleBase<ippl::ParticleSpatialLayout<T, Dim>>;
21 std::shared_ptr<ParticleContainer<T, Dim>>
pc_m;
22 std::shared_ptr<FieldSolver_t>
fs_m;
84 ippl::FieldLayout<Dim>* fl, ippl::UniformCartesian<T, Dim>* mesh,
85 bool& isFirstRepartition) {
88 static IpplTimings::TimerRef tupdateLayout = IpplTimings::getTimer(
"updateLayout");
89 IpplTimings::startTimer(tupdateLayout);
90 (*E_m).updateLayout(*fl);
91 (*rho_m).updateLayout(*fl);
93 if (
fs_m->getStype() ==
"CG") {
94 phi_m->updateLayout(*fl);
100 (*layout).updateLayout(*fl, *mesh);
101 IpplTimings::stopTimer(tupdateLayout);
102 static IpplTimings::TimerRef tupdatePLayout = IpplTimings::getTimer(
"updatePB");
103 IpplTimings::startTimer(tupdatePLayout);
104 if (!isFirstRepartition) {
107 IpplTimings::stopTimer(tupdatePLayout);
110 void initializeORB(ippl::FieldLayout<Dim>* fl, ippl::UniformCartesian<T, Dim>* mesh) {
115 ippl::FieldLayout<Dim>* fl, ippl::UniformCartesian<T, Dim>* mesh,
116 bool& isFirstRepartition) {
120 using Base = ippl::ParticleBase<ippl::ParticleSpatialLayout<T, Dim>>;
121 typename Base::particle_position_type *R;
123 bool res =
orb.binaryRepartition(*R, *fl, isFirstRepartition);
125 std::cout <<
"Could not repartition!" << std::endl;
130 if constexpr (
Dim == 2 ||
Dim == 3) {
131 if (
fs_m->getStype() ==
"FFT") {
132 std::get<FFTSolver_t<T, Dim>>(
fs_m->getSolver()).setRhs(*
rho_m);
134 if constexpr (
Dim == 3) {
135 if (
fs_m->getStype() ==
"TG") {
136 std::get<FFTTruncatedGreenSolver_t<T, Dim>>(
fs_m->getSolver()).setRhs(*
rho_m);
137 }
else if (
fs_m->getStype() ==
"OPEN") {
138 std::get<OpenSolver_t<T, Dim>>(
fs_m->getSolver()).setRhs(*
rho_m);
146 if (ippl::Comm->size() < 2) {
150 std::vector<int> res(ippl::Comm->size());
151 double equalPart = (double)totalP / ippl::Comm->size();
152 double dev = std::abs((
double)
pc_m->getLocalNum() - equalPart) / totalP;
157 &local, 1, MPI_INT, res.data(), 1, MPI_INT, ippl::Comm->getCommunicator());
159 for (
unsigned int i = 0; i < res.size(); i++) {
ippl::Field< double, Dim, ViewArgs... > Field_t
ippl::Field< ippl::Vector< T, Dim >, Dim, ViewArgs... > VField_t
typename ippl::ParticleSpatialLayout< T, Dim, Mesh_t< Dim > > PLayout_t
ippl::Field< T, Dim, Mesh_t< Dim >, Centering_t< Dim >, ViewArgs... > Field
ippl::detail::size_type size_type
ippl::OrthogonalRecursiveBisection< Field< double, Dim >, T > ORB
std::shared_ptr< FieldSolver_t > getFieldSolver() const
double loadbalancethreshold_m
void setParticleContainer(std::shared_ptr< ParticleContainer< T, Dim > > pc)
Field_t< Dim > * getRho() const
void setE(VField_t< T, Dim > *E)
void setLoadBalanceThreshold(double threshold)
Field< T, Dim > * getPhi()
LoadBalancer(double lbs, std::shared_ptr< FieldContainer< T, Dim > > &fc, std::shared_ptr< ParticleContainer< T, Dim > > &pc, std::shared_ptr< FieldSolver_t > &fs)
void setRho(Field_t< Dim > *rho)
bool balance(size_type totalP, const unsigned int nstep)
unsigned int loadbalancefreq_m
double getLoadBalanceThreshold() const
VField_t< T, Dim > * getE() const
ippl::FieldSolverBase< T, Dim > FieldSolver_t
void repartition(ippl::FieldLayout< Dim > *fl, ippl::UniformCartesian< T, Dim > *mesh, bool &isFirstRepartition)
ippl::ParticleBase< ippl::ParticleSpatialLayout< T, Dim > > Base
std::shared_ptr< FieldSolver_t > fs_m
void updateLayout(ippl::FieldLayout< Dim > *fl, ippl::UniformCartesian< T, Dim > *mesh, bool &isFirstRepartition)
std::shared_ptr< ParticleContainer< T, Dim > > getParticleContainer() const
void setPhi(Field< T, Dim > *phi)
void setFieldSolver(std::shared_ptr< FieldSolver_t > fs)
void initializeORB(ippl::FieldLayout< Dim > *fl, ippl::UniformCartesian< T, Dim > *mesh)
std::shared_ptr< ParticleContainer< T, Dim > > pc_m