18 #ifndef GZ_MATH_TIME_VARYING_VOLUMETRIC_GRID_LOOKUP_FIELD_HH_
19 #define GZ_MATH_TIME_VARYING_VOLUMETRIC_GRID_LOOKUP_FIELD_HH_
21 #include <gz/math/detail/InterpolationPoint.hh>
35 template<
typename T,
typename V,
typename S>
57 public: std::optional<S>
StepTo(
const S &_session,
const T &_time);
80 public:
template<
typename X>
83 const std::vector<InterpolationPoint4D<T, V>> &_points,
86 const X _default = X(0)
96 template<
typename T,
typename V>
114 template<
typename T,
typename V>
124 this->gridFields.emplace(_time, _field);
130 sess.iter = this->gridFields.begin();
138 sess.iter = this->gridFields.lower_bound(_time);
145 return this->gridFields.end() != _session.iter;
149 public: std::optional<InMemorySession<T, V>>
StepTo(
151 if (_session.iter == gridFields.end())
158 auto nextTime =
std::next(_session.iter);
159 if (nextTime == this->gridFields.end() || _time < _session.iter->first)
164 while (nextTime != this->gridFields.end()
165 && nextTime->first <= _time)
167 newSess.iter = nextTime;
170 newSess.
time = _time;
182 if (_session.iter == this->gridFields.end())
188 InterpolationPoint4D<T, V> slice1;
189 slice1.timeSlice = _session.iter->second.GetInterpolators(
190 _point, _tol.X(), _tol.Y(), _tol.Z());
191 slice1.time = _session.iter->first;
194 auto nextTime =
std::next(_session.iter);
195 if (nextTime != this->gridFields.end())
198 InterpolationPoint4D<T, V> slice2;
199 slice2.timeSlice = nextTime->second.GetInterpolators(
200 _point, _tol.X(), _tol.Y(), _tol.Z());
201 slice2.time = nextTime->first;
219 public:
template<
typename X>
222 const std::vector<InterpolationPoint4D<T, V>> &_interpolators,
226 const X _default = X(0)
229 if (_session.iter == this->gridFields.end())
235 auto time = _session.
time;
236 if (_interpolators.size() == 0)
return std::nullopt;
237 if (_interpolators.size() == 1)
240 return _session.iter->second.EstimateValueUsingTrilinear(
247 if (_interpolators[0].timeSlice.size() == 0
248 && _interpolators[1].timeSlice.size() == 0)
253 if (_interpolators[1].timeSlice.size() == 0)
255 return _session.iter->second.EstimateValueUsingTrilinear(
261 if (_interpolators[0].timeSlice.size() == 0)
263 return next->second.EstimateValueUsingTrilinear(
271 auto res1 = _session.iter->second.EstimateValueUsingTrilinear(
277 auto res2 = next->second.EstimateValueUsingTrilinear(
283 if (res1.has_value() || res2.has_value())
285 InterpolationPoint1D<T>
286 pt1{_session.iter->first, 0}, pt2{next->first, 1};
289 res1.value_or(_default), res2.value_or(_default)};
290 return LinearInterpolate(pt1, pt2, times, time);
301 if (_session.iter == this->gridFields.end())
308 return _session.iter->second.Bounds();