LCOV - code coverage report
Current view: top level - src/functions - PiecewiseMultilinear.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #31825 (c328ac) with base d8769b Lines: 37 54 68.5 %
Date: 2025-11-10 13:32:39 Functions: 5 11 45.5 %
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 "PiecewiseMultilinear.h"
      11             : #include "GriddedData.h"
      12             : 
      13             : registerMooseObject("MooseApp", PiecewiseMultilinear);
      14             : 
      15             : InputParameters
      16       15454 : PiecewiseMultilinear::validParams()
      17             : {
      18       15454 :   InputParameters params = PiecewiseMultiInterpolation::validParams();
      19       30908 :   params.addClassDescription(
      20             :       "PiecewiseMultilinear performs linear interpolation on 1D, 2D, 3D or 4D "
      21             :       "data.  The data_file specifies the axes directions and the function "
      22             :       "values.  If a point lies outside the data range, the appropriate end "
      23             :       "value is used.");
      24       30908 :   params.addParam<Real>(
      25       30908 :       "epsilon", 1e-12, "Finite differencing parameter for gradient and time derivative");
      26       15454 :   return params;
      27           0 : }
      28             : 
      29         259 : PiecewiseMultilinear::PiecewiseMultilinear(const InputParameters & parameters)
      30         483 :   : PiecewiseMultiInterpolation(parameters), _epsilon(getParam<Real>("epsilon"))
      31             : {
      32         224 : }
      33             : 
      34             : Real
      35     1358972 : PiecewiseMultilinear::sample(const GridPoint & pt) const
      36             : {
      37     1358972 :   return sampleInternal<false>(pt);
      38             : }
      39             : 
      40             : ADReal
      41           0 : PiecewiseMultilinear::sample(const ADGridPoint & pt) const
      42             : {
      43           0 :   return sampleInternal<true>(pt);
      44             : }
      45             : 
      46             : template <bool is_ad>
      47             : Moose::GenericType<Real, is_ad>
      48     1358972 : PiecewiseMultilinear::sampleInternal(const Moose::GenericType<GridPoint, is_ad> pt) const
      49             : {
      50             :   using std::abs;
      51             :   /*
      52             :    * left contains the indices of the point to the 'left', 'down', etc, of pt
      53             :    * right contains the indices of the point to the 'right', 'up', etc, of pt
      54             :    * Hence, left and right define the vertices of the hypercube containing pt
      55             :    */
      56     1358972 :   GridIndex left(_dim);
      57     1358972 :   GridIndex right(_dim);
      58     5427670 :   for (unsigned int i = 0; i < _dim; ++i)
      59     4068698 :     getNeighborIndices(_grid[i], MetaPhysicL::raw_value(pt[i]), left[i], right[i]);
      60             : 
      61             :   /*
      62             :    * The following just loops through all the vertices of the
      63             :    * hypercube containing pt, evaluating the function at all
      64             :    * those vertices, and weighting the contributions to the
      65             :    * final result depending on the distance of pt from the vertex
      66             :    */
      67     1358972 :   Moose::GenericType<Real, is_ad> f = 0;
      68           0 :   Moose::GenericType<Real, is_ad> weight;
      69     1358972 :   GridIndex arg(_dim);
      70             :   // number of points in hypercube = 2^_dim
      71    12229684 :   for (unsigned int i = 0; i < (1u << _dim); ++i)
      72             :   {
      73    10870712 :     weight = 1;
      74    43533248 :     for (unsigned int j = 0; j < _dim; ++j)
      75             :       // shift i j-bits to the right and see if the result has a 0 as its right-most bit
      76    32662536 :       if ((i >> j) % 2 == 0)
      77             :       {
      78    16331268 :         arg[j] = left[j];
      79    16331268 :         if (left[j] != right[j])
      80     8698608 :           weight *= abs(pt[j] - _grid[j][right[j]]);
      81             :         else
      82             :           // unusual "end condition" case. weight by 0.5 because we will encounter this twice
      83     7632660 :           weight *= 0.5;
      84             :       }
      85             :       else
      86             :       {
      87    16331268 :         arg[j] = right[j];
      88    16331268 :         if (left[j] != right[j])
      89     8698608 :           weight *= abs(pt[j] - _grid[j][left[j]]);
      90             :         else
      91             :           // unusual "end condition" case. weight by 0.5 because we will encounter this twice
      92     7632660 :           weight *= 0.5;
      93             :       }
      94    10870712 :     f += _gridded_data->evaluateFcn(arg) * weight;
      95             :   }
      96             : 
      97             :   /*
      98             :    * finally divide by the volume of the hypercube
      99             :    */
     100     1358972 :   weight = 1;
     101     5427670 :   for (unsigned int dim = 0; dim < pt.size(); ++dim)
     102     4068698 :     if (left[dim] != right[dim])
     103     2170678 :       weight *= _grid[dim][right[dim]] - _grid[dim][left[dim]];
     104             :     else
     105             :       // unusual "end condition" case. weight by 1 to cancel the two 0.5 encountered previously
     106     1898020 :       weight *= 1;
     107             : 
     108     1358972 :   return f / weight;
     109           0 : }
     110             : 
     111             : RealGradient
     112           0 : PiecewiseMultilinear::gradient(Real t, const Point & p) const
     113             : {
     114           0 :   RealGradient grad;
     115             : 
     116             :   // sample center point
     117           0 :   auto s1 = sample(pointInGrid<false>(t, p));
     118             : 
     119             :   // sample epsilon steps in all directions
     120           0 :   for (const auto dir : _axes)
     121           0 :     if (dir < 3)
     122             :     {
     123           0 :       Point pp = p;
     124           0 :       pp(dir) += _epsilon;
     125           0 :       grad(dir) = (sample(pointInGrid<false>(t, pp)) - s1) / _epsilon;
     126             :     }
     127             : 
     128           0 :   return grad;
     129             : }
     130             : 
     131             : Real
     132           0 : PiecewiseMultilinear::timeDerivative(Real t, const Point & p) const
     133             : {
     134           0 :   return (sample(pointInGrid<false>(t + _epsilon, p)) - sample(pointInGrid<false>(t, p))) /
     135           0 :          _epsilon;
     136             : }

Generated by: LCOV version 1.14