8 double initial_epsilon,
10 unsigned int num_steps)
11 : mpi_communicator(comm)
12 , this_mpi_process(Utilities::MPI::this_mpi_process(comm))
13 , pcout(std::cout, this_mpi_process == 0)
14 , initial_epsilon(initial_epsilon)
15 , scaling_factor(scaling_factor)
16 , num_steps(num_steps)
20 pcout <<
"Warning: Epsilon scaling factor should be > 1.0. Using default value of 2.0." << std::endl;
21 this->scaling_factor = 2.0;
25 pcout <<
"Warning: Number of epsilon scaling steps cannot be 0. Using default value of 1." << std::endl;
32 std::vector<double> epsilon_sequence;
36 for (
unsigned int i = 0; i <
num_steps; ++i) {
41 return epsilon_sequence;
45 const std::vector<double>& epsilon_sequence,
46 unsigned int num_levels)
48 std::vector<std::vector<double>> distribution(num_levels);
50 if (num_levels == 0) {
51 pcout <<
"Warning: No levels provided for epsilon distribution." << std::endl;
57 if (epsilon_sequence.size() <= num_levels) {
60 for (
unsigned int level = 0; level < num_levels; ++level) {
61 if (level < epsilon_sequence.size()) {
62 distribution[level].push_back(epsilon_sequence[level]);
65 distribution[level].push_back(epsilon_sequence.back());
71 unsigned int remaining_epsilons = epsilon_sequence.size();
72 unsigned int remaining_levels = num_levels;
74 unsigned int epsilon_index = 0;
75 for (
unsigned int level = 0; level < num_levels; ++level) {
77 unsigned int epsilons_for_level = (remaining_epsilons + remaining_levels - 1) / remaining_levels;
80 for (
unsigned int i = 0; i < epsilons_for_level && epsilon_index < epsilon_sequence.size(); ++i) {
81 distribution[level].push_back(epsilon_sequence[epsilon_index++]);
84 remaining_epsilons -= epsilons_for_level;
93 unsigned int num_levels)
103 unsigned int level_index)
const
107 static const std::vector<double> empty_vector;
108 pcout <<
"Warning: Requested epsilon values for invalid level index: "
109 << level_index << std::endl;
121 pcout <<
"Epsilon distribution has not been computed yet." << std::endl;
125 pcout <<
"\n----------------------------------------" << std::endl;
126 pcout <<
"Epsilon Scaling Distribution:" << std::endl;
127 pcout <<
"----------------------------------------" << std::endl;
132 pcout <<
"----------------------------------------" << std::endl;
136 pcout <<
"Level " << num_levels - level <<
" (";
142 pcout <<
"intermediate";
147 pcout << level_epsilons.size() <<
" epsilon value(s): ";
149 for (
unsigned int i = 0; i < level_epsilons.size(); ++i) {
150 pcout << std::scientific << std::setprecision(4) << level_epsilons[i];
151 if (i < level_epsilons.size() - 1) {
157 pcout <<
"----------------------------------------" << std::endl;
158 pcout << std::defaultfloat;
double initial_epsilon
The initial epsilon value.
void print_epsilon_distribution() const
Print the epsilon distribution.
double scaling_factor
The scaling factor for epsilon.
std::vector< double > generate_epsilon_sequence() const
Generate the sequence of epsilon values.
std::vector< std::vector< double > > distribute_epsilon_values(const std::vector< double > &epsilon_sequence, unsigned int num_levels)
Distribute epsilon values across levels.
std::vector< std::vector< double > > epsilon_distribution
The computed epsilon distribution.
const std::vector< double > & get_epsilon_values_for_level(unsigned int level_index) const
Get epsilon values for a specific level.
unsigned int num_steps
The total number of epsilon scaling steps.
EpsilonScalingHandler(const MPI_Comm &comm, double initial_epsilon, double scaling_factor, unsigned int num_steps)
Constructor.
std::vector< std::vector< double > > compute_epsilon_distribution(unsigned int num_levels)
Compute epsilon distribution for multilevel optimization.
ConditionalOStream pcout
A conditional output stream for parallel printing.
const unsigned int this_mpi_process
The rank of the current MPI process.