ftle.hpp
Go to the documentation of this file.
1 
7 #pragma once
8 
9 #include "flow.hpp"
10 #include <Eigen/Dense>
11 #include <Eigen/Eigenvalues>
12 
13 namespace LCS {
14 
21 template <typename T, unsigned Dim = 2>
22 class FTLE : public Field<T, Dim, 1>
23 {
24  public:
29  Field<T, Dim, 1>(std::get<0>(ff.CurrentPosition().GetAll().Size()),
30  std::get<1>(ff.CurrentPosition().GetAll().Size())),
31  flow_field_(ff),
32  initial_time_(ff.InitialPosition().GetTime())
33  {
34  this->UpdateTime(ff.GetTime());
35  }
36 
42  inline T Get(const unsigned i, const unsigned j) const
43  {
44  return this->data_(i,j);
45  }
46 
48  void Calculate()
49  {
50  Clock clock;
51  clock.Begin();
52  auto initial_pos_data = flow_field_.InitialPosition().GetAll();
53  auto current_pos_data = flow_field_.CurrentPosition().GetAll();
54  auto dt = this->time_ - initial_time_;
55 
56  switch(flow_field_.GetDirection())
57  {
58  case Forward:
59  std::cout << "Forward FTLE calculation begins" << std::endl;
60  break;
61  case Backward:
62  std::cout << "Backward FTLE calculation begins" << std::endl;
63  break;
64  default: break;
65  }
66 
67  #pragma omp parallel for
68  for (unsigned i = 0; i < this->nx_; ++i)
69  {
70  Vector<T, Dim> x_pre, x_next, y_pre, y_next;
71  Vector<T, Dim> x0_pre, x0_next, y0_pre, y0_next;
72 
73  Eigen::Matrix<T, 2, 2> deformation, cauchy_green;
74 
75  for (unsigned j = 0; j < this->ny_; ++j)
76  {
77  std::tie(x0_pre, x0_next, y0_pre, y0_next) = initial_pos_data.GetNearby(i,j);
78  std::tie(x_pre, x_next, y_pre, y_next) = current_pos_data.GetNearby(i,j);
79 
80  // deformation tensor
81  deformation(0,0) = (x_next.x-x_pre.x) / (x0_next.x-x0_pre.x);
82  deformation(0,1) = (y_next.x-y_pre.x) / (y0_next.y-y0_pre.y);
83  deformation(1,0) = (x_next.y-x_pre.y) / (x0_next.x-x0_pre.x);
84  deformation(1,1) = (y_next.y-y_pre.y) / (y0_next.y-y0_pre.y);
85 
86  cauchy_green = deformation.transpose() * deformation;
87 
88  auto eivals = cauchy_green.template selfadjointView<Eigen::Lower>().eigenvalues();
89  this->data_(i,j).value = .5 * std::log(eivals.maxCoeff()) / dt;
90  }
91  }
92 
93  clock.End();
94  switch(flow_field_.GetDirection())
95  {
96  case Forward:
97  std::cout << "Forward FTLE calculation ends";
98  break;
99  case Backward:
100  std::cout << "Backward FTLE calculation ends";
101  break;
102  default: break;
103  }
104  std::cout << " (Execution time: " <<
105  std::setprecision(4) << clock.GetTotalElapsedTime() << "s)" << std::endl;
106  }
107 
108  private:
109  FlowField<T, Dim>& flow_field_;
110  T initial_time_;
111 };
112 
113 }
Classes for flow fields.
Class for flow field.
Definition: flow.hpp:15
void End()
Definition: basic.hpp:374
T y
Definition: basic.hpp:104
const unsigned nx_
Definition: field.hpp:95
T x
Definition: basic.hpp:103
T Get(const unsigned i, const unsigned j) const
Definition: ftle.hpp:42
Class for finite-time Lyapunov exponent (FTLE) fields.
Definition: ftle.hpp:22
auto & GetAll() const
Definition: field.hpp:47
Class for time recording.
Definition: basic.hpp:354
const unsigned ny_
Definition: field.hpp:96
Definition: flow.hpp:27
Class for general physical fields.
Definition: field.hpp:35
FTLE(FlowField< T, Dim > &ff)
Definition: ftle.hpp:28
void Calculate()
Definition: ftle.hpp:48
auto GetTime()
Definition: flow.hpp:79
void UpdateTime(const T time)
Definition: field.hpp:79
Tensor< Vector< T, Size >, Dim > data_
Definition: field.hpp:97
Struct for vectors.
Definition: basic.hpp:92
auto GetTime() const
Definition: field.hpp:55
double GetTotalElapsedTime() const
Definition: basic.hpp:400
void Begin()
Definition: basic.hpp:363
Definition: flow.hpp:26
T time_
Definition: field.hpp:98