n-Dimensional Fast Methods  0.7
 All Classes Functions Variables Typedefs Pages
eikonalsolver.hpp
1 
23 #ifndef EIKONALSOLVER_H_
24 #define EIKONALSOLVER_H_
25 
26 #include <iostream>
27 #include <cmath>
28 #include <algorithm>
29 #include <numeric>
30 #include <fstream>
31 #include <array>
32 #include <chrono>
33 
34 #include <boost/concept_check.hpp>
35 
36 #include <fast_methods/fm/solver.hpp>
37 #include <fast_methods/console/console.h>
38 
39 template <class grid_t>
40 class EikonalSolver : public Solver<grid_t>{
41 
42  public:
43  EikonalSolver() : Solver<grid_t>("EikonalSolver") {}
44  EikonalSolver(const std::string& name) : Solver<grid_t>(name) {}
45 
48  virtual double solveEikonal
49  (const int & idx) {
50  unsigned int a = grid_t::getNDims(); // a parameter of the Eikonal equation.
51  Tvalues_.clear();
52 
53  for (unsigned int dim = 0; dim < grid_t::getNDims(); ++dim) {
54  double minTInDim = grid_->getMinValueInDim(idx, dim);
55  if (!isinf(minTInDim) && minTInDim < grid_->getCell(idx).getArrivalTime())
56  Tvalues_.push_back(minTInDim);
57  else
58  a -=1;
59  }
60 
61  if (a == 0)
62  return std::numeric_limits<double>::infinity();
63 
64  // Sort the neighbor values to make easy the following code.
66  std::sort(Tvalues_.begin(), Tvalues_.end());
67  double updatedT;
68  for (unsigned i = 1; i <= a; ++i) {
69  updatedT = solveEikonalNDims(idx, i);
70  // If no more dimensions or increasing one dimension will not improve time.
71  if (i == a || (updatedT - Tvalues_[i]) < utils::COMP_MARGIN)
72  break;
73  }
74  return updatedT;
75  }
76 
77  protected:
80  double solveEikonalNDims
81  (unsigned int idx, unsigned int dim) {
82  // Solve for 1 dimension.
83  if (dim == 1)
84  return Tvalues_[0] + grid_->getLeafSize() / grid_->getCell(idx).getVelocity();
85 
86  // Solve for any number > 1 of dimensions.
87  double sumT = 0;
88  double sumTT = 0;
89  for (unsigned i = 0; i < dim; ++i) {
90  sumT += Tvalues_[i];
91  sumTT += Tvalues_[i]*Tvalues_[i];
92  }
93 
94  // These a,b,c values are simplified since leafsize^2, which should be present in the three
95  // terms but they are cancelled out when solving the quadratic function.
96  double a = dim;
97  double b = -2*sumT;
98  double c = sumTT - grid_->getLeafSize() * grid_->getLeafSize() / (grid_->getCell(idx).getVelocity()*grid_->getCell(idx).getVelocity());
99  double quad_term = b*b - 4*a*c;
100 
101  if (quad_term < 0)
102  return std::numeric_limits<double>::infinity();
103  else
104  return (-b + sqrt(quad_term))/(2*a);
105  }
106 
108  std::vector<double> Tvalues_;
109 
111  std::array <unsigned int, 2*grid_t::getNDims()> neighbors_;
112 
113  using Solver<grid_t>::grid_;
114 };
115 
116 #endif /* EIKONALSOLVER_H_*/
Abstract class that serves as interface for the actual EikonalSolvers implemented. It requires (at least) the computeInternal method to be implemented,.
std::array< unsigned int, 2 *grid_t::getNDims()> neighbors_
Auxiliar array which stores the neighbor of each iteration of the computeFM() function.
virtual double solveEikonal(const int &idx)
Solves nD Eikonal equation for cell idx. If heuristics are activated, it will add the estimated trave...
grid_t * grid_
Grid container.
Definition: solver.hpp:219
std::vector< double > Tvalues_
Auxiliar vector with values T0,T1...Tn-1 variables in the Discretized Eikonal Equation.
Abstract class that serves as interface for the actual solvers implemented. It requires (at least) th...
Definition: solver.hpp:40
static constexpr double COMP_MARGIN
When comparing doubles if(a < b), do if(a+COMP_MARGIN < b) to avoid double precission issues...
Definition: utils.h:27
double solveEikonalNDims(unsigned int idx, unsigned int dim)
Solves the Eikonal equation assuming that Tvalues_ is sorted.