Quinoa all test code coverage report
Current view: top level - Walker - Distributor.cpp (source / functions) Hit Total Coverage
Commit: Quinoa_v0.3-957-gb4f0efae0 Lines: 282 311 90.7 %
Date: 2021-11-11 18:25:50 Functions: 20 22 90.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 299 578 51.7 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Walker/Distributor.cpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.
       7                 :            :              All rights reserved. See the LICENSE file for details.
       8                 :            :   \brief     Distributor drives the time integration of differential equations
       9                 :            :   \details   Distributor drives the time integration of differential equations.
      10                 :            :     The implementation uses the Charm++ runtime system and is fully asynchronous,
      11                 :            :     overlapping computation, communication as well as I/O. The algorithm
      12                 :            :     utilizes the structured dagger (SDAG) Charm++ functionality. The high-level
      13                 :            :     overview of the algorithm structure and how it interfaces with Charm++ is
      14                 :            :     discussed in the Charm++ interface file src/Walker/distributor.ci.
      15                 :            : */
      16                 :            : // *****************************************************************************
      17                 :            : 
      18                 :            : #include <list>
      19                 :            : #include <string>
      20                 :            : #include <algorithm>
      21                 :            : #include <functional>
      22                 :            : #include <iomanip>
      23                 :            : #include <iostream>
      24                 :            : #include <iterator>
      25                 :            : #include <limits>
      26                 :            : #include <cmath>
      27                 :            : #include <cstddef>
      28                 :            : 
      29                 :            : #include "NoWarning/format.hpp"
      30                 :            : 
      31                 :            : #include "Macro.hpp"
      32                 :            : #include "Print.hpp"
      33                 :            : #include "Tags.hpp"
      34                 :            : #include "StatCtr.hpp"
      35                 :            : #include "Exception.hpp"
      36                 :            : #include "Particles.hpp"
      37                 :            : #include "LoadDistributor.hpp"
      38                 :            : #include "Distributor.hpp"
      39                 :            : #include "Integrator.hpp"
      40                 :            : #include "DiffEqStack.hpp"
      41                 :            : #include "TxtStatWriter.hpp"
      42                 :            : #include "PDFReducer.hpp"
      43                 :            : #include "PDFWriter.hpp"
      44                 :            : #include "Options/PDFFile.hpp"
      45                 :            : #include "Options/PDFPolicy.hpp"
      46                 :            : #include "Walker/InputDeck/InputDeck.hpp"
      47                 :            : #include "NoWarning/walker.decl.h"
      48                 :            : 
      49                 :            : extern CProxy_Main mainProxy;
      50                 :            : 
      51                 :            : using walker::Distributor;
      52                 :            : 
      53                 :         74 : Distributor::Distributor() :
      54                 :            :   m_output( { false, false } ),
      55                 :            :   m_it( 0 ),
      56                 :            :   m_npar( 0 ),
      57                 :            :   m_t( 0.0 ),
      58                 :        148 :   m_dt( computedt() ),
      59                 :            :   m_intproxy(),
      60                 :            :   m_timer(),
      61                 :            :   m_nameOrdinary( g_inputdeck.momentNames( tk::ctr::ordinary ) ),
      62                 :            :   m_nameCentral( g_inputdeck.momentNames( tk::ctr::central ) ),
      63                 :          0 :   m_ordinary( m_nameOrdinary.size(), 0.0 ),
      64                 :          0 :   m_central( m_nameCentral.size(), 0.0 ),
      65                 :            :   m_ordupdf(),
      66                 :            :   m_ordbpdf(),
      67                 :            :   m_ordtpdf(),
      68                 :            :   m_cenupdf(),
      69                 :            :   m_cenbpdf(),
      70                 :            :   m_centpdf(),
      71                 :            :   m_tables(),
      72 [ +  - ][ +  - ]:         74 :   m_moments()
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
      73                 :            : // *****************************************************************************
      74                 :            : // Constructor
      75                 :            : // *****************************************************************************
      76                 :            : {
      77                 :            :   // Get command line object reference
      78                 :         74 :   const auto& cmd = g_inputdeck.get< tag::cmd >();
      79                 :            : 
      80                 :            :   // Compute load distribution given total work (= number of particles) and
      81                 :            :   // user-specified virtualization
      82                 :         74 :   uint64_t chunksize = 0, remainder = 0;
      83         [ +  - ]:        148 :   auto nchare = tk::linearLoadDistributor(
      84                 :         74 :                   cmd.get< tag::virtualization >(),
      85                 :         74 :                   g_inputdeck.get< tag::discr, tag::npar >(),
      86                 :            :                   CkNumPes(),
      87                 :            :                   chunksize,
      88                 :            :                   remainder );
      89 [ -  + ][ -  - ]:         74 :   Assert( chunksize != 0, "Chunksize must not be zero" );
         [ -  - ][ -  - ]
      90                 :            : 
      91                 :            :   // Compute total number of particles distributed over all workers. Note that
      92                 :            :   // this number will not necessarily be the same as given by the user, coming
      93                 :            :   // from g_inputdeck.get< tag::discr, tag::npar >(), since each Charm++ chare
      94                 :            :   // array element constructor takes this chunksize argument, which equals the
      95                 :            :   // number of particles the array element (worker) will work on.
      96                 :         74 :   m_npar = static_cast< tk::real >( nchare * chunksize );
      97                 :            : 
      98         [ +  - ]:        148 :   auto print = printer();
      99                 :            : 
     100                 :            :   // Print out info on what will be done and how
     101         [ +  - ]:         74 :   info( print, chunksize, nchare );
     102                 :            : 
     103                 :            :   // Output header for statistics output file
     104 [ +  + ][ -  + ]:         74 :   tk::TxtStatWriter sw( !m_nameOrdinary.empty() || !m_nameCentral.empty() ?
                 [ +  - ]
     105                 :            :                         cmd.get< tag::io, tag::stat >() :
     106                 :            :                         std::string(),
     107                 :         74 :                         g_inputdeck.get< tag::flformat, tag::stat >(),
     108         [ +  - ]:        222 :                         g_inputdeck.get< tag::prec, tag::stat >() );
     109         [ +  - ]:         74 :   sw.header( m_nameOrdinary, m_nameCentral, m_tables.first );
     110                 :            : 
     111                 :            :   // Print out time integration header
     112         [ +  - ]:         74 :   print.endsubsection();
     113 [ +  - ][ +  - ]:         74 :   print.diag( "Starting time stepping ..." );
     114         [ +  - ]:         74 :   header( print );
     115                 :            : 
     116                 :            :   // Start timer measuring total integration time
     117         [ +  - ]:         74 :   m_timer.emplace_back();
     118                 :            : 
     119                 :            :   // Construct and initialize map of statistical moments
     120         [ +  + ]:       1318 :   for (const auto& product : g_inputdeck.get< tag::stat >())
     121         [ +  - ]:       1244 :     m_moments[ product ] = 0.0;
     122                 :            : 
     123                 :            :   // Activate SDAG-wait for estimation of ordinary statistics
     124         [ +  - ]:         74 :   thisProxy.wait4ord();
     125                 :            :   // Activate SDAG-wait for estimation of PDFs at select times
     126         [ +  - ]:         74 :   thisProxy.wait4pdf();
     127                 :            : 
     128                 :            :   // Create statistics merger chare group collecting chare contributions
     129         [ +  - ]:        148 :   CProxy_Collector collproxy = CProxy_Collector::ckNew( thisProxy );
     130                 :            : 
     131                 :            :   // Create partcle writer Charm++ chare nodegroup
     132                 :            :   tk::CProxy_ParticleWriter particlewriter =
     133         [ +  - ]:         74 :     tk::CProxy_ParticleWriter::ckNew( cmd.get< tag::io, tag::particles >() );
     134                 :            : 
     135                 :            :   // Fire up asynchronous differential equation integrators
     136                 :            :   m_intproxy =
     137                 :          0 :     CProxy_Integrator::ckNew( thisProxy, collproxy, particlewriter, chunksize,
     138 [ +  - ][ +  - ]:         74 :                               static_cast<int>( nchare ) );
     139                 :         74 : }
     140                 :            : 
     141                 :            : void
     142                 :         74 : Distributor::info( const WalkerPrint& print,
     143                 :            :                    uint64_t chunksize,
     144                 :            :                    std::size_t nchare )
     145                 :            : // *****************************************************************************
     146                 :            : //  Print information at startup
     147                 :            : //! \param[in] print Pretty printer object to use for printing
     148                 :            : //! \param[in] chunksize Chunk size, see Base/LoadDistribution.h
     149                 :            : //! \param[in] nchare Total number of Charem++ Integrator chares doing work
     150                 :            : // *****************************************************************************
     151                 :            : {
     152                 :            :   // Get command line object reference
     153                 :         74 :   const auto& cmd = g_inputdeck.get< tag::cmd >();
     154                 :            : 
     155 [ +  - ][ +  - ]:         74 :   print.part( "Factory" );
     156                 :            : 
     157                 :            :   // Print out info data layout
     158 [ +  - ][ +  - ]:         74 :   print.list( "Particle properties data layout (CMake: PARTICLE_DATA_LAYOUT)",
     159 [ +  - ][ +  - ]:        222 :               std::list< std::string >{ tk::Particles::layout() } );
         [ +  + ][ -  - ]
     160                 :            : 
     161                 :            :   // Re-create differential equations stack for output
     162         [ +  - ]:         74 :   DiffEqStack stack;
     163                 :            : 
     164         [ +  - ]:         74 :   print.endpart();
     165                 :            : 
     166                 :            :   // Instantiate tables to sample and output to statistics file
     167         [ +  - ]:         74 :   m_tables = stack.tables();
     168                 :            : 
     169                 :            :   // Print out information on problem
     170 [ +  - ][ +  - ]:         74 :   print.part( "Problem" );
     171                 :            : 
     172                 :            :   // Print out info on problem title
     173         [ +  - ]:         74 :   if ( !g_inputdeck.get< tag::title >().empty() )
     174         [ +  - ]:         74 :     print.title( g_inputdeck.get< tag::title >() );
     175                 :            : 
     176                 :            :   // Print out info on settings of selected differential equations
     177 [ +  - ][ +  - ]:         74 :   print.diffeqs( "Differential equations integrated", stack.info() );
                 [ +  - ]
     178                 :            : 
     179                 :            :   // Print out info on RNGs selected
     180                 :            :   // ...
     181                 :            : 
     182                 :            :   // Print I/O filenames
     183 [ +  - ][ +  - ]:         74 :   print.section( "Output filenames" );
     184         [ +  + ]:         74 :   if (!g_inputdeck.get< tag::stat >().empty())
     185 [ +  - ][ +  - ]:         72 :     print.item( "Statistics", cmd.get< tag::io, tag::stat >() );
     186         [ +  + ]:         74 :   if (!g_inputdeck.get< tag::pdf >().empty())
     187 [ +  - ][ +  - ]:         13 :     print.item( "PDF", cmd.get< tag::io, tag::pdf >() );
     188         [ +  + ]:         74 :   if (!g_inputdeck.get< tag::param, tag::position, tag::depvar >().empty())
     189 [ +  - ][ +  - ]:          6 :     print.item( "Particle positions", cmd.get< tag::io, tag::particles >() );
     190                 :            : 
     191                 :            :   // Print discretization parameters
     192 [ +  - ][ +  - ]:         74 :   print.section( "Discretization parameters" );
     193 [ +  - ][ +  - ]:         74 :   print.item( "Number of time steps",
     194                 :         74 :               g_inputdeck.get< tag::discr, tag::nstep >() );
     195 [ +  - ][ +  - ]:         74 :   print.item( "Terminate time",
     196                 :         74 :               g_inputdeck.get< tag::discr, tag::term >() );
     197 [ +  - ][ +  - ]:         74 :   print.item( "Initial time step size",
     198                 :         74 :               g_inputdeck.get< tag::discr, tag::dt >() );
     199                 :            : 
     200                 :            :   // Print output intervals
     201 [ +  - ][ +  - ]:         74 :   print.section( "Output intervals" );
     202                 :         74 :   const auto& interval = g_inputdeck.get< tag::output, tag::iter >();
     203 [ +  - ][ +  - ]:         74 :   print.item( "TTY", interval.get< tag::tty >() );
     204         [ +  + ]:         74 :   if (!g_inputdeck.get< tag::stat >().empty())
     205 [ +  - ][ +  - ]:         72 :     print.item( "Statistics", interval.get< tag::stat >() );
     206         [ +  + ]:         74 :   if (!g_inputdeck.get< tag::pdf >().empty())
     207 [ +  - ][ +  - ]:         13 :     print.item( "PDF", interval.get< tag::pdf >() );
     208         [ +  + ]:         74 :   if (!g_inputdeck.get< tag::param, tag::position, tag::depvar >().empty())
     209 [ +  - ][ +  - ]:          6 :     print.item( "Particles", interval.get< tag::particles >() );
     210                 :            : 
     211                 :            :   // Print out statistics estimated
     212 [ +  - ][ +  - ]:         74 :   print.statistics( "Statistical moments and distributions" );
     213                 :            : 
     214                 :            :   // Print out info on load distirubtion
     215 [ +  - ][ +  - ]:         74 :   print.section( "Load distribution" );
     216 [ +  - ][ +  - ]:         74 :   print.item( "Virtualization [0.0...1.0]",
     217                 :         74 :               g_inputdeck.get< tag::cmd, tag::virtualization >() );
     218 [ +  - ][ +  - ]:         74 :   print.item( "Number of work units", nchare );
     219 [ +  - ][ +  - ]:         74 :   print.item( "User load (# of particles)",
     220                 :         74 :               g_inputdeck.get< tag::discr, tag::npar >() );
     221 [ +  - ][ +  - ]:         74 :   print.item( "Chunksize (load per work unit)", chunksize );
     222 [ +  - ][ +  - ]:         74 :   print.item( "Actual load (# of particles)",
     223 [ +  - ][ +  - ]:        148 :               std::to_string( nchare * chunksize ) +
     224         [ +  - ]:        148 :               " (=" +
     225 [ +  - ][ +  - ]:        296 :               std::to_string( nchare ) + "*" +
                 [ +  - ]
     226 [ +  - ][ +  - ]:        296 :               std::to_string( chunksize ) + ")" );
     227                 :         74 : }
     228                 :            : 
     229                 :            : tk::real
     230                 :     406886 : Distributor::computedt()
     231                 :            : // *****************************************************************************
     232                 :            : // Compute size of next time step
     233                 :            : //! \return Size of dt for the next time step
     234                 :            : // *****************************************************************************
     235                 :            : {
     236                 :            :   // Simply return a constant user-defined dt for now
     237                 :     406886 :   return g_inputdeck.get< tag::discr, tag::dt >();
     238                 :            : }
     239                 :            : 
     240                 :            : void
     241                 :     406812 : Distributor::estimateOrd( tk::real* ord, [[maybe_unused]] int n )
     242                 :            : // *****************************************************************************
     243                 :            : // Estimate ordinary moments
     244                 :            : //! \param[in] ord Ordinary moments (sum) collected over all chares
     245                 :            : //! \param[in] n Number of ordinary moments in array ord
     246                 :            : // *****************************************************************************
     247                 :            : {
     248 [ -  + ][ -  - ]:     406812 :   Assert( static_cast<std::size_t>(n) == m_ordinary.size(),
         [ -  - ][ -  - ]
     249                 :            :           "Number of ordinary moments contributed not equal to expected" );
     250                 :            : 
     251                 :            :   // Add contribution from PE to total sums, i.e., u[i] += v[i] for all i
     252         [ +  + ]:    2679974 :   for (std::size_t i=0; i<m_ordinary.size(); ++i) m_ordinary[i] += ord[i];
     253                 :            : 
     254                 :            :   // Finish computing moments, i.e., divide sums by the number of samples
     255                 :            :   // cppcheck-suppress useStlAlgorithm
     256         [ +  + ]:    2679974 :   for (auto& m : m_ordinary) m /= m_npar;
     257                 :            : 
     258                 :            :   // Activate SDAG trigger signaling that ordinary moments have been estimated
     259                 :     406812 :   estimateOrdDone();
     260                 :     406812 : }
     261                 :            : 
     262                 :            : void
     263                 :     406812 : Distributor::estimateCen( tk::real* cen, [[maybe_unused]] int n )
     264                 :            : // *****************************************************************************
     265                 :            : // Estimate ordinary moments
     266                 :            : //! \param[in] cen Central moments (sum) collected over all chares
     267                 :            : //! \param[in] n Number of central moments in array cen
     268                 :            : // *****************************************************************************
     269                 :            : {
     270 [ -  + ][ -  - ]:     406812 :   Assert( static_cast<std::size_t>(n) == m_central.size(),
         [ -  - ][ -  - ]
     271                 :            :           "Number of central moments contributed not equal to expected" );
     272                 :            : 
     273                 :            :   // Add contribution from PE to total sums, i.e., u[i] += v[i] for all i
     274         [ +  + ]:    4950270 :   for (std::size_t i=0; i<m_central.size(); ++i) m_central[i] += cen[i];
     275                 :            : 
     276                 :            :   // Finish computing moments, i.e., divide sums by the number of samples
     277                 :            :   // cppcheck-suppress useStlAlgorithm
     278         [ +  + ]:    4950270 :   for (auto& m : m_central) m /= m_npar;
     279                 :            : 
     280                 :            :   // Activate SDAG trigger signaling that central moments have been estimated
     281                 :     406812 :   estimateCenDone();
     282                 :     406812 : }
     283                 :            : 
     284                 :            : void
     285                 :     406812 : Distributor::estimateOrdPDF( CkReductionMsg* msg )
     286                 :            : // *****************************************************************************
     287                 :            : // Estimate ordinary PDFs
     288                 :            : //! \param[in] msg Serialized vectors of uni-, bi-, and tri-variate PDFs
     289                 :            : // *****************************************************************************
     290                 :            : {
     291                 :            :   // Deserialize final PDFs
     292                 :     813624 :   PUP::fromMem creator( msg->getData() );
     293         [ +  - ]:     406812 :   creator | m_ordupdf;
     294         [ +  - ]:     406812 :   creator | m_ordbpdf;
     295         [ +  - ]:     406812 :   creator | m_ordtpdf;
     296                 :            : 
     297 [ +  - ][ +  - ]:     406812 :   delete msg;
     298                 :            : 
     299                 :            :   // Activate SDAG trigger signaling that ordinary PDFs have been estimated
     300         [ +  - ]:     406812 :   estimateOrdPDFDone();
     301                 :     406812 : }
     302                 :            : 
     303                 :            : void
     304                 :     406812 : Distributor::estimateCenPDF( CkReductionMsg* msg )
     305                 :            : // *****************************************************************************
     306                 :            : // Estimate central PDFs
     307                 :            : //! \param[in] msg Serialized vectors of uni-, bi-, and tri-variate PDFs
     308                 :            : // *****************************************************************************
     309                 :            : {
     310                 :            :   // Deserialize final PDFs
     311                 :     813624 :   PUP::fromMem creator( msg->getData() );
     312         [ +  - ]:     406812 :   creator | m_cenupdf;
     313         [ +  - ]:     406812 :   creator | m_cenbpdf;
     314         [ +  - ]:     406812 :   creator | m_centpdf;
     315                 :            : 
     316 [ +  - ][ +  - ]:     406812 :   delete msg;
     317                 :            : 
     318                 :            :   // Activate SDAG trigger signaling that central PDFs have been estimated
     319         [ +  - ]:     406812 :   estimateCenPDFDone();
     320                 :     406812 : }
     321                 :            : 
     322                 :            : void
     323                 :     406812 : Distributor::outStat()
     324                 :            : // *****************************************************************************
     325                 :            : // Output statistics to file
     326                 :            : // *****************************************************************************
     327                 :            : {
     328                 :            :   // lambda to sample tables to write to statistics file
     329                 :     977476 :   auto extra = [this]() -> std::vector< tk::real > {
     330         [ +  - ]:     325792 :     std::vector< tk::real > x( m_tables.second.size() );
     331                 :     325792 :     std::size_t j = 0;
     332 [ +  + ][ +  - ]:     325892 :     for (const auto& t : m_tables.second) x[ j++ ] = tk::sample<1>(m_t,t)[0];
     333                 :     325792 :     return x;
     334                 :     406812 :   };
     335                 :            : 
     336                 :            :   // Append statistics file at selected times
     337         [ +  + ]:     406812 :   if (!((m_it+1) % g_inputdeck.get< tag::output, tag::iter, tag::stat >())) {
     338 [ +  + ][ -  + ]:     631582 :     tk::TxtStatWriter sw( !m_nameOrdinary.empty() || !m_nameCentral.empty() ?
                 [ +  - ]
     339                 :     305790 :                           g_inputdeck.get< tag::cmd, tag::io, tag::stat >() :
     340                 :            :                           std::string(),
     341                 :     325792 :                           g_inputdeck.get< tag::flformat, tag::stat >(),
     342                 :     325792 :                           g_inputdeck.get< tag::prec, tag::stat >(),
     343         [ +  - ]:     977376 :                           std::ios_base::app );
     344 [ +  - ][ +  - ]:     325792 :     if (sw.stat( m_it, m_t, m_ordinary, m_central, extra() ))
                 [ +  + ]
     345                 :     305790 :       m_output.get< tag::stat >() = true;
     346                 :            :   }
     347                 :     406812 : }
     348                 :            : 
     349                 :            : void
     350                 :     406812 : Distributor::outPDF()
     351                 :            : // *****************************************************************************
     352                 :            : // Output PDFs to file
     353                 :            : // *****************************************************************************
     354                 :            : {
     355                 :     406812 :   const auto term = g_inputdeck.get< tag::discr, tag::term >();
     356                 :     406812 :   const auto eps = std::numeric_limits< tk::real >::epsilon();
     357                 :     406812 :   const auto nstep = g_inputdeck.get< tag::discr, tag::nstep >();
     358                 :     406812 :   const auto pdffreq = g_inputdeck.get< tag::output, tag::iter, tag::pdf >();
     359                 :            : 
     360                 :            :   // output PDFs at t=0 (regardless of whether it was requested), or at
     361                 :            :   // selected times, or in the last time step (regardless of whether it was
     362                 :            :   // requested
     363         [ +  + ]:     406812 :   if ( m_it == 0 ||
     364         [ +  + ]:     406738 :        !((m_it+1) % pdffreq) ||
     365 [ +  - ][ +  + ]:      42886 :        (std::fabs(m_t+m_dt-term) < eps || (m_it+1) >= nstep) )
     366                 :            :   {
     367                 :            :     // Generate iteration count and physical time for PDF output. In the first
     368                 :            :     // iteration, the particles are NOT advanced, see Integration::advance(),
     369                 :            :     // and we write it=0 and time=0.0 into the PDF files. For the rest of the
     370                 :            :     // iterations we write the iteration count and the physical time
     371                 :            :     // corresponding to the iteration just completed.
     372         [ +  + ]:     363932 :     auto it = m_it == 0 ? m_it : m_it + 1;
     373         [ +  + ]:     363932 :     auto t = m_it == 0 ? m_t : m_t + m_dt;
     374                 :            : 
     375                 :     363932 :     outUniPDF( it, t );                 // Output univariate PDFs to file(s)
     376                 :     363932 :     outBiPDF( it, t );                  // Output bivariate PDFs to file(s)
     377                 :     363932 :     outTriPDF( it, t );                 // Output trivariate PDFs to file(s)
     378                 :     363932 :     m_output.get< tag::pdf >() = true;  // Signal that PDFs were written
     379                 :            :   }
     380                 :     406812 : }
     381                 :            : 
     382                 :            : void
     383                 :         28 : Distributor::writeUniPDF( std::uint64_t it,
     384                 :            :                           tk::real t,
     385                 :            :                           const tk::UniPDF& p,
     386                 :            :                           tk::ctr::Moment m,
     387                 :            :                           std::size_t idx )
     388                 :            : // *****************************************************************************
     389                 :            : // Write univariate PDF to file
     390                 :            : //! \param[in] it Iteration count to write in output file
     391                 :            : //! \param[in] t Physical time to write in output file
     392                 :            : //! \param[in] p Univariate PDF to output
     393                 :            : //! \param[in] m ORDINARY or CENTRAL PDF we are writing
     394                 :            : //! \param[in] idx Index of the PDF of all ordinary or central PDFs requested
     395                 :            : // *****************************************************************************
     396                 :            : {
     397                 :            :   // Get PDF metadata
     398                 :            :   const auto nfo =
     399                 :         28 :     tk::ctr::pdfInfo< 1 >( g_inputdeck.get< tag::discr, tag::binsize >(),
     400                 :         28 :                            g_inputdeck.get< tag::cmd, tag::io, tag::pdfnames >(),
     401                 :         28 :                            g_inputdeck.get< tag::discr, tag::extent >(),
     402                 :         28 :                            g_inputdeck.get< tag::pdf >(),
     403                 :            :                            m,
     404                 :            :                            idx,
     405                 :            :                            it,
     406         [ +  - ]:         56 :                            t );
     407                 :            : 
     408                 :            :   // Construct PDF file name: base name + '_' + pdf name
     409                 :            :   std::string filename =
     410 [ +  - ][ +  - ]:         56 :     g_inputdeck.get< tag::cmd, tag::io, tag::pdf >() + '_' + nfo.name;
     411                 :            : 
     412                 :            :   // Augment PDF filename by time stamp if PDF output file policy is multiple
     413         [ -  + ]:         28 :   if (g_inputdeck.get< tag::selected, tag::pdfpolicy >() ==
     414                 :            :       tk::ctr::PDFPolicyType::MULTIPLE)
     415 [ -  - ][ -  - ]:          0 :     filename += '_' + std::to_string( m_t );
                 [ -  - ]
     416                 :            : 
     417                 :            :   // Augment PDF filename by '.txt' extension
     418         [ +  - ]:         28 :   filename += ".txt";
     419                 :            : 
     420                 :            :   // Create new PDF file (overwrite if exists)
     421                 :            :   tk::PDFWriter pdfw( filename,
     422                 :         28 :                       g_inputdeck.get< tag::flformat, tag::pdf >(),
     423         [ +  - ]:         56 :                       g_inputdeck.get< tag::prec, tag::pdf >() );
     424                 :            : 
     425                 :            :   // Output PDF
     426         [ +  - ]:         28 :   pdfw.writeTxt( p, nfo );
     427                 :         28 : }
     428                 :            : 
     429                 :            : void
     430                 :          8 : Distributor::writeBiPDF( std::uint64_t it,
     431                 :            :                          tk::real t,
     432                 :            :                          const tk::BiPDF& p,
     433                 :            :                          tk::ctr::Moment m,
     434                 :            :                          std::size_t idx )
     435                 :            : // *****************************************************************************
     436                 :            : // Write bivariate PDF to file
     437                 :            : //! \param[in] it Iteration count to write in output file
     438                 :            : //! \param[in] t Physical time to write in output file
     439                 :            : //! \param[in] p Bivariate PDF to output
     440                 :            : //! \param[in] m ORDINARY or CENTRAL PDF we are writing
     441                 :            : //! \param[in] idx Index of the PDF of all ordinary or central PDFs requested
     442                 :            : // *****************************************************************************
     443                 :            : {
     444                 :            :   // Get PDF metadata
     445                 :            :   const auto nfo =
     446                 :          8 :     tk::ctr::pdfInfo< 2 >( g_inputdeck.get< tag::discr, tag::binsize >(),
     447                 :          8 :                            g_inputdeck.get< tag::cmd, tag::io, tag::pdfnames >(),
     448                 :          8 :                            g_inputdeck.get< tag::discr, tag::extent >(),
     449                 :          8 :                            g_inputdeck.get< tag::pdf >(),
     450                 :            :                            m,
     451                 :            :                            idx,
     452                 :            :                            it,
     453         [ +  - ]:         16 :                            t );
     454                 :            : 
     455                 :            :   // Construct PDF file name: base name + '_' + pdf name
     456                 :            :   std::string filename =
     457 [ +  - ][ +  - ]:         16 :     g_inputdeck.get< tag::cmd, tag::io, tag::pdf >() + '_' + nfo.name;
     458                 :            : 
     459                 :            :   // Augment PDF filename by time stamp if PDF output file policy is multiple
     460         [ -  + ]:          8 :   if (g_inputdeck.get< tag::selected, tag::pdfpolicy >() ==
     461                 :            :       tk::ctr::PDFPolicyType::MULTIPLE)
     462 [ -  - ][ -  - ]:          0 :     filename += '_' + std::to_string( m_t );
                 [ -  - ]
     463                 :            : 
     464                 :          8 :   const auto& filetype = g_inputdeck.get< tag::selected, tag::filetype >();
     465                 :            : 
     466                 :            :   // Augment PDF filename by the appropriate extension
     467         [ +  + ]:          8 :   if (filetype == tk::ctr::PDFFileType::TXT)
     468         [ +  - ]:          6 :     filename += ".txt";
     469         [ +  - ]:          2 :   else if (filetype == tk::ctr::PDFFileType::GMSHTXT ||
     470         [ -  + ]:          2 :            filetype == tk::ctr::PDFFileType::GMSHBIN )
     471         [ -  - ]:          0 :     filename += ".gmsh";
     472         [ +  - ]:          2 :   else if (filetype == tk::ctr::PDFFileType::EXODUSII)
     473         [ +  - ]:          2 :     filename += ".exo";
     474 [ -  - ][ -  - ]:          0 :   else Throw( "Unkown PDF file type attempting to output bivariate PDF" );
                 [ -  - ]
     475                 :            : 
     476                 :            :   // Create new PDF file (overwrite if exists)
     477                 :            :   tk::PDFWriter pdfw( filename,
     478                 :          8 :                       g_inputdeck.get< tag::flformat, tag::pdf >(),
     479         [ +  - ]:         16 :                       g_inputdeck.get< tag::prec, tag::pdf >() );
     480                 :            : 
     481                 :            :   // Output PDF
     482         [ +  + ]:          8 :   if (filetype == tk::ctr::PDFFileType::TXT)
     483         [ +  - ]:          6 :     pdfw.writeTxt( p, nfo );
     484         [ -  + ]:          2 :   else if (filetype == tk::ctr::PDFFileType::GMSHTXT)
     485         [ -  - ]:          0 :     pdfw.writeGmshTxt( p, nfo,
     486                 :          0 :                        g_inputdeck.get< tag::selected, tag::pdfctr >() );
     487         [ -  + ]:          2 :   else if (filetype == tk::ctr::PDFFileType::GMSHBIN)
     488         [ -  - ]:          0 :     pdfw.writeGmshBin( p, nfo,
     489                 :          0 :                        g_inputdeck.get< tag::selected, tag::pdfctr >() );
     490         [ +  - ]:          2 :   else if (filetype == tk::ctr::PDFFileType::EXODUSII)
     491         [ +  - ]:          2 :     pdfw.writeExodusII( p, nfo,
     492                 :          2 :                         g_inputdeck.get< tag::selected, tag::pdfctr >() );
     493                 :          8 : }
     494                 :            : 
     495                 :            : void
     496                 :          8 : Distributor::writeTriPDF( std::uint64_t it,
     497                 :            :                           tk::real t,
     498                 :            :                           const tk::TriPDF& p,
     499                 :            :                           tk::ctr::Moment m,
     500                 :            :                           std::size_t idx )
     501                 :            : // *****************************************************************************
     502                 :            : // Write trivariate PDF to file
     503                 :            : //! \param[in] it Iteration count to write in output file
     504                 :            : //! \param[in] t Physical time to write in output file
     505                 :            : //! \param[in] p Trivariate PDF to output
     506                 :            : //! \param[in] m ORDINARY or CENTRAL PDF we are writing
     507                 :            : //! \param[in] idx Index of the PDF of all ordinary or central PDFs requested
     508                 :            : // *****************************************************************************
     509                 :            : {
     510                 :            :   // Get PDF metadata
     511                 :            :   const auto nfo =
     512                 :          8 :     tk::ctr::pdfInfo< 3 >( g_inputdeck.get< tag::discr, tag::binsize >(),
     513                 :          8 :                            g_inputdeck.get< tag::cmd, tag::io, tag::pdfnames >(),
     514                 :          8 :                            g_inputdeck.get< tag::discr, tag::extent >(),
     515                 :          8 :                            g_inputdeck.get< tag::pdf >(),
     516                 :            :                            m,
     517                 :            :                            idx,
     518                 :            :                            it,
     519         [ +  - ]:         16 :                            t );
     520                 :            : 
     521                 :            :   // Construct PDF file name: base name + '_' + pdf name
     522                 :            :   std::string filename =
     523 [ +  - ][ +  - ]:         16 :     g_inputdeck.get< tag::cmd, tag::io, tag::pdf >() + '_' + nfo.name;
     524                 :            : 
     525                 :            :   // Augment PDF filename by time stamp if PDF output file policy is multiple
     526         [ -  + ]:          8 :   if (g_inputdeck.get< tag::selected, tag::pdfpolicy >() ==
     527                 :            :       tk::ctr::PDFPolicyType::MULTIPLE)
     528 [ -  - ][ -  - ]:          0 :     filename += '_' + std::to_string( m_t );
                 [ -  - ]
     529                 :            : 
     530                 :          8 :   const auto& filetype = g_inputdeck.get< tag::selected, tag::filetype >();
     531                 :            : 
     532                 :            :   // Augment PDF filename by the appropriate extension
     533         [ +  + ]:          8 :   if (filetype == tk::ctr::PDFFileType::TXT)
     534         [ +  - ]:          4 :     filename += ".txt";
     535         [ +  - ]:          4 :   else if (filetype == tk::ctr::PDFFileType::GMSHTXT ||
     536         [ -  + ]:          4 :            filetype == tk::ctr::PDFFileType::GMSHBIN )
     537         [ -  - ]:          0 :     filename += ".gmsh";
     538         [ +  - ]:          4 :   else if (filetype == tk::ctr::PDFFileType::EXODUSII)
     539         [ +  - ]:          4 :     filename += ".exo";
     540 [ -  - ][ -  - ]:          0 :   else Throw( "Unkown PDF file type attempting to output trivariate PDF" );
                 [ -  - ]
     541                 :            : 
     542                 :            :   // Create new PDF file (overwrite if exists)
     543                 :            :   tk::PDFWriter pdfw( filename,
     544                 :          8 :                       g_inputdeck.get< tag::flformat, tag::pdf >(),
     545         [ +  - ]:         16 :                       g_inputdeck.get< tag::prec, tag::pdf >() );
     546                 :            : 
     547                 :            :   // Output PDF
     548         [ +  + ]:          8 :   if (filetype == tk::ctr::PDFFileType::TXT)
     549         [ +  - ]:          4 :     pdfw.writeTxt( p, nfo );
     550         [ -  + ]:          4 :   else if (filetype == tk::ctr::PDFFileType::GMSHTXT)
     551         [ -  - ]:          0 :      pdfw.writeGmshTxt( p, nfo,
     552                 :          0 :                         g_inputdeck.get< tag::selected, tag::pdfctr >() );
     553         [ -  + ]:          4 :   else if (filetype == tk::ctr::PDFFileType::GMSHBIN)
     554         [ -  - ]:          0 :      pdfw.writeGmshBin( p, nfo,
     555                 :          0 :                         g_inputdeck.get< tag::selected, tag::pdfctr >() );
     556         [ +  - ]:          4 :   else if (filetype == tk::ctr::PDFFileType::EXODUSII)
     557         [ +  - ]:          4 :     pdfw.writeExodusII( p, nfo,
     558                 :          4 :                         g_inputdeck.get< tag::selected, tag::pdfctr >() );
     559                 :          8 : }
     560                 :            : 
     561                 :            : void
     562                 :     363932 : Distributor::outUniPDF( std::uint64_t it, tk::real t )
     563                 :            : // *****************************************************************************
     564                 :            : // Output all requested univariate PDFs to file(s)
     565                 :            : //! \param[in] it Iteration count to write in output file
     566                 :            : //! \param[in] t Physical time to write in output file
     567                 :            : // *****************************************************************************
     568                 :            : {
     569                 :     363932 :   std::size_t idx = 0;
     570         [ +  + ]:     363952 :   for (const auto& p : m_ordupdf)
     571         [ +  - ]:         20 :     writeUniPDF( it, t, p, tk::ctr::Moment::ORDINARY, idx++ );
     572                 :     363932 :   idx = 0;
     573         [ +  + ]:     363940 :   for (const auto& p : m_cenupdf)
     574         [ +  - ]:          8 :     writeUniPDF( it, t, p, tk::ctr::Moment::CENTRAL, idx++ );
     575                 :     363932 : }
     576                 :            : 
     577                 :            : void
     578                 :     363932 : Distributor::outBiPDF( std::uint64_t it, tk::real t )
     579                 :            : // *****************************************************************************
     580                 :            : // Output all requested bivariate PDFs to file(s)
     581                 :            : //! \param[in] it Iteration count to write in output file
     582                 :            : //! \param[in] t Physical time to write in output file
     583                 :            : //! \return Number of PDFs written
     584                 :            : // *****************************************************************************
     585                 :            : {
     586                 :     363932 :   std::size_t idx = 0;
     587         [ +  + ]:     363936 :   for (const auto& p : m_ordbpdf)
     588         [ +  - ]:          4 :     writeBiPDF( it, t, p, tk::ctr::Moment::ORDINARY, idx++ );
     589                 :     363932 :   idx = 0;
     590         [ +  + ]:     363936 :   for (const auto& p : m_cenbpdf) {
     591         [ +  - ]:          4 :     writeBiPDF( it, t, p, tk::ctr::Moment::CENTRAL, idx++ );
     592                 :            :   }
     593                 :     363932 : }
     594                 :            : 
     595                 :            : void
     596                 :     363932 : Distributor::outTriPDF( std::uint64_t it, tk::real t )
     597                 :            : // *****************************************************************************
     598                 :            : // Output all requested trivariate PDFs to file(s)
     599                 :            : //! \param[in] it Iteration count to write in output file
     600                 :            : //! \param[in] t Physical time to write in output file
     601                 :            : //! \return Number of PDFs written
     602                 :            : // *****************************************************************************
     603                 :            : {
     604                 :     363932 :   std::size_t idx = 0;
     605         [ +  + ]:     363936 :   for (const auto& p : m_ordtpdf) {
     606         [ +  - ]:          4 :     writeTriPDF( it, t, p, tk::ctr::Moment::ORDINARY, idx++ );
     607                 :            :   }
     608                 :     363932 :   idx = 0;
     609         [ +  + ]:     363936 :   for (const auto& p : m_centpdf) {
     610         [ +  - ]:          4 :     writeTriPDF( it, t, p, tk::ctr::Moment::CENTRAL, idx++ );
     611                 :            :   }
     612                 :     363932 : }
     613                 :            : 
     614                 :            : void
     615                 :     406812 : Distributor::evaluateTime()
     616                 :            : // *****************************************************************************
     617                 :            : // Evaluate time step, compute new time step size, decide if it is time to quit
     618                 :            : // *****************************************************************************
     619                 :            : {
     620                 :     406812 :   const auto term = g_inputdeck.get< tag::discr, tag::term >();
     621                 :     406812 :   const auto eps = std::numeric_limits< tk::real >::epsilon();
     622                 :     406812 :   const auto nstep = g_inputdeck.get< tag::discr, tag::nstep >();
     623                 :            : 
     624                 :            :   // Increase number of iterations taken
     625                 :     406812 :   ++m_it;
     626                 :            :   // Advance physical time
     627                 :     406812 :   m_t += m_dt;
     628                 :            :   // Truncate the size of last time step
     629         [ +  + ]:     406812 :   if (m_t > term) m_t = term;
     630                 :            :   // Compute size of next time step
     631                 :     406812 :   m_dt = computedt();
     632                 :            :   // Echo one-liner info on time step
     633                 :     406812 :   report();
     634                 :            : 
     635                 :            :   // Finish if either max iterations or max time reached 
     636 [ +  + ][ +  + ]:     406812 :   if ( std::fabs(m_t-term) > eps && m_it < nstep ) {
     637                 :            : 
     638         [ +  - ]:     406738 :     if (g_inputdeck.stat()) {
     639                 :            :       // Update map of statistical moments
     640                 :     406738 :       std::size_t ord = 0;
     641                 :     406738 :       std::size_t cen = 0;
     642         [ +  + ]:    7222114 :       for (const auto& product : g_inputdeck.get< tag::stat >())
     643 [ +  - ][ +  + ]:    6815376 :         if (tk::ctr::ordinary( product ))
     644         [ +  - ]:    2272649 :           m_moments[ product ] = m_ordinary[ ord++ ];
     645                 :            :         else
     646         [ +  - ]:    4542727 :           m_moments[ product ] = m_central[ cen++ ];
     647                 :            : 
     648                 :            :       // Zero statistics counters and accumulators
     649         [ +  - ]:     406738 :       std::fill( begin(m_ordinary), end(m_ordinary), 0.0 );
     650         [ +  - ]:     406738 :       std::fill( begin(m_central), end(m_central), 0.0 );
     651                 :            : 
     652                 :            :       // Re-activate SDAG-wait for estimation of ordinary stats for next step
     653                 :     406738 :       thisProxy.wait4ord();
     654                 :            :       // Re-activate SDAG-wait for estimation of PDFs for next step
     655                 :     406738 :       thisProxy.wait4pdf();
     656                 :            :     }
     657                 :            : 
     658                 :            :     // Continue with next time step with all integrators
     659                 :     406738 :     m_intproxy.advance( m_dt, m_t, m_it, m_moments );
     660                 :            : 
     661                 :         74 :   } else finish();
     662                 :     406812 : }
     663                 :            : 
     664                 :            : void
     665                 :         74 : Distributor::finish()
     666                 :            : // *****************************************************************************
     667                 :            : // Normal finish of time stepping
     668                 :            : // *****************************************************************************
     669                 :            : {
     670                 :            :   // Print out reason for stopping
     671                 :         74 :   const auto term = g_inputdeck.get< tag::discr, tag::term >();
     672                 :         74 :   const auto nstep = g_inputdeck.get< tag::discr, tag::nstep >();
     673                 :            : 
     674         [ +  - ]:        148 :   auto print = printer();
     675                 :            : 
     676         [ +  - ]:         74 :   print.endsubsection();
     677         [ +  + ]:         74 :   if (m_it >= g_inputdeck.get< tag::discr, tag::nstep >())
     678 [ +  - ][ +  - ]:          9 :      print.note( "Normal finish, maximum number of iterations reached: " +
     679         [ +  - ]:         18 :                  std::to_string( nstep ) );
     680                 :            :    else 
     681 [ +  - ][ +  - ]:         65 :      print.note( "Normal finish, maximum time reached: " +
     682         [ +  - ]:        130 :                  std::to_string( term ) );
     683                 :            : 
     684                 :            :   // Quit
     685         [ +  - ]:         74 :   mainProxy.finalize();
     686                 :         74 : }
     687                 :            : 
     688                 :            : void
     689                 :          0 : Distributor::nostat()
     690                 :            : // *****************************************************************************
     691                 :            : //  Charm++ reduction target enabling shortcutting sync points if no stats
     692                 :            : //! \details This reduction target is called if there are no statistics nor PDFs
     693                 :            : //!   to be estimated and thus some synchronization points can be skipped. Upon
     694                 :            : //!   this call we simply finish up the time step as usual.
     695                 :            : // *****************************************************************************
     696                 :            : {
     697                 :          0 :   evaluateTime();
     698                 :          0 : }
     699                 :            : 
     700                 :            : void
     701                 :         74 : Distributor::header( const WalkerPrint& print ) const
     702                 :            : // *****************************************************************************
     703                 :            : // Print out time integration header
     704                 :            : //! \param[in] print Pretty printer object to use for printing
     705                 :            : // *****************************************************************************
     706                 :            : {
     707 [ +  - ][ +  - ]:         74 :   print.inthead( "Time integration", "Differential equations testbed",
         [ +  - ][ +  - ]
                 [ +  - ]
     708                 :            :     "Legend: it - iteration count\n"
     709                 :            :     "         t - time\n"
     710                 :            :     "        dt - time step size\n"
     711                 :            :     "       ETE - estimated time elapsed (h:m:s)\n"
     712                 :            :     "       ETA - estimated time for accomplishment (h:m:s)\n"
     713                 :            :     "       out - status flags, legend:\n"
     714                 :            :     "             s - statistics output\n"
     715                 :            :     "             p - PDFs output\n"
     716                 :            :     "             x - particle positions output\n",
     717                 :            :     "\n      it             t            dt        ETE        ETA   out\n"
     718                 :            :       " ---------------------------------------------------------------\n" );
     719                 :         74 : }
     720                 :            : 
     721                 :            : void
     722                 :     406812 : Distributor::report()
     723                 :            : // *****************************************************************************
     724                 :            : // Print out one-liner report on time step
     725                 :            : // *****************************************************************************
     726                 :            : {
     727         [ +  + ]:     406812 :   if (!(m_it % g_inputdeck.get< tag::output, tag::iter, tag::tty >())) {
     728                 :            : 
     729                 :            :   const auto parfreq =
     730                 :       1566 :     g_inputdeck.get< tag::output, tag::iter, tag::particles >();
     731                 :            :   const auto poseq =
     732                 :       1566 :     !g_inputdeck.get< tag::param, tag::position, tag::depvar >().empty();
     733                 :            : 
     734                 :            :     // estimated time elapsed and for accomplishment
     735 [ +  - ][ +  - ]:       1566 :     tk::Timer::Watch ete, eta;
     736         [ +  - ]:       3132 :     m_timer[0].eta( g_inputdeck.get< tag::discr, tag::term >(), m_t,
     737                 :       1566 :                     g_inputdeck.get< tag::discr, tag::nstep >(), m_it,
     738                 :            :                     ete, eta );
     739                 :            : 
     740         [ +  - ]:       3132 :     auto print = printer();
     741                 :            : 
     742                 :            :     // Output one-liner
     743                 :       1566 :     print << std::setfill(' ') << std::setw(8) << m_it << "  "
     744                 :          0 :           << std::scientific << std::setprecision(6)
     745                 :          0 :           << std::setw(12) << m_t << "  "
     746                 :       1566 :           << m_dt << "  "
     747                 :          0 :           << std::setfill('0')
     748                 :          0 :           << std::setw(3) << ete.hrs.count() << ":"
     749                 :          0 :           << std::setw(2) << ete.min.count() << ":"
     750                 :          0 :           << std::setw(2) << ete.sec.count() << "  "
     751                 :          0 :           << std::setw(3) << eta.hrs.count() << ":"
     752                 :          0 :           << std::setw(2) << eta.min.count() << ":"
     753 [ +  - ][ +  - ]:       1566 :           << std::setw(2) << eta.sec.count() << "  ";
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     754                 :            : 
     755                 :            :     // Augment one-liner with output indicators
     756 [ +  + ][ +  - ]:       1566 :     if (m_output.get< tag::stat >()) print << 's';
     757 [ +  + ][ +  - ]:       1566 :     if (m_output.get< tag::pdf >()) print << 'p';
     758 [ +  + ][ -  + ]:       1566 :     if (poseq && !(m_it % parfreq)) print << 'x';
                 [ -  - ]
     759                 :            : 
     760                 :            :     // Reset output indicators
     761                 :       1566 :     m_output.get< tag::stat >() = false;
     762                 :       1566 :     m_output.get< tag::pdf >() = false;
     763                 :            : 
     764         [ +  - ]:       1566 :     print << std::endl;
     765                 :            :   }
     766                 :     406812 : }
     767                 :            : 
     768                 :            : #include "NoWarning/distributor.def.h"

Generated by: LCOV version 1.14