22#ifndef EXADG_UTILITIES_PRINT_SOLVER_RESULTS_H_ 
   23#define EXADG_UTILITIES_PRINT_SOLVER_RESULTS_H_ 
   29#include <deal.II/base/conditional_ostream.h> 
   30#include <deal.II/base/mpi.h> 
   31#include <deal.II/base/utilities.h> 
   34#include <exadg/utilities/print_functions.h> 
   40  std::vector<std::tuple<unsigned int, dealii::types::global_dof_index, double>> 
const & wall_times,
 
   41  std::string 
const & operator_type,
 
   42  MPI_Comm 
const &    mpi_comm)
 
   44  unsigned int N_mpi_processes = dealii::Utilities::MPI::n_mpi_processes(mpi_comm);
 
   46  if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
 
   49    std::cout << std::endl
 
   50              << print_horizontal_line()
 
   51              << std::endl << std::endl
 
   52              << 
"Operator type: " << operator_type
 
   53              << std::endl << std::endl
 
   54              << std::setw(5) << std::left << 
"k" 
   55              << std::setw(15) << std::left << 
"DoFs" 
   56              << std::setw(15) << std::left << 
"DoFs/sec" 
   57              << std::setw(15) << std::left << 
"DoFs/(sec*core)" 
   58              << std::endl << std::flush;
 
   60    typedef typename std::vector<std::tuple<unsigned int, dealii::types::global_dof_index, double> >::const_iterator ITERATOR;
 
   61    for(ITERATOR it = wall_times.begin(); it != wall_times.end(); ++it)
 
   63      std::cout << std::setw(5) << std::left << std::get<0>(*it)
 
   64                << std::scientific << std::setprecision(4)
 
   65                << std::setw(15) << std::left << (double)std::get<1>(*it)
 
   66                << std::setw(15) << std::left << std::get<2>(*it)
 
   67                << std::setw(15) << std::left << std::get<2>(*it)/(double)N_mpi_processes
 
   68                << std::endl << std::flush;
 
   71    std::cout << print_horizontal_line() << std::endl << std::endl << std::flush;
 
   77print_throughput_steady(dealii::ConditionalOStream 
const &    pcout,
 
   78                        dealii::types::global_dof_index 
const n_dofs,
 
   79                        double const                          overall_time_avg,
 
   80                        unsigned int const                    N_mpi_processes)
 
   84        << 
"Throughput:" << std::endl
 
   85        << 
"  Number of MPI processes = " << N_mpi_processes << std::endl
 
   86        << 
"  Degrees of freedom      = " << n_dofs << std::endl
 
   87        << 
"  Wall time               = " << std::scientific << std::setprecision(2) << overall_time_avg << 
" s" << std::endl
 
   88        << 
"  Throughput              = " << std::scientific << std::setprecision(2) << n_dofs / (overall_time_avg * N_mpi_processes) << 
" DoFs/s/core" << std::endl
 
   94print_throughput_10(dealii::ConditionalOStream 
const &    pcout,
 
   95                    dealii::types::global_dof_index 
const n_dofs,
 
   97                    unsigned int const                    N_mpi_processes)
 
   99  double const tau_10 = t_10 * (double)N_mpi_processes / n_dofs;
 
  103        << 
"Throughput of linear solver (numbers based on n_10):" << std::endl
 
  104        << 
"  Number of MPI processes = " << N_mpi_processes << std::endl
 
  105        << 
"  Degrees of freedom      = " << n_dofs << std::endl
 
  106        << 
"  Wall time t_10          = " << std::scientific << std::setprecision(2) << t_10 << 
" s" << std::endl
 
  107        << 
"  tau_10                  = " << std::scientific << std::setprecision(2) << tau_10 << 
" s*core/DoF" << std::endl
 
  108        << 
"  Throughput E_10         = " << std::scientific << std::setprecision(2) << 1.0 / tau_10 << 
" DoF/s/core" << std::endl
 
  114print_throughput_unsteady(dealii::ConditionalOStream 
const &    pcout,
 
  115                          dealii::types::global_dof_index 
const n_dofs,
 
  116                          double const                          overall_time_avg,
 
  117                          unsigned int const                    N_time_steps,
 
  118                          unsigned int const                    N_mpi_processes)
 
  120  double const time_per_timestep = overall_time_avg / (double)N_time_steps;
 
  124        << 
"Throughput per time step:" << std::endl
 
  125        << 
"  Number of MPI processes = " << N_mpi_processes << std::endl
 
  126        << 
"  Degrees of freedom      = " << n_dofs << std::endl
 
  127        << 
"  Wall time               = " << std::scientific << std::setprecision(2) << overall_time_avg << 
" s" << std::endl
 
  128        << 
"  Time steps              = " << std::left << N_time_steps << std::endl
 
  129        << 
"  Wall time per time step = " << std::scientific << std::setprecision(2) << time_per_timestep << 
" s" << std::endl
 
  130        << 
"  Throughput              = " << std::scientific << std::setprecision(2) << n_dofs / (time_per_timestep * N_mpi_processes) << 
" DoFs/s/core" << std::endl
 
  136print_throughput_unsteady(dealii::ConditionalOStream 
const & pcout,
 
  137                          double const                       avg_n_dofs,
 
  138                          double const                       overall_time_avg,
 
  139                          unsigned int const                 N_time_steps,
 
  140                          unsigned int const                 N_mpi_processes)
 
  142  double const time_per_timestep = overall_time_avg / (double)N_time_steps;
 
  146        << 
"Throughput per time step:" << std::endl
 
  147        << 
"  Number of MPI processes    = " << N_mpi_processes << std::endl
 
  148        << 
"  Average Degrees of freedom = " << std::scientific << std::setprecision(2)<< avg_n_dofs << std::endl
 
  149        << 
"  Wall time                  = " << std::scientific << std::setprecision(2) << overall_time_avg << 
" s" << std::endl
 
  150        << 
"  Time steps                 = " << std::left << N_time_steps << std::endl
 
  151        << 
"  Wall time per time step    = " << std::scientific << std::setprecision(2) << time_per_timestep << 
" s" << std::endl
 
  152        << 
"  Throughput                 = " << std::scientific << std::setprecision(2) << avg_n_dofs / (time_per_timestep * N_mpi_processes) << 
" DoFs/s/core" << std::endl
 
  158print_costs(dealii::ConditionalOStream 
const & pcout,
 
  159            double const                       overall_time_avg,
 
  160            unsigned int const                 N_mpi_processes)
 
  165        << 
"Computational costs:" << std::endl
 
  166        << 
"  Number of MPI processes = " << N_mpi_processes << std::endl
 
  167        << 
"  Wall time               = " << std::scientific << std::setprecision(2) << overall_time_avg << 
" s" << std::endl
 
  168        << 
"  Computational costs     = " << std::scientific << std::setprecision(2) << overall_time_avg * (double)N_mpi_processes / 3600.0 << 
" CPUh" << std::endl
 
  174print_solver_info_nonlinear(dealii::ConditionalOStream 
const & pcout,
 
  175                            unsigned int const                 N_iter_nonlinear,
 
  176                            unsigned int const                 N_iter_linear,
 
  177                            double const                       wall_time)
 
  180  double const N_iter_linear_avg =
 
  181    (N_iter_nonlinear > 0) ? 
double(N_iter_linear) / double(N_iter_nonlinear) : N_iter_linear;
 
  185        << 
"  Newton iterations:      " << std::setw(12) << std::right << N_iter_nonlinear << std::endl
 
  186        << 
"  Linear iterations (avg):" << std::setw(12) << std::fixed << std::setprecision(1) << std::right << N_iter_linear_avg << std::endl
 
  187        << 
"  Linear iterations (tot):" << std::setw(12) << std::right << N_iter_linear << std::endl
 
  188        << 
"  Wall time [s]:          " << std::setw(12) << std::scientific << std::setprecision(2) << std::right << wall_time << std::endl
 
  194print_solver_info_linear(dealii::ConditionalOStream 
const & pcout,
 
  195                         unsigned int const                 N_iter_linear,
 
  196                         double const                       wall_time)
 
  201        << 
"  Iterations:   " << std::setw(12) << std::right << N_iter_linear << std::endl
 
  202        << 
"  Wall time [s]:" << std::setw(12) << std::scientific << std::setprecision(2) << std::right << wall_time << std::endl
 
  208print_wall_time(dealii::ConditionalOStream 
const & pcout, 
double const wall_time)
 
  213        << 
"  Wall time [s]:" << std::setw(12) << std::scientific << std::setprecision(2) << std::right << wall_time << std::endl
 
  219print_list_of_iterations(dealii::ConditionalOStream 
const & pcout,
 
  220                         std::vector<std::string> 
const &   names,
 
  221                         std::vector<double> 
const &        iterations_avg)
 
  223  unsigned int length = 1;
 
  224  for(
unsigned int i = 0; i < names.size(); ++i)
 
  226    length = length > names[i].length() ? length : names[i].length();
 
  230  for(
unsigned int i = 0; i < iterations_avg.size(); ++i)
 
  232    pcout << 
"  " << std::setw(length + 2) << std::left << names[i] << std::fixed
 
  233          << std::setprecision(2) << std::right << std::setw(6) << iterations_avg[i] << std::endl;
 
  239  SolverResult() : degree(1), dofs(1), n_10(0), tau_10(0.0)
 
  243  SolverResult(
unsigned int const                    degree_,
 
  244               dealii::types::global_dof_index 
const dofs_,
 
  246               double const                          tau_10_)
 
  247    : degree(degree_), dofs(dofs_), n_10(n_10_), tau_10(tau_10_)
 
  252  print_header(dealii::ConditionalOStream 
const & pcout)
 
  255    pcout << std::setw(7) << 
"degree";
 
  256    pcout << std::setw(15) << 
"dofs";
 
  257    pcout << std::setw(8) << 
"n_10";
 
  258    pcout << std::setw(15) << 
"tau_10";
 
  259    pcout << std::setw(15) << 
"throughput";
 
  263    pcout << std::setw(7) << 
" ";
 
  264    pcout << std::setw(15) << 
" ";
 
  265    pcout << std::setw(8) << 
" ";
 
  266    pcout << std::setw(15) << 
"in s*core/DoF";
 
  267    pcout << std::setw(15) << 
"in DoF/s/core";
 
  274  print(dealii::ConditionalOStream 
const & pcout)
 const 
  276    pcout << std::setw(7) << std::fixed << degree;
 
  277    pcout << std::setw(15) << std::fixed << dofs;
 
  278    pcout << std::setw(8) << std::fixed << std::setprecision(1) << n_10;
 
  279    pcout << std::setw(15) << std::scientific << std::setprecision(2) << tau_10;
 
  280    pcout << std::setw(15) << std::scientific << std::setprecision(2) << 1.0 / tau_10;
 
  285  dealii::types::global_dof_index dofs;
 
 
  291print_results(std::vector<SolverResult> 
const & results, MPI_Comm 
const & mpi_comm)
 
  294  dealii::ConditionalOStream pcout(std::cout,
 
  295                                   dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0);
 
  297  pcout << std::endl << print_horizontal_line() << std::endl << std::endl;
 
  299  pcout << 
"Summary of results:" << std::endl << std::endl;
 
  301  SolverResult::print_header(pcout);
 
  302  for(std::vector<SolverResult>::const_iterator it = results.begin(); it != results.end(); ++it)
 
  305  pcout << print_horizontal_line() << std::endl << std::endl;