BELFEM 0.9.0
Berkeley Lab Finite Element Framework
Loading...
Searching...
No Matches
user_table.hpp
Go to the documentation of this file.
1/*
2 * Two-column lookup table, shared by the material and the source plugin.
3 *
4 * Both plugins used to carry one copy of this loader per data file -- ten in
5 * matlib.cpp and one in current.cpp, sixty-eight lines each, differing only in
6 * the file name. They also located their data with the __FILE__ trick, which
7 * baked the SOURCE directory into the binary and broke the moment the sources
8 * moved into ./src and the data into ./data. Both problems are fixed here:
9 * one implementation, and the data directory comes from CMake as
10 * BELFEM_USER_DATA_DIR, so the library does not depend on where it is launched
11 * from either.
12 */
13
14#ifndef TAPE_QUENCH_USER_TABLE_HPP
15#define TAPE_QUENCH_USER_TABLE_HPP
16
17#include <algorithm>
18#include <fstream>
19#include <sstream>
20#include <string>
21#include <vector>
22
23#include <belfem_user_api>
24
25#ifndef BELFEM_USER_DATA_DIR
26#error "BELFEM_USER_DATA_DIR is not set -- see the target_compile_definitions in CMakeLists.txt"
27#endif
28
29namespace usermat
30{
31//------------------------------------------------------------------------------
32
48 class Table
49 {
50 const std::string mFile ;
51 std::vector< belfem::real > mX ;
52 std::vector< belfem::real > mY ;
53 bool mLoaded = false ;
54
55//------------------------------------------------------------------------------
56 public:
57//------------------------------------------------------------------------------
58
59 explicit Table( const std::string & File ) : mFile( File )
60 {
61 }
62
63//------------------------------------------------------------------------------
64
67 {
68 if ( ! mLoaded )
69 {
70 this->load() ;
71 }
72
73 if ( x <= mX.front() ) return mY.front() ;
74 if ( x >= mX.back() ) return mY.back() ;
75
76 // index of the first sample strictly greater than x. The two
77 // clamps above guarantee 1 <= k <= mX.size() - 1, so neither
78 // k - 1 nor k can run off the ends.
79 const std::size_t k = std::distance(
80 mX.begin(), std::upper_bound( mX.begin(), mX.end(), x ) ) ;
81
82 const belfem::real t = ( x - mX[ k-1 ] ) / ( mX[ k ] - mX[ k-1 ] ) ;
83
84 return mY[ k-1 ] + t * ( mY[ k ] - mY[ k-1 ] ) ;
85 }
86
87//------------------------------------------------------------------------------
88 private:
89//------------------------------------------------------------------------------
90
91 void
92 load()
93 {
94 const std::string tPath = std::string( BELFEM_USER_DATA_DIR ) + mFile ;
95
96 std::ifstream tFile( tPath ) ;
97
98 BELFEM_ERROR( tFile.is_open(),
99 "Cannot open user data file %s", tPath.c_str() ) ;
100
101 std::string tLine ;
102 belfem::real x ;
103 belfem::real y ;
104
105 while ( std::getline( tFile, tLine ) )
106 {
107 std::istringstream tStream( tLine ) ;
108
109 if ( tStream >> x >> y )
110 {
111 mX.push_back( x ) ;
112 mY.push_back( y ) ;
113 }
114 }
115
116 tFile.close() ;
117
118 BELFEM_ERROR( mX.size() > 1,
119 "User data file %s contains fewer than two samples", tPath.c_str() ) ;
120
121 mLoaded = true ;
122 }
123 };
124
125//------------------------------------------------------------------------------
126}
127#endif //TAPE_QUENCH_USER_TABLE_HPP
#define BELFEM_ERROR(aCheck,...)
Definition assert.hpp:264
belfem::real operator()(const belfem::real x)
Definition user_table.hpp:66
Table(const std::string &File)
Definition user_table.hpp:59
double real
Definition typedefs.hpp:36
Definition user_table.hpp:30