9#include "Kokkos_Macros.hpp"
130template <
typename ScalarType >
133 using ViewType = Kokkos::View< ScalarType**, Kokkos::LayoutRight >;
151 KOKKOS_INLINE_FUNCTION
155 ScalarType fx = ( x -
x_min ) /
dx;
156 ScalarType fy = ( y -
y_min ) /
dy;
158 const ScalarType fx_max =
static_cast< ScalarType
>(
nx - 1 );
159 const ScalarType fy_max =
static_cast< ScalarType
>(
ny - 1 );
161 if ( fx < ScalarType( 0 ) )
163 fx = ScalarType( 0 );
171 if ( fy < ScalarType( 0 ) )
173 fy = ScalarType( 0 );
182 if (
nx == 1 &&
ny == 1 )
189 int iy =
static_cast< int >( fy );
195 ScalarType ty = fy -
static_cast< ScalarType
>( iy );
196 return ( ScalarType( 1 ) - ty ) *
data( 0, iy ) + ty *
data( 0, iy + 1 );
201 int ix =
static_cast< int >( fx );
206 ScalarType tx = fx -
static_cast< ScalarType
>( ix );
207 return ( ScalarType( 1 ) - tx ) *
data( ix, 0 ) + tx *
data( ix + 1, 0 );
211 int ix =
static_cast< int >( fx );
212 int iy =
static_cast< int >( fy );
225 const ScalarType tx = fx -
static_cast< ScalarType
>( ix );
226 const ScalarType ty = fy -
static_cast< ScalarType
>( iy );
228 return ( ScalarType( 1 ) - tx ) * ( ScalarType( 1 ) - ty ) *
data( ix, iy ) +
229 tx * ( ScalarType( 1 ) - ty ) *
data( ix + 1, iy ) + ( ScalarType( 1 ) - tx ) * ty *
data( ix, iy + 1 ) +
230 tx * ty *
data( ix + 1, iy + 1 );
243 std::vector< std::string > tokens;
246 for (
const char c : line )
248 if ( c ==
' ' || c ==
'\t' || c ==
',' )
252 tokens.push_back( tok );
263 tokens.push_back( tok );
318template <
typename ScalarType =
double >
320 const std::string& filename,
321 const std::vector< int >& column_indices,
323 const std::string& label =
"lookup_table" )
327 throw std::runtime_error(
328 "terra::io::read_lookup_tables_2d: exactly one of stride_x / stride_y must be 1. "
329 "See GridLayout2D documentation for the two supported configurations." );
332 const int total_rows = layout.
nx * layout.
ny;
333 const int num_cols =
static_cast< int >( column_indices.size() );
340 for (
int c : column_indices )
343 throw std::runtime_error(
"terra::io::read_lookup_tables_2d: negative column index." );
344 if ( c > max_col_idx )
349 std::ifstream file( filename );
350 if ( !file.is_open() )
351 throw std::runtime_error(
"terra::io::read_lookup_tables_2d: cannot open file: " + filename );
354 std::vector< std::vector< ScalarType > > flat( num_cols );
355 for (
auto& v : flat )
356 v.reserve(
static_cast< size_t >( total_rows ) );
362 while ( data_row < total_rows && std::getline( file, line ) )
368 const auto first_nonspace = line.find_first_not_of(
" \t\r" );
369 if ( first_nonspace == std::string::npos )
371 if ( line[first_nonspace] ==
'#' )
377 if (
static_cast< int >( tokens.size() ) <= max_col_idx )
379 throw std::runtime_error(
380 "terra::io::read_lookup_tables_2d: file '" + filename +
"', line " + std::to_string( line_number ) +
381 ": expected at least " + std::to_string( max_col_idx + 1 ) +
" columns, found " +
382 std::to_string( tokens.size() ) +
"." );
385 for (
int c = 0; c < num_cols; ++c )
389 flat[c].push_back(
static_cast< ScalarType
>( std::stod( tokens[column_indices[c]] ) ) );
391 catch (
const std::exception& e )
393 throw std::runtime_error(
394 "terra::io::read_lookup_tables_2d: file '" + filename +
"', line " + std::to_string( line_number ) +
395 ": cannot parse '" + tokens[column_indices[c]] +
"' as a number." );
402 if ( data_row < total_rows )
404 throw std::runtime_error(
405 "terra::io::read_lookup_tables_2d: file '" + filename +
"': expected " + std::to_string( total_rows ) +
406 " data rows (nx=" + std::to_string( layout.
nx ) +
" * ny=" + std::to_string( layout.
ny ) +
407 "), but found only " + std::to_string( data_row ) +
"." );
411 std::vector< ScalarLookupTable2D< ScalarType > > result;
412 result.reserve(
static_cast< size_t >( num_cols ) );
414 for (
int c = 0; c < num_cols; ++c )
416 const std::string view_label = label +
"_col" + std::to_string( column_indices[c] );
421 auto host_view = Kokkos::create_mirror_view( Kokkos::HostSpace{}, device_view );
424 for (
int k = 0; k < total_rows; ++k )
428 host_view( ix, iy ) = flat[c][
static_cast< size_t >( k )];
431 Kokkos::deep_copy( device_view, host_view );
434 table.
data = device_view;
435 table.
x_min =
static_cast< ScalarType
>( layout.
x_min );
436 table.
y_min =
static_cast< ScalarType
>( layout.
y_min );
437 table.
dx =
static_cast< ScalarType
>( layout.
dx );
438 table.
dy =
static_cast< ScalarType
>( layout.
dy );
439 table.
nx = layout.
nx;
440 table.
ny = layout.
ny;
442 result.push_back( std::move( table ) );
461template <
typename ScalarType =
double >
463 const std::string& filename,
466 const std::string& label =
"lookup_table" )
467{
return read_lookup_tables_2d< ScalarType >( filename, { column_index }, layout, label ).front(); }
std::vector< std::string > split_flexible(const std::string &line)
Split a line on any combination of spaces, tabs, and commas.
Definition lookup_table_2d_reader.hpp:241
void flat_to_grid(int k, const GridLayout2D &layout, int &ix, int &iy)
Given a flat index k, return (ix, iy) according to the layout strides.
Definition lookup_table_2d_reader.hpp:271
Definition lookup_table_2d_reader.hpp:12
ScalarLookupTable2D< ScalarType > read_lookup_table_2d(const std::string &filename, int column_index, const GridLayout2D &layout, const std::string &label="lookup_table")
Convenience overload: read a single column from a data file.
Definition lookup_table_2d_reader.hpp:462
std::vector< ScalarLookupTable2D< ScalarType > > read_lookup_tables_2d(const std::string &filename, const std::vector< int > &column_indices, const GridLayout2D &layout, const std::string &label="lookup_table")
Read selected columns from a delimited data file into 2D lookup tables.
Definition lookup_table_2d_reader.hpp:319
Describes the 2D grid layout for a linearized data column.
Definition lookup_table_2d_reader.hpp:108
int ny
Number of grid points along y.
Definition lookup_table_2d_reader.hpp:110
double x_min
x coordinate of the first (ix=0) grid point
Definition lookup_table_2d_reader.hpp:111
double dx
Grid spacing along x (must be > 0)
Definition lookup_table_2d_reader.hpp:113
int stride_x
Flat-index step when ix increases by 1 (see above)
Definition lookup_table_2d_reader.hpp:115
int stride_y
Flat-index step when iy increases by 1 (see above)
Definition lookup_table_2d_reader.hpp:116
int nx
Number of grid points along x.
Definition lookup_table_2d_reader.hpp:109
double y_min
y coordinate of the first (iy=0) grid point
Definition lookup_table_2d_reader.hpp:112
double dy
Grid spacing along y (must be > 0)
Definition lookup_table_2d_reader.hpp:114
Device-capable 2D scalar lookup table with bilinear interpolation.
Definition lookup_table_2d_reader.hpp:132
ScalarType x_min
x coordinate of grid point ix=0
Definition lookup_table_2d_reader.hpp:136
ViewType data
2D device view, indexed as data(ix, iy)
Definition lookup_table_2d_reader.hpp:135
ScalarType y_min
y coordinate of grid point iy=0
Definition lookup_table_2d_reader.hpp:137
int nx
Number of grid points along x.
Definition lookup_table_2d_reader.hpp:140
ScalarType dx
Spacing between grid points along x.
Definition lookup_table_2d_reader.hpp:138
ScalarType operator()(ScalarType x, ScalarType y) const
Bilinearly interpolated value at physical coordinates (x, y).
Definition lookup_table_2d_reader.hpp:152
int ny
Number of grid points along y.
Definition lookup_table_2d_reader.hpp:141
Kokkos::View< ScalarType **, Kokkos::LayoutRight > ViewType
Definition lookup_table_2d_reader.hpp:133
ScalarType dy
Spacing between grid points along y.
Definition lookup_table_2d_reader.hpp:139