LCOV - code coverage report
Current view: top level - src/functions - PiecewiseMultiInterpolation.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 43 49 87.8 %
Date: 2025-07-17 01:28:37 Functions: 7 14 50.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 "MooseUtils.h"
      11             : #include "PiecewiseMultiInterpolation.h"
      12             : #include "GriddedData.h"
      13             : 
      14             : InputParameters
      15       43255 : PiecewiseMultiInterpolation::validParams()
      16             : {
      17       43255 :   InputParameters params = Function::validParams();
      18       43255 :   params.addParam<FileName>(
      19             :       "data_file",
      20             :       "File holding data for use with PiecewiseMultiInterpolation.  Format: any empty line and any "
      21             :       "line "
      22             :       "beginning with # are ignored, all other lines are assumed to contain relevant information.  "
      23             :       "The file must begin with specification of the grid.  This is done through lines containing "
      24             :       "the keywords: AXIS X; AXIS Y; AXIS Z; or AXIS T.  Immediately following the keyword line "
      25             :       "must be a space-separated line of real numbers which define the grid along the specified "
      26             :       "axis.  These data must be monotonically increasing.  After all the axes and their grids "
      27             :       "have been specified, there must be a line that is DATA.  Following that line, function "
      28             :       "values are given in the correct order (they may be on individual lines, or be "
      29             :       "space-separated on a number of lines).  When the function is evaluated, f[i,j,k,l] "
      30             :       "corresponds to the i + j*Ni + k*Ni*Nj + l*Ni*Nj*Nk data value.  Here i>=0 corresponding to "
      31             :       "the index along the first AXIS, j>=0 corresponding to the index along the second AXIS, etc, "
      32             :       "and Ni = number of grid points along the first AXIS, etc.");
      33       43255 :   return params;
      34           0 : }
      35             : 
      36         256 : PiecewiseMultiInterpolation::PiecewiseMultiInterpolation(const InputParameters & parameters)
      37             :   : Function(parameters),
      38         256 :     _gridded_data(std::make_unique<GriddedData>(getParam<FileName>("data_file"))),
      39         491 :     _dim(_gridded_data->getDim())
      40             : {
      41         235 :   _gridded_data->getAxes(_axes);
      42         235 :   _gridded_data->getGrid(_grid);
      43             : 
      44             :   // GriddedData does not require monotonicity of axes, but we do
      45         561 :   for (unsigned int i = 0; i < _dim; ++i)
      46        1621 :     for (unsigned int j = 1; j < _grid[i].size(); ++j)
      47        1295 :       if (_grid[i][j - 1] >= _grid[i][j])
      48           7 :         mooseError("PiecewiseMultiInterpolation needs monotonically-increasing axis data.  Axis ",
      49             :                    i,
      50             :                    " contains non-monotonicity at value ",
      51           7 :                    _grid[i][j]);
      52             : 
      53             :   // GriddedData does not demand that each axis is independent, but we do
      54         228 :   std::set<int> s(_axes.begin(), _axes.end());
      55         228 :   if (s.size() != _dim)
      56           7 :     mooseError(
      57             :         "PiecewiseMultiInterpolation needs the AXES to be independent.  Check the AXIS lines in "
      58             :         "your data file.");
      59         221 : }
      60             : 
      61         221 : PiecewiseMultiInterpolation::~PiecewiseMultiInterpolation() {}
      62             : 
      63             : template <bool is_ad>
      64             : Moose::GenericType<PiecewiseMultiInterpolation::GridPoint, is_ad>
      65     1202000 : PiecewiseMultiInterpolation::pointInGrid(const Moose::GenericType<Real, is_ad> & t,
      66             :                                          const Moose::GenericType<Point, is_ad> & p) const
      67             : {
      68             :   // convert the inputs to an input to the sample function using _axes
      69     1202000 :   Moose::GenericType<GridPoint, is_ad> point_in_grid(_dim);
      70     4800208 :   for (unsigned int i = 0; i < _dim; ++i)
      71             :   {
      72     3598208 :     if (_axes[i] < 3)
      73     2401184 :       point_in_grid[i] = p(_axes[i]);
      74     1197024 :     else if (_axes[i] == 3) // the time direction
      75     1197024 :       point_in_grid[i] = t;
      76             :   }
      77     1202000 :   return point_in_grid;
      78           0 : }
      79             : 
      80             : template PiecewiseMultiInterpolation::GridPoint
      81             : PiecewiseMultiInterpolation::pointInGrid<false>(const Real &, const Point &) const;
      82             : template PiecewiseMultiInterpolation::ADGridPoint
      83             : PiecewiseMultiInterpolation::pointInGrid<true>(const ADReal &, const ADPoint &) const;
      84             : 
      85             : Real
      86     1202000 : PiecewiseMultiInterpolation::value(Real t, const Point & p) const
      87             : {
      88     1202000 :   return sample(pointInGrid<false>(t, p));
      89             : }
      90             : 
      91             : ADReal
      92           0 : PiecewiseMultiInterpolation::value(const ADReal & t, const ADPoint & p) const
      93             : {
      94           0 :   return sample(pointInGrid<true>(t, p));
      95             : }
      96             : 
      97             : ADReal
      98           0 : PiecewiseMultiInterpolation::sample(const ADGridPoint &) const
      99             : {
     100           0 :   mooseError("The AD variant of 'sample' needs to be implemented");
     101             : }
     102             : 
     103             : void
     104     3598208 : PiecewiseMultiInterpolation::getNeighborIndices(std::vector<Real> in_arr,
     105             :                                                 Real x,
     106             :                                                 unsigned int & lower_x,
     107             :                                                 unsigned int & upper_x) const
     108             : {
     109     3598208 :   int N = in_arr.size();
     110     3598208 :   if (x <= in_arr[0])
     111             :   {
     112      556352 :     lower_x = 0;
     113      556352 :     upper_x = 0;
     114             :   }
     115     3041856 :   else if (x >= in_arr[N - 1])
     116             :   {
     117      616272 :     lower_x = N - 1;
     118      616272 :     upper_x = N - 1;
     119             :   }
     120             :   else
     121             :   {
     122             :     // returns up which points at the first element in inArr that is not less than x
     123     2425584 :     std::vector<double>::iterator up = std::lower_bound(in_arr.begin(), in_arr.end(), x);
     124             : 
     125             :     // std::distance returns std::difference_type, which can be negative in theory, but
     126             :     // in this context will always be >=0.  Therefore the explicit cast is just to shut
     127             :     // the compiler up.
     128     2425584 :     upper_x = static_cast<unsigned int>(std::distance(in_arr.begin(), up));
     129     2425584 :     if (in_arr[upper_x] == x)
     130      507648 :       lower_x = upper_x;
     131             :     else
     132     1917936 :       lower_x = upper_x - 1;
     133             :   }
     134     3598208 : }

Generated by: LCOV version 1.14