C++QEDElements  v2 Milestone 10
a framework for simulating open quantum dynamics – generic elements
MultiLevel_.h
Go to the documentation of this file.
1 // Copyright András Vukics 2006–2014. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.txt)
3 // -*- C++ -*-
4 #ifndef CPPQEDELEMENTS_FREES_MULTILEVEL__H_INCLUDED
5 #define CPPQEDELEMENTS_FREES_MULTILEVEL__H_INCLUDED
6 
7 #include "MultiLevel_Fwd.h"
8 
9 #include "ParsMultiLevel.h"
10 
11 #include "AveragingUtils.tcc"
12 
13 #include "ElementAveraged.h"
14 #include "ElementLiouvillean.h"
15 #include "Free.h"
16 #include "FreeExact.h"
17 #include "Hamiltonian.h"
18 
19 #include <boost/fusion/mpl/size.hpp>
20 
21 #include <boost/shared_ptr.hpp>
22 
23 
25 namespace multilevel {
26 
27 
28 const std::string keyTitle="MultiLevel";
29 
30 
31 using namespace structure::freesystem;
32 
33 
34 template<int NL>
35 struct LevelsMF : mpl::identity<blitz::TinyVector<dcomp,NL> > {};
36 
37 
38 template<int NL>
39 struct RealLevelsMF : mpl::identity<blitz::TinyVector<double,NL> > {};
40 
41 
42 
44 //
45 // Exact
46 //
48 
50 
52 template<int NL>
53 class Exact : public structure::FreeExact<false>
54 {
55 public:
56  typedef typename LevelsMF<NL>::type Levels;
57 
58  Exact(const Levels& zIs) : FreeExact<false>(NL), zIs_(zIs) {}
59 
60  const Levels& get_zIs() const {return zIs_;}
61 
62 private:
63  void updateU(double) const;
64 
65  bool applicableInMaster_v() const;
66 
67  const Levels zIs_;
68 
69 };
70 
71 
72 
74 //
75 // Hamiltonian
76 //
78 
79 
80 template<typename T>
81 class Storage
82 {
83 public:
84  Storage(const T& value) : value_(value) {}
85 
86  const T& get() const {return value_;}
87  void set(const T& value) {value_=value;}
88 
89 private:
90  T value_;
91 
92 };
93 
94 
95 template<>
96 class Storage<double>
97 {
98 public:
99  Storage(double value) : value_(value) {}
100 
101  double get() const {return value_;}
102  void set(double value) {value_=value;}
103 
104 private:
105  double value_;
106 
107 };
108 
109 
110 
111 template<typename T>
112 inline
113 std::ostream& operator<<(std::ostream& os, const Storage<T>& s)
114 {
115  return os<<s.get();
116 }
117 
118 
119 template<typename T>
120 inline
121 std::istream& operator>>(std::istream& is, Storage<T>& s)
122 {
123  T temp; is>>temp;
124  s.set(temp);
125  return is;
126 }
127 
128 
130 template<int I, int J>
131 class Pump : public Storage<dcomp>, public tmptools::pair_c<I,J>
132 {
133 public:
134  typedef Storage<dcomp> Base;
135 
136  Pump(const dcomp& value) : Base(value) {}
137  Pump() : Base(dcomp()) {}
138 
139 };
140 
141 
142 template<int NL, typename VP>
144  : public structure::Hamiltonian<1>,
145  public Exact<NL>
146 {
147 public:
148  static const int NPT=mpl::size<VP>::value; // number of pumped transitions
149 
150  typedef typename Exact<NL>::Levels Levels;
151 
152  HamiltonianIP(const Levels& zSchs, const Levels& zIs, const VP& etas)
153  : Exact<NL>(zIs), zSchs_(zSchs), etas_(etas) {}
154 
155 private:
156  void addContribution_v(double, const StateVectorLow&, StateVectorLow&, double) const;
157 
158 
159  const Levels zSchs_;
160 
161  const VP etas_;
162 
163 };
164 
165 
166 template<int NL, typename VP>
168  : public structure::HamiltonianTimeDependenceDispatched<1,structure::NO_TIME>
169 {
170 public:
171  static const int NPT=mpl::size<VP>::value; // number of pumped transitions
172 
173  typedef typename LevelsMF<NL>::type Levels;
174 
175  HamiltonianSch(const Levels& zSchs, const VP& etas) : zSchs_(zSchs), etas_(etas) {}
176 
177  const Levels& get_zSchs() const {return zSchs_;}
178 
179 private:
180  void addContribution_v(structure::NoTime, const StateVectorLow&, StateVectorLow&) const;
181 
182 
183  const Levels zSchs_;
184 
185  const VP etas_;
186 
187 };
188 
189 
191 //
192 // Liouvillean
193 //
195 
196 
198 template<int I, int J>
199 class Decay : public Storage<double>, public tmptools::pair_c<I,J>
200 {
201 public:
202  typedef Storage<double> Base;
203 
204  Decay(double value) : Base(value) {}
205  Decay() : Base(0) {}
206 
207 };
208 
209 
210 template<int NL, typename VL>
211 class Liouvillean : public structure::ElementLiouvilleanStrategies<1,mpl::size<VL>::value>
212 // Note that, at some point, the Fusion sequence VL needs to be converted into a runtime sequence (JumpStrategies & JumpRateStrategies)
213 {
214 public:
215  static const int NLT=mpl::size<VL>::value; // number of lossy transitions
216 
218 
219  typedef typename Base::JumpStrategies JumpStrategies ;
220  typedef typename Base::JumpRateStrategies JumpRateStrategies;
221 
222  static_assert( blitzplusplus::TinyVectorLengthTraits<JumpRateStrategies>::value==NLT , "Jump number inconsistent." );
223 
224  typedef typename Base::KeyLabels KeyLabels;
225 
226  Liouvillean(const VL& gammas) : Base(Liouvillean::fillJS(),Liouvillean::fillJRS(),keyTitle,fillKeyLabels()), gammas_(gammas) {}
227 
228  const JumpStrategies fillJS () const;
229  const JumpRateStrategies fillJRS() const;
230 
231  static const KeyLabels fillKeyLabels();
232 
233 private:
234  template<int>
235  void jumpStrategy(StateVectorLow&) const;
236 
237  template<int>
238  double jumpRateStrategy(const LazyDensityOperator&) const;
239 
240  // NEED_TO_UNDERSTAND can member TEMPLATES be passed as template parameters? This would be needed to fuse fillJS and fillJRS into a template together with the helper classes below
241 
242  class JS_helper;
243  class JRS_helper;
244 
245  class KeyHelper;
246 
247  const VL gammas_;
248 
249 };
250 
251 
252 
254 //
255 // Averaged
256 //
258 
259 
260 } // multilevel
261 
262 
264 //
265 // Highest level
266 //
268 
269 
270 template<int NL>
272  : public structure::Free
273 {
274 public:
275  typedef boost::shared_ptr<const MultiLevelBase> Ptr;
276 
278 
279  MultiLevelBase(const RealFreqs& realFreqs=RealFreqs(), const ComplexFreqs& complexFreqs=ComplexFreqs())
280  : structure::Free(NL,realFreqs,complexFreqs)
281  {
282  getParsStream()<<"# "<<multilevel::keyTitle<<std::endl;
283  }
284 
285  virtual ~MultiLevelBase() {}
286 
287 };
288 
289 
291 
298 template<int NL, typename VP, typename VL, typename AveragingType>
300  : public multilevel::HamiltonianSch<NL,VP>,
301  public multilevel::Liouvillean<NL,VL>,
302  public MultiLevelBase<NL>,
303  public AveragingType
304  // The ordering becomes important here
305 {
306 public:
307  typedef typename multilevel:: LevelsMF<NL>::type Levels;
308  typedef typename multilevel::RealLevelsMF<NL>::type RealLevels;
309 
312  typedef MultiLevelBase<NL> Base;
313 
314  typedef typename Base::Ptr Ptr;
315 
316  template<typename... AveragingConstructorParameters>
317  PumpedLossyMultiLevelSch(const RealLevels&, const VP&, const VL&, AveragingConstructorParameters&&...);
318 
319 };
320 
321 
322 
323 namespace multilevel {
324 
325 #define RETURN_type typename MultiLevelBase<NL>::Ptr
326 
328 template<typename AveragingType, int NL, typename VP, typename VL, typename... AveragingConstructorParameters>
329 inline
330 RETURN_type
331 makePumpedLossySch(const blitz::TinyVector<double,NL>& deltas,
332  // note that, understandably, if we write
333  // const typename RealLevelsMF<NL>::type&
334  // here, the compiler cannot deduce NL anymore
335  const VP& etas, const VL& gammas,
336  AveragingConstructorParameters&&... a)
337 {
338  return boost::make_shared<PumpedLossyMultiLevelSch<NL,VP,VL,AveragingType> >(deltas,etas,gammas,a...);
339 }
340 
342 template<typename AveragingType, int NL, typename VP, typename VL, typename... AveragingConstructorParameters>
343 inline
344 RETURN_type
345 makePumpedLossySch(const multilevel::ParsPumpedLossy<NL,VP,VL>& p, AveragingConstructorParameters&&... a)
346 {
347  return makePumpedLossySch<AveragingType>(p.deltas,p.etas,p.gammas,a...);
348 }
349 
351 template<int NL, typename VP, typename VL>
352 inline
353 RETURN_type
354 makePumpedLossySch(const blitz::TinyVector<double,NL>& deltas, const VP& etas, const VL& gammas, const std::string& keyTitle="PumpedLossyMultiLevelSch", bool offDiagonals=false)
355 {
356  return makePumpedLossySch<ReducedDensityOperator<1> >(deltas,etas,gammas,keyTitle,NL,offDiagonals);
357 }
358 
360 template<int NL, typename VP, typename VL>
361 inline
362 RETURN_type
363 makePumpedLossySch(const multilevel::ParsPumpedLossy<NL,VP,VL>& p, const std::string& keyTitle="PumpedLossyMultiLevelSch", bool offDiagonals=false)
364 {
365  return makePumpedLossySch<ReducedDensityOperator<1> >(p,keyTitle,NL,offDiagonals);
366 }
367 
368 
369 #undef RETURN_type
370 
371 } // multilevel
372 
373 
374 #endif // CPPQEDELEMENTS_FREES_MULTILEVEL__H_INCLUDED
Contains helpers for the MultiLevel bundle.
Definition: MultiLevel_.h:25
RETURN_type makePumpedLossySch(const blitz::TinyVector< double, NL > &deltas, const VP &etas, const VL &gammas, AveragingConstructorParameters &&...a)
Maker function for PumpedLossyMultiLevelSch.
Definition: MultiLevel_.h:331
boost::shared_ptr< const QuantumSystem > Ptr
quantumdata::Types< 1 >::StateVectorLow StateVectorLow
std::list< CF > ComplexFreqs
blitz::TinyVector< JumpStrategy, NLINDBLADS > JumpStrategies
blitz::TinyVector< JumpRateStrategy, NLINDBLADS > JumpRateStrategies
std::istream & operator>>(std::istream &, Method &)
std::list< RF > RealFreqs
Class representing an elementary pump term (an here) with a compile-time pair and a runtime complex...
Definition: MultiLevel_.h:131
Implements a free multi-level system with driving and loss.
Definition: MultiLevel_.h:299
Class representing an elementary decay term (a here) with a compile-time pair and a runtime real va...
Definition: MultiLevel_.h:199
std::ostringstream & getParsStream()
std::complex< double > dcomp