WaveBlocksND
basic_steps.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../types.hpp"
4 #include "../utilities/squeeze.hpp"
5 #include "../utilities/adaptors.hpp"
6 
7 
8 namespace waveblocks {
9  namespace propagators {
10  namespace steps {
11  using utilities::Squeeze;
15 
24  template<int N, int D>
25  struct StepT {
26  static void apply(HaWpParamSet<D>& params,
27  const real_t &delta_t) {
28  params.updateq( 0.5 * delta_t * params.p() );
29  params.updateQ( 0.5 * delta_t * params.P() );
30  params.updateS( 0.25 * delta_t * params.p().dot(params.p()) );
31  }
32  };
33 
39  template<bool Mode>
40  struct HelperL {
41  template<class L>
42  static const typename std::remove_reference<decltype(std::declval<L>()[0])>::type& apply(const L& level, int i) {
43  return level[i];
44  }
45  };
46 
47  template<>
48  struct HelperL<false> {
49  template<class L>
50  static const L& apply(const L& level, int i) {
51  (void) i; // Unused
52  return level;
53  }
54  };
55 
61  template<int N, int D, bool MODE>
62  struct HelperA {
63  template<class Potential>
64  static void apply(int i, const Potential &V, HaWpParamSet<D> &params, const real_t &delta_t) {
65  // TODO: Inefficient since all levels are evaluated for each q.
66  const auto& leading_level_taylor = V.get_leading_level().taylor_at(complex_t(1,0) * Squeeze<D,RVector<D>>::apply(params.q()));
67  params.updatep( -delta_t * Unsqueeze<D,RVector<D>>::apply(HelperL<MODE>::apply(std::get<1>(leading_level_taylor),i).real()));
68  params.updateP( -delta_t * HelperL<MODE>::apply(std::get<2>(leading_level_taylor),i) * params.Q() );
69  params.updateS( -delta_t * HelperL<MODE>::apply(std::get<0>(leading_level_taylor),i));
70  }
71  };
72 
81  template<int N, int D>
82  struct StepU {
83  template<class Potential>
84  static void inhomogeneous(int i, const Potential &V, HaWpParamSet<D> &params, const real_t &delta_t) {
85  HelperA<N,D,true>::apply(i, V, params, delta_t);
86  }
87  template<class Potential>
88  static void homogeneous(const Potential &V, HaWpParamSet<D> &params, const real_t &delta_t) {
89  HelperA<N,D,false>::apply(-1, V, params, delta_t);
90  }
91  };
92 
96  template<class Packet, class Potential, class IP, int N, int D>
97  struct HelperF {
99  const Packet& packet,
100  const Potential& V) {
101  int size = 0;
102  for (auto& component : packet.components()) {
103  size += component.coefficients().size();
104  }
105  F.resize(size,size);
106 
107  // Operator
108  auto op =
109  [&V] (const CMatrix<D,Eigen::Dynamic> &nodes,
110  const RMatrix<D,1> &pos,
111  dim_t i,
112  dim_t j)
113  {
114  const dim_t n_nodes = nodes.cols();
115  CMatrix<1,Eigen::Dynamic> result(1, n_nodes);
116 
117  #pragma omp parallel for schedule(guided)
118  for(int l = 0; l < n_nodes; ++l) {
119  // TODO: Super inefficient: we compute an N x N matrix when we only want one entry.
120  result(0, l) = V.evaluate_local_remainder_at(Squeeze<D, CMatrix<D,Eigen::Dynamic>>::apply(nodes,l),
121  Squeeze<D, CVector<D>>::apply(complex_t(1,0)*pos)) (i,j);
122  }
123  return result;
124  };
125 
126  // Build matrix
127  F = IP::build_matrix(packet, op);
128  }
129  };
130 
134  template<class Packet, class Potential, class IP,int D>
135  struct HelperF<Packet,Potential,IP,1,D> {
137  const Packet& packet,
138  const Potential &V) {
139 
140  // Operator
141  auto op =
142  [&V] (const CMatrix<D,Eigen::Dynamic> &nodes,
143  const RMatrix<D,1> &pos)
144  {
145  const dim_t n_nodes = nodes.cols();
146  CMatrix<1,Eigen::Dynamic> result(1, n_nodes);
147 
148  #pragma omp parallel for schedule(guided)
149  for(int l = 0; l < n_nodes; ++l) {
150  result(0, l) = V.evaluate_local_remainder_at(Squeeze<D, CMatrix<D,Eigen::Dynamic>>::apply(nodes,l),
151  Squeeze<D, CVector<D>>::apply(complex_t(1,0)*pos));
152  }
153  return result;
154  };
155 
156  // Build matrix
157  F = IP::build_matrix(packet, op);
158  }
159  };
160 
169  template<class Packet, class Potential, int N, int D, class IP>
170  struct StepW {
171  static void apply(Packet &packet, const Potential& V, const real_t& delta_t) {
172  // Compute the matrix F
175  // Common prefactor
176  complex_t factor = -delta_t * complex_t(0,1) / (packet.eps()*packet.eps());
177  // Put all coefficients into a vector
178  CVector<Eigen::Dynamic> coefficients = PacketToCoefficients<Packet>::to(packet);
179  // Compute product of exponential with coefficients
180  coefficients = (factor * F).exp() * coefficients;
181  // Put all coefficients back
182  PacketToCoefficients<Packet>::from(coefficients, packet);
183  }
184  };
185  }
186  }
187 }
GVector< complex_t, R > CVector
Definition: types.hpp:50
static void inhomogeneous(int i, const Potential &V, HaWpParamSet< D > &params, const real_t &delta_t)
Definition: basic_steps.hpp:84
Propagate one step with the non-quadratic potential remainder part W.
Definition: basic_steps.hpp:170
Definition: coefficients_file_parser.cpp:10
Performs commong code of StepU for all specializations.
Definition: basic_steps.hpp:62
static const std::remove_reference< decltype(std::declval< L >)[0])>::type & apply(const L &level, int i)
Definition: basic_steps.hpp:42
Eigen::Matrix< real_t, R, C > RMatrix
Definition: types.hpp:22
static void build(CMatrix< Eigen::Dynamic, Eigen::Dynamic > &F, const Packet &packet, const Potential &V)
Definition: basic_steps.hpp:98
std::complex< real_t > complex_t
Definition: types.hpp:15
double real_t
Definition: types.hpp:14
static void homogeneous(const Potential &V, HaWpParamSet< D > &params, const real_t &delta_t)
Definition: basic_steps.hpp:88
Definition: squeeze.hpp:33
Helper class for StepU. If Mode then level is supscripted in i.
Definition: basic_steps.hpp:40
Builds the inner product matrix.
Definition: basic_steps.hpp:97
static const L & apply(const L &level, int i)
Definition: basic_steps.hpp:50
This class represents the Hagedorn parameter set .
Definition: hawp_paramset.hpp:24
GVector< real_t, R > RVector
Definition: types.hpp:53
static void build(CMatrix< Eigen::Dynamic, Eigen::Dynamic > &F, const Packet &packet, const Potential &V)
Definition: basic_steps.hpp:136
Propagate one step with the quadratic potential part U.
Definition: basic_steps.hpp:82
function L
Definition: jquery.js:16
static void apply(Packet &packet, const Potential &V, const real_t &delta_t)
Definition: basic_steps.hpp:171
Eigen::Matrix< complex_t, R, C > CMatrix
Definition: types.hpp:19
Definition: squeeze.hpp:7
static void apply(int i, const Potential &V, HaWpParamSet< D > &params, const real_t &delta_t)
Definition: basic_steps.hpp:64
static void apply(HaWpParamSet< D > &params, const real_t &delta_t)
Definition: basic_steps.hpp:26
int dim_t
Definition: types.hpp:16
Propagate one step with the kinetic operator T.
Definition: basic_steps.hpp:25