https://mooseframework.inl.gov
Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Friends | List of all members
ValueCache< T > Class Template Reference

ValueCache is a generic helper template to implement an unstructured data cache, where arbitrary result types can be placed in an n-dimensional space of real numbers. More...

#include <ValueCache.h>

Public Member Functions

 ValueCache (std::size_t in_dim, std::size_t max_leaf_size=10)
 Construct a ValueCache with indices in in_dim dimensions. More...
 
 ValueCache (const std::string &file_name, std::size_t in_dim, std::size_t max_leaf_size=10)
 Same as above, but provide a filename for storing/restoring the cache content between runs. More...
 
 ~ValueCache ()
 Object destructor. If the cache was constructed with a file name, it gets written here. More...
 
void insert (const std::vector< Real > &in_val, const T &out_val)
 insert a new value out_value at the position in_val More...
 
std::tuple< const std::vector< Real > &, const T &, RealgetNeighbor (const std::vector< Real > &in_val)
 get a single neighbor of in_val along with stored values and distances More...
 
std::vector< std::tuple< const std::vector< Real > &, const T &, Real > > getNeighbors (const std::vector< Real > &in_val, const std::size_t k)
 get a list of up to k neighbors of in_val along with stored values and distances More...
 
std::size_t size ()
 return the number of cache entries More...
 
void clear ()
 remove all data from the cache More...
 
std::size_t kdtree_get_point_count () const
 Nanoflann interface functions. More...
 
Real kdtree_get_pt (const std::size_t idx, const std::size_t dim) const
 
template<class BBOX >
bool kdtree_get_bbox (BBOX &bb) const
 

Protected Types

using KdTreeT = nanoflann::KDTreeSingleIndexDynamicAdaptor< nanoflann::L2_Simple_Adaptor< Real, ValueCache< T > >, ValueCache< T >, -1, std::size_t >
 

Protected Member Functions

void rebuildTree ()
 rebuild the kd-tree from scratch and update the bounding box More...
 

Protected Attributes

std::vector< std::pair< std::vector< Real >, T > > _location_data
 
std::unique_ptr< KdTreeT_kd_tree
 
const std::size_t _in_dim
 
const std::size_t _max_leaf_size
 
const std::size_t _max_subtrees
 
std::optional< std::string > _persistent_storage_file
 file name for persistent store/restore of the cache More...
 
std::vector< std::pair< Real, Real > > _bbox
 bounding box (updated upon insertion) More...
 

Friends

void dataStore (std::ostream &stream, ValueCache< T > &c, void *context)
 
void dataLoad (std::istream &stream, ValueCache< T > &c, void *context)
 

Detailed Description

template<typename T>
class ValueCache< T >

ValueCache is a generic helper template to implement an unstructured data cache, where arbitrary result types can be placed in an n-dimensional space of real numbers.

Upon lookup the closest result to a given point in n-space is returned. Applications include caching reasonable initial guesses for local Newton solves as found in certain phase field models as well as thermodynamic Gibbs energy minimization.

Definition at line 27 of file ValueCache.h.

Member Typedef Documentation

◆ KdTreeT

template<typename T>
using ValueCache< T >::KdTreeT = nanoflann::KDTreeSingleIndexDynamicAdaptor<nanoflann::L2_Simple_Adaptor<Real, ValueCache<T> >, ValueCache<T>, -1, std::size_t>
protected

Definition at line 86 of file ValueCache.h.

Constructor & Destructor Documentation

◆ ValueCache() [1/2]

template<typename T >
ValueCache< T >::ValueCache ( std::size_t  in_dim,
std::size_t  max_leaf_size = 10 
)

Construct a ValueCache with indices in in_dim dimensions.

Definition at line 106 of file ValueCache.h.

107  : _kd_tree(nullptr), _in_dim(in_dim), _max_leaf_size(max_leaf_size), _max_subtrees(100)
108 {
109 }
const std::size_t _in_dim
Definition: ValueCache.h:91
const std::size_t _max_subtrees
Definition: ValueCache.h:93
std::unique_ptr< KdTreeT > _kd_tree
Definition: ValueCache.h:89
const std::size_t _max_leaf_size
Definition: ValueCache.h:92

◆ ValueCache() [2/2]

template<typename T >
ValueCache< T >::ValueCache ( const std::string &  file_name,
std::size_t  in_dim,
std::size_t  max_leaf_size = 10 
)

Same as above, but provide a filename for storing/restoring the cache content between runs.

Definition at line 112 of file ValueCache.h.

115  : ValueCache(in_dim, max_leaf_size)
116 {
117  _persistent_storage_file = file_name;
118 
119  // if the persistent storage file exists and is readable, load it
121  /*check_line_endings =*/false,
122  /*throw_on_unreadable =*/false))
123  {
124  std::ifstream in_file(_persistent_storage_file->c_str());
125  if (!in_file)
126  mooseError("Failed to open '", *_persistent_storage_file, "' for reading.");
127  dataLoad(in_file, *this, nullptr);
128  }
129 }
friend void dataLoad(std::istream &stream, ValueCache< T > &c, void *context)
Definition: ValueCache.h:311
std::optional< std::string > _persistent_storage_file
file name for persistent store/restore of the cache
Definition: ValueCache.h:96
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
ValueCache(std::size_t in_dim, std::size_t max_leaf_size=10)
Construct a ValueCache with indices in in_dim dimensions.
Definition: ValueCache.h:106
bool checkFileReadable(const std::string &filename, bool check_line_endings=false, bool throw_on_unreadable=true, bool check_for_git_lfs_pointer=true)
Checks to see if a file is readable (exists and permissions)
Definition: MooseUtils.C:250

◆ ~ValueCache()

template<typename T >
ValueCache< T >::~ValueCache ( )

Object destructor. If the cache was constructed with a file name, it gets written here.

Definition at line 132 of file ValueCache.h.

133 {
134  // if a persistent storage file was specified, write results back to it
135  if (_persistent_storage_file.has_value())
136  {
137  std::ofstream out_file(_persistent_storage_file->c_str());
138  if (!out_file)
139  mooseWarning("Failed to open '", *_persistent_storage_file, "' for writing.");
140  dataStore(out_file, *this, nullptr);
141  }
142 }
std::optional< std::string > _persistent_storage_file
file name for persistent store/restore of the cache
Definition: ValueCache.h:96
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition: MooseError.h:336
friend void dataStore(std::ostream &stream, ValueCache< T > &c, void *context)
Definition: ValueCache.h:304

Member Function Documentation

◆ clear()

template<typename T >
void ValueCache< T >::clear ( )

remove all data from the cache

Definition at line 243 of file ValueCache.h.

244 {
245  _location_data.clear();
246  _kd_tree = nullptr;
247 }
std::unique_ptr< KdTreeT > _kd_tree
Definition: ValueCache.h:89
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88

◆ getNeighbor()

template<typename T >
std::tuple< const std::vector< Real > &, const T &, Real > ValueCache< T >::getNeighbor ( const std::vector< Real > &  in_val)

get a single neighbor of in_val along with stored values and distances

Retrieve a single closest neighbor to in_val.

Throws an exception if no values are stored.

Definition at line 184 of file ValueCache.h.

185 {
186  // throw an exception if this is called on an empty cache
187  if (_location_data.empty())
188  throw std::runtime_error("Attempting to retrieve a neighbor from an empty ValueCache.");
189 
190  // buffers for the kNN search
191  nanoflann::KNNResultSet<Real> result_set(1);
192  std::size_t return_index;
193  Real distance;
194 
195  // kNN search
196  result_set.init(&return_index, &distance);
197  _kd_tree->findNeighbors(result_set, in_val.data());
198 
199  const auto & [location, data] = _location_data[return_index];
200  return {std::cref(location), std::cref(data), distance};
201 }
Real distance(const Point &p)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unique_ptr< KdTreeT > _kd_tree
Definition: ValueCache.h:89
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88

◆ getNeighbors()

template<typename T >
std::vector< std::tuple< const std::vector< Real > &, const T &, Real > > ValueCache< T >::getNeighbors ( const std::vector< Real > &  in_val,
const std::size_t  k 
)

get a list of up to k neighbors of in_val along with stored values and distances

This function performs a search on the value cache and returns either the k-nearest neighbors or the neighbors available if the cache size is less than k.

Definition at line 209 of file ValueCache.h.

210 {
211  // return early if no points are stored
212  if (_location_data.empty())
213  return {};
214 
215  // buffers for the kNN search
216  nanoflann::KNNResultSet<Real> result_set(std::min(k, size()));
217  std::vector<std::size_t> return_indices(std::min(k, size()));
218  std::vector<Real> distances(std::min(k, size()));
219 
220  // kNN search
221  result_set.init(return_indices.data(), distances.data());
222  _kd_tree->findNeighbors(result_set, in_val.data());
223 
224  // prepare results to be returned
225  std::vector<std::tuple<const std::vector<Real> &, const T &, Real>> nearest_neighbors;
226  for (const auto i : index_range(result_set))
227  {
228  const auto & [location, data] = _location_data[return_indices[i]];
229  nearest_neighbors.emplace_back(std::cref(location), std::cref(data), distances[i]);
230  }
231  return nearest_neighbors;
232 }
std::size_t size()
return the number of cache entries
Definition: ValueCache.h:236
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unique_ptr< KdTreeT > _kd_tree
Definition: ValueCache.h:89
auto min(const L &left, const R &right)
auto index_range(const T &sizable)
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88

◆ insert()

template<typename T >
void ValueCache< T >::insert ( const std::vector< Real > &  in_val,
const T &  out_val 
)

insert a new value out_value at the position in_val

Definition at line 146 of file ValueCache.h.

147 {
148  mooseAssert(in_val.size() == _in_dim, "Key dimensions do not match cache dimensions");
149 
150  auto id = size();
151  _location_data.emplace_back(in_val, out_val);
152 
153  // update bounding box
154  if (id == 0)
155  {
156  // first item is inserted
157  _bbox.resize(_in_dim);
158  for (const auto i : make_range(_in_dim))
159  _bbox[i] = {in_val[i], in_val[i]};
160  }
161  else
162  for (const auto i : make_range(_in_dim))
163  _bbox[i] = {std::min(_bbox[i].first, in_val[i]), std::max(_bbox[i].second, in_val[i])};
164 
165  // do we have too many subtrees?
166  if (_kd_tree && _kd_tree->getAllIndices().size() > _max_subtrees)
167  _kd_tree = nullptr;
168 
169  // rebuild tree or add point
170  if (!_kd_tree)
171  {
172  _kd_tree = std::make_unique<KdTreeT>(_in_dim, *this, _max_leaf_size);
173  mooseAssert(_kd_tree != nullptr, "KDTree was not properly initialized.");
174  }
175  else
176  _kd_tree->addPoints(id, id);
177 }
std::size_t size()
return the number of cache entries
Definition: ValueCache.h:236
const std::size_t _in_dim
Definition: ValueCache.h:91
auto max(const L &left, const R &right)
const std::size_t _max_subtrees
Definition: ValueCache.h:93
std::vector< std::pair< Real, Real > > _bbox
bounding box (updated upon insertion)
Definition: ValueCache.h:99
std::unique_ptr< KdTreeT > _kd_tree
Definition: ValueCache.h:89
const std::size_t _max_leaf_size
Definition: ValueCache.h:92
IntRange< T > make_range(T beg, T end)
auto min(const L &left, const R &right)
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88

◆ kdtree_get_bbox()

template<typename T >
template<class BBOX >
bool ValueCache< T >::kdtree_get_bbox ( BBOX &  bb) const

Definition at line 291 of file ValueCache.h.

292 {
293  if (_location_data.empty())
294  return false;
295 
296  // return the bounding box incrementally built upon insertion
297  for (const auto i : make_range(_in_dim))
298  bb[i] = {_bbox[i].first, _bbox[i].second};
299  return true;
300 }
const std::size_t _in_dim
Definition: ValueCache.h:91
std::vector< std::pair< Real, Real > > _bbox
bounding box (updated upon insertion)
Definition: ValueCache.h:99
IntRange< T > make_range(T beg, T end)
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88

◆ kdtree_get_point_count()

template<typename T >
std::size_t ValueCache< T >::kdtree_get_point_count ( ) const

Nanoflann interface functions.

Definition at line 276 of file ValueCache.h.

277 {
278  return _location_data.size();
279 }
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88

◆ kdtree_get_pt()

template<typename T >
Real ValueCache< T >::kdtree_get_pt ( const std::size_t  idx,
const std::size_t  dim 
) const

Definition at line 283 of file ValueCache.h.

284 {
285  return _location_data[idx].first[dim];
286 }
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:153
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)

◆ rebuildTree()

template<typename T >
void ValueCache< T >::rebuildTree ( )
protected

rebuild the kd-tree from scratch and update the bounding box

Definition at line 251 of file ValueCache.h.

Referenced by dataLoad().

252 {
253  if (_location_data.empty())
254  return;
255 
256  // reset bounding box (must be done before the tree is built)
257  _bbox.resize(_in_dim);
258  const auto & location0 = _location_data[0].first;
259  for (const auto i : make_range(_in_dim))
260  _bbox[i] = {location0[i], location0[i]};
261 
262  for (const auto & pair : _location_data)
263  {
264  const auto & location = pair.first;
265  for (const auto i : make_range(_in_dim))
266  _bbox[i] = {std::min(_bbox[i].first, location[i]), std::max(_bbox[i].second, location[i])};
267  }
268 
269  // build kd-tree
270  _kd_tree = std::make_unique<KdTreeT>(_in_dim, *this, _max_leaf_size);
271  mooseAssert(_kd_tree != nullptr, "KDTree was not properly initialized.");
272 }
const std::size_t _in_dim
Definition: ValueCache.h:91
auto max(const L &left, const R &right)
std::vector< std::pair< Real, Real > > _bbox
bounding box (updated upon insertion)
Definition: ValueCache.h:99
std::unique_ptr< KdTreeT > _kd_tree
Definition: ValueCache.h:89
const std::size_t _max_leaf_size
Definition: ValueCache.h:92
IntRange< T > make_range(T beg, T end)
auto min(const L &left, const R &right)
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88

◆ size()

template<typename T >
std::size_t ValueCache< T >::size ( )

return the number of cache entries

Definition at line 236 of file ValueCache.h.

237 {
238  return kdtree_get_point_count();
239 }
std::size_t kdtree_get_point_count() const
Nanoflann interface functions.
Definition: ValueCache.h:276

Friends And Related Function Documentation

◆ dataLoad

template<typename T>
void dataLoad ( std::istream &  stream,
ValueCache< T > &  c,
void context 
)
friend

Definition at line 311 of file ValueCache.h.

Referenced by ValueCache< T >::ValueCache().

312 {
313  loadHelper(stream, c._location_data, context);
314  c.rebuildTree();
315 }
void rebuildTree()
rebuild the kd-tree from scratch and update the bounding box
Definition: ValueCache.h:251
void loadHelper(std::istream &stream, P &data, void *context)
Scalar helper routine.
Definition: DataIO.h:985
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88

◆ dataStore

template<typename T>
void dataStore ( std::ostream &  stream,
ValueCache< T > &  c,
void context 
)
friend

Definition at line 304 of file ValueCache.h.

305 {
306  storeHelper(stream, c._location_data, context);
307 }
void storeHelper(std::ostream &stream, P &data, void *context)
Scalar helper routine.
Definition: DataIO.h:893
std::vector< std::pair< std::vector< Real >, T > > _location_data
Definition: ValueCache.h:88

Member Data Documentation

◆ _bbox

template<typename T>
std::vector<std::pair<Real, Real> > ValueCache< T >::_bbox
protected

bounding box (updated upon insertion)

Definition at line 99 of file ValueCache.h.

◆ _in_dim

template<typename T>
const std::size_t ValueCache< T >::_in_dim
protected

Definition at line 91 of file ValueCache.h.

◆ _kd_tree

template<typename T>
std::unique_ptr<KdTreeT> ValueCache< T >::_kd_tree
protected

Definition at line 89 of file ValueCache.h.

◆ _location_data

template<typename T>
std::vector<std::pair<std::vector<Real>, T> > ValueCache< T >::_location_data
protected

Definition at line 88 of file ValueCache.h.

Referenced by dataLoad(), and dataStore().

◆ _max_leaf_size

template<typename T>
const std::size_t ValueCache< T >::_max_leaf_size
protected

Definition at line 92 of file ValueCache.h.

◆ _max_subtrees

template<typename T>
const std::size_t ValueCache< T >::_max_subtrees
protected

Definition at line 93 of file ValueCache.h.

◆ _persistent_storage_file

template<typename T>
std::optional<std::string> ValueCache< T >::_persistent_storage_file
protected

file name for persistent store/restore of the cache

Definition at line 96 of file ValueCache.h.

Referenced by ValueCache< T >::ValueCache().


The documentation for this class was generated from the following file: