LCOV - code coverage report
Current view: top level - src/vectorpostprocessors - HistogramVectorPostprocessor.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 57 59 96.6 %
Date: 2025-07-17 01:28:37 Functions: 7 7 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "HistogramVectorPostprocessor.h"
      11             : 
      12             : #include <algorithm>
      13             : 
      14             : registerMooseObject("MooseApp", HistogramVectorPostprocessor);
      15             : 
      16             : InputParameters
      17       14297 : HistogramVectorPostprocessor::validParams()
      18             : {
      19       14297 :   InputParameters params = GeneralVectorPostprocessor::validParams();
      20       14297 :   params.addClassDescription("Compute a histogram for each column of a VectorPostprocessor");
      21             : 
      22       14297 :   params.addRequiredParam<VectorPostprocessorName>(
      23             :       "vpp", "The VectorPostprocessor to compute histogram of");
      24             : 
      25       14297 :   params.addRequiredParam<unsigned int>("num_bins", "The number of bins for the histograms");
      26             : 
      27       14297 :   return params;
      28           0 : }
      29             : 
      30          16 : HistogramVectorPostprocessor::HistogramVectorPostprocessor(const InputParameters & parameters)
      31             :   : GeneralVectorPostprocessor(parameters),
      32          16 :     _vpp_name(getParam<VectorPostprocessorName>("vpp")),
      33          32 :     _num_bins(getParam<unsigned int>("num_bins"))
      34             : {
      35          16 : }
      36             : 
      37             : void
      38          16 : HistogramVectorPostprocessor::initialSetup()
      39             : {
      40          16 :   const VectorPostprocessor & vpp = getUserObjectByName<VectorPostprocessor>(_vpp_name);
      41          28 :   for (const auto & vec_name : vpp.getVectorNames())
      42          24 :     _histogram_data[vec_name] = {&declareVector(vec_name + "_lower"),
      43          24 :                                  &declareVector(vec_name + "_upper"),
      44          12 :                                  &declareVector(vec_name)};
      45          16 :   if (_histogram_data.empty())
      46           4 :     paramError("vpp", "The specified VectorPostprocessor does not have any declared vectors");
      47          12 : }
      48             : 
      49             : void
      50          11 : HistogramVectorPostprocessor::initialize()
      51             : {
      52             :   // no need to reset, execute() writes in place
      53          11 : }
      54             : 
      55             : void
      56          11 : HistogramVectorPostprocessor::execute()
      57             : {
      58          11 :   if (processor_id() == 0) // Only compute on processor 0
      59             :   {
      60           8 :     const VectorPostprocessor & vpp = getUserObjectByName<VectorPostprocessor>(_vpp_name);
      61          16 :     for (const auto & vec_name : vpp.getVectorNames())
      62             :     {
      63           8 :       const auto & values = _fe_problem.getVectorPostprocessorValueByName(_vpp_name, vec_name);
      64             : 
      65             :       mooseAssert(_histogram_data.count(vec_name), "Error retrieving VPP vector");
      66           8 :       auto & histo_data = _histogram_data.at(vec_name);
      67           8 :       computeHistogram(values, histo_data);
      68             :     }
      69             :   }
      70          11 : }
      71             : 
      72             : void
      73          11 : HistogramVectorPostprocessor::finalize()
      74             : {
      75          11 : }
      76             : 
      77             : void
      78           8 : HistogramVectorPostprocessor::computeHistogram(const std::vector<Real> & values,
      79             :                                                HistoData & histo_data)
      80             : {
      81           8 :   if (values.empty())
      82           0 :     mooseError("Cannot compute histogram without data!");
      83             : 
      84             :   // Grab the vectors to fill
      85           8 :   auto & lower_vector = *histo_data._lower;
      86           8 :   auto & upper_vector = *histo_data._upper;
      87           8 :   auto & histogram = *histo_data._histogram;
      88             : 
      89             :   // Resize everything
      90             :   // Note: no need to zero anything out
      91             :   // that will automatically be done if the bin should be zero by the algorithm below
      92           8 :   lower_vector.resize(_num_bins);
      93           8 :   upper_vector.resize(_num_bins);
      94           8 :   histogram.resize(_num_bins);
      95             : 
      96             :   // Create a sorted copy of the values
      97           8 :   std::vector<Real> sorted_values(values.size());
      98           8 :   std::partial_sort_copy(values.begin(), values.end(), sorted_values.begin(), sorted_values.end());
      99             : 
     100             :   // Get the min and max values
     101           8 :   auto min = sorted_values.front();
     102           8 :   auto max = sorted_values.back();
     103             : 
     104             :   // The bin stride/length
     105           8 :   auto bin_stride = (max - min) / static_cast<Real>(_num_bins);
     106             : 
     107           8 :   auto current_value_iter = sorted_values.begin();
     108           8 :   auto sorted_values_end = sorted_values.end();
     109             : 
     110             :   // Fill the bins
     111          40 :   for (unsigned int bin = 0; bin < _num_bins; bin++)
     112             :   {
     113             :     // Compute bin edges
     114             :     // These are computed individually on purpose so that the exact same values will match the
     115             :     // previous and next bins
     116          32 :     auto lower = (bin * bin_stride) + min;
     117          32 :     auto upper = ((bin + 1) * bin_stride) + min;
     118             : 
     119          32 :     lower_vector[bin] = lower;
     120          32 :     upper_vector[bin] = upper;
     121             : 
     122             :     // Find the number of values that fall in this bin
     123          32 :     unsigned long int num_values = 0;
     124         120 :     while (current_value_iter != sorted_values_end && *current_value_iter <= upper)
     125             :     {
     126          88 :       num_values++;
     127          88 :       current_value_iter++;
     128             :     }
     129             : 
     130          32 :     histogram[bin] = static_cast<Real>(num_values);
     131             :   }
     132           8 : }

Generated by: LCOV version 1.14