LCOV - code coverage report
Current view: top level - src/utils - GriddedData.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 95 100 95.0 %
Date: 2025-07-17 01:28:37 Functions: 9 9 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 "GriddedData.h"
      11             : #include "MooseUtils.h"
      12             : #include <fstream>
      13             : #include <algorithm>
      14             : 
      15             : /**
      16             :  * Creates a GriddedData object by reading info from file_name
      17             :  * A grid is defined in _grid.
      18             :  *   For example, if grid[0] = {1, 2, 3} and grid[1] = {-1, 1}
      19             :  *   this defines a 2D grid (_dim = 2), with points
      20             :  *   (1,-1), (2,-1), (3,-1), (1,1), (2,1), (3,1)
      21             :  * The i_th axis of the grid corresponds to the axes[i] axis
      22             :  *   of the simulation: see the function getAxes
      23             :  * Values at each grid point are stored in _fcn.
      24             :  *   They are ordered as in the example above.
      25             :  * _step is just a quantity used in evaluateFcn
      26             :  * The file must have the following format:
      27             :  *   All blank lines and lines starting with # are ignored
      28             :  *   The first significant line (not blank or starting with #)
      29             :  *   should be either
      30             :  *     AXIS X
      31             :  *   or
      32             :  *     AXIS Y
      33             :  *   or
      34             :  *     AXIS Z
      35             :  *   or
      36             :  *     AXIS T
      37             :  *   The next significant line should be a space-separated
      38             :  *   array of real numbers defining the grid along that axis
      39             :  *   direction.
      40             :  *   Any number of AXIS and subsequent space-separated arrays
      41             :  *   can be defined, but if using this in conjunction with
      42             :  *   PiecewiseMultilinear, a maximum of 4 should be defined.
      43             :  *   The AXIS lines define the grid in the MOOSE simulation reference
      44             :  *   frame, and is used by PiecewiseMultilinear, for instance.
      45             :  *   The next significant line should be DATA
      46             :  *   All significant lines after DATA should be the function values
      47             :  *   at each grid point, on any number of lines of the file, but
      48             :  *   each line must be space separated.  The ordering is such
      49             :  *   that when the function is evaluated, f[i,j,k,l] corresponds
      50             :  *   to the i + j*Ni + k*Ni*Nj + l*Ni*Nj*Nk data value.  Here
      51             :  *   i>=0 corresponds to the index along the first AXIS, and Ni is
      52             :  *   the number of grid points along that axis, etc.
      53             :  *   See the function parse for an example.
      54             :  */
      55         261 : GriddedData::GriddedData(std::string file_name)
      56             : {
      57         264 :   parse(_dim, _axes, _grid, _fcn, _step, file_name);
      58         249 : }
      59             : 
      60             : unsigned int
      61         237 : GriddedData::getDim()
      62             : {
      63         237 :   return _dim;
      64             : }
      65             : 
      66             : void
      67         237 : GriddedData::getAxes(std::vector<int> & axes)
      68             : {
      69         237 :   axes.resize(_dim);
      70         237 :   std::copy(_axes.begin(), _axes.end(), axes.begin());
      71         237 : }
      72             : 
      73             : void
      74         237 : GriddedData::getGrid(std::vector<std::vector<Real>> & grid)
      75             : {
      76         237 :   grid.resize(_dim);
      77         576 :   for (unsigned int i = 0; i < _dim; ++i)
      78             :   {
      79         339 :     grid[i].resize(_grid[i].size());
      80         339 :     std::copy(_grid[i].begin(), _grid[i].end(), grid[i].begin());
      81             :   }
      82         237 : }
      83             : 
      84             : void
      85           2 : GriddedData::getFcn(std::vector<Real> & fcn)
      86             : {
      87           2 :   fcn.resize(_fcn.size());
      88           2 :   std::copy(_fcn.begin(), _fcn.end(), fcn.begin());
      89           2 : }
      90             : 
      91             : Real
      92     9609344 : GriddedData::evaluateFcn(const GridIndex & ijk)
      93             : {
      94     9609344 :   if (ijk.size() != _dim)
      95           0 :     mooseError(
      96           0 :         "Gridded data evaluateFcn called with ", ijk.size(), " arguments, but expected ", _dim);
      97     9609344 :   unsigned int index = ijk[0];
      98    28872384 :   for (unsigned int i = 1; i < _dim; ++i)
      99    19263040 :     index += ijk[i] * _step[i];
     100     9609344 :   if (index >= _fcn.size())
     101           0 :     mooseError("Gridded data evaluateFcn attempted to access index ",
     102             :                index,
     103             :                " of function, but it contains only ",
     104           0 :                _fcn.size(),
     105             :                " entries");
     106     9609344 :   return _fcn[index];
     107             : }
     108             : 
     109             : void
     110         261 : GriddedData::parse(unsigned int & dim,
     111             :                    std::vector<int> & axes,
     112             :                    std::vector<std::vector<Real>> & grid,
     113             :                    std::vector<Real> & f,
     114             :                    std::vector<unsigned int> & step,
     115             :                    std::string file_name)
     116             : {
     117             :   // initialize
     118         261 :   dim = 0;
     119         261 :   axes.resize(0);
     120         261 :   grid.resize(0);
     121         261 :   f.resize(0);
     122             : 
     123             :   // open file and initialize quantities
     124         261 :   std::ifstream file(file_name.c_str());
     125         261 :   if (!file.good())
     126           7 :     mooseError("Error opening file '" + file_name + "' from GriddedData.");
     127         254 :   std::string line;
     128         254 :   bool reading_grid_data = false;
     129         254 :   bool reading_value_data = false;
     130             : 
     131             :   // read file line-by-line extracting data
     132       38911 :   while (getSignificantLine(file, line))
     133             :   {
     134             :     // look for AXIS keywords
     135       38657 :     reading_grid_data = false;
     136       38657 :     if (line.compare("AXIS X") == 0)
     137             :     {
     138         201 :       dim += 1;
     139         201 :       reading_grid_data = true;
     140         201 :       axes.push_back(0);
     141             :     }
     142       38456 :     else if (line.compare("AXIS Y") == 0)
     143             :     {
     144          69 :       dim += 1;
     145          69 :       reading_grid_data = true;
     146          69 :       axes.push_back(1);
     147             :     }
     148       38387 :     else if (line.compare("AXIS Z") == 0)
     149             :     {
     150          14 :       dim += 1;
     151          14 :       reading_grid_data = true;
     152          14 :       axes.push_back(2);
     153             :     }
     154       38373 :     else if (line.compare("AXIS T") == 0)
     155             :     {
     156          66 :       dim += 1;
     157          66 :       reading_grid_data = true;
     158          66 :       axes.push_back(3);
     159             :     }
     160             : 
     161             :     // just found an AXIS keyword
     162       38657 :     if (reading_grid_data)
     163             :     {
     164         350 :       grid.resize(dim); // add another dimension to the grid
     165         350 :       grid[dim - 1].resize(0);
     166         350 :       if (getSignificantLine(file, line))
     167         349 :         splitToRealVec(line, grid[dim - 1]);
     168         350 :       continue; // read next line from file
     169             :     }
     170             : 
     171             :     // previous significant line must have been DATA
     172       38307 :     if (reading_value_data)
     173       38026 :       splitToRealVec(line, f);
     174             : 
     175             :     // look for DATA keyword
     176       38307 :     if (line.compare("DATA") == 0)
     177         253 :       reading_value_data = true;
     178             : 
     179             :     // ignore any other lines - if we get here probably the data file is corrupt
     180             :   }
     181             : 
     182             :   // check that some axes have been defined
     183         254 :   if (dim == 0)
     184           8 :     mooseError("No valid AXIS lines found by GriddedData");
     185             : 
     186             :   // step is useful in evaluateFcn
     187         246 :   step.resize(dim);
     188         246 :   step[0] = 1; // this is actually not used
     189         350 :   for (unsigned int i = 1; i < dim; ++i)
     190         104 :     step[i] = step[i - 1] * grid[i - 1].size();
     191             : 
     192             :   // perform some checks
     193         246 :   unsigned int num_data_points = 1;
     194         595 :   for (unsigned int i = 0; i < dim; ++i)
     195             :   {
     196         350 :     if (grid[i].size() == 0)
     197           1 :       mooseError("Axis ", i, " in your GriddedData has zero size");
     198         349 :     num_data_points *= grid[i].size();
     199             :   }
     200         245 :   if (num_data_points != f.size())
     201           8 :     mooseError("According to AXIS statements in GriddedData, number of data points is ",
     202             :                num_data_points,
     203             :                " but ",
     204           8 :                f.size(),
     205             :                " function values were read from file");
     206         243 : }
     207             : 
     208             : bool
     209       39261 : GriddedData::getSignificantLine(std::ifstream & file_stream, std::string & line)
     210             : {
     211       39707 :   while (std::getline(file_stream, line))
     212             :   {
     213       39452 :     if (line.size() == 0) // empty line: read next line from file
     214          21 :       continue;
     215       39431 :     if (line[0] == '#') // just a comment: read next line from file
     216         425 :       continue;
     217             :     // have got a significant line
     218       39006 :     return true;
     219             :   }
     220             :   // have run out of file
     221         255 :   return false;
     222             : }
     223             : 
     224             : void
     225       38375 : GriddedData::splitToRealVec(const std::string & input_string, std::vector<Real> & output_vec)
     226             : {
     227       38375 :   std::vector<Real> values;
     228       38375 :   bool status = MooseUtils::tokenizeAndConvert<Real>(input_string, values, " ");
     229             : 
     230       38375 :   if (!status)
     231           0 :     mooseError("GriddedData: Failed to convert string into Real when reading line ", input_string);
     232             : 
     233       78469 :   for (auto val : values)
     234       40094 :     output_vec.push_back(val);
     235       38375 : }

Generated by: LCOV version 1.14