C++QEDCore  v2 Milestone 10
a framework for simulating open quantum dynamics – core
ElementLiouvillean.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)
2 // -*- C++ -*-
4 #ifndef CPPQEDCORE_STRUCTURE_ELEMENTLIOUVILLEAN_H_INCLUDED
5 #define CPPQEDCORE_STRUCTURE_ELEMENTLIOUVILLEAN_H_INCLUDED
6 
7 #include "ElementLiouvilleanFwd.h"
8 
9 #include "Liouvillean.h"
11 
12 #include <boost/function.hpp>
13 
14 #include <boost/mpl/for_each.hpp>
15 
16 
17 namespace structure {
18 
19 
21 namespace lindblad {
22 
23 
25 
26 template<int NLINDBLADS>
27 class Base
28 {
29 protected:
31  template<int LINDBLAD_ORDINAL, typename OTHER=typename boost::enable_if_c< (LINDBLAD_ORDINAL<NLINDBLADS) >::type>
32  class LindbladNo : mpl::int_<LINDBLAD_ORDINAL> {};
33 
34 };
35 
36 
38 
49 template<int RANK, int LINDBLAD_ORDINAL, bool IS_TIME_DEPENDENT, int NLINDBLADS=LINDBLAD_ORDINAL+1>
50 class _ : public mpl::if_c<LINDBLAD_ORDINAL,_<RANK,LINDBLAD_ORDINAL-1,IS_TIME_DEPENDENT,NLINDBLADS>,Base<NLINDBLADS> >::type
51 {
52 public:
54 
56  void typeErasedActWithJ(Time t, typename quantumdata::Types<RANK>::StateVectorLow& psi) const {doActWithJ(t,psi,typename Base<NLINDBLADS>::template LindbladNo<LINDBLAD_ORDINAL>());}
57 
59  double typeErasedRate(Time t, const quantumdata::LazyDensityOperator<RANK>& matrix) const {return rate(t,matrix,typename Base<NLINDBLADS>::template LindbladNo<LINDBLAD_ORDINAL>());}
60 
61 private:
62  virtual void doActWithJ(Time, typename quantumdata::Types<RANK>::StateVectorLow&, typename Base<NLINDBLADS>::template LindbladNo<LINDBLAD_ORDINAL>) const = 0;
63 
64  virtual double rate(Time, const quantumdata::LazyDensityOperator<RANK>&, typename Base<NLINDBLADS>::template LindbladNo<LINDBLAD_ORDINAL>) const = 0;
65 
66 };
67 
68 
69 } // lindblad
70 
71 
74 {
75  ElementLiouvilleanException(const std::string& tag) : cpputils::TaggedException(tag) {}
76 };
77 
78 
80 
93 template<int RANK, int NLINDBLADS, bool IS_TIME_DEPENDENT>
94 class ElementLiouvillean : public ElementLiouvilleanAveragedCommon<LiouvilleanTimeDependenceDispatched<RANK,IS_TIME_DEPENDENT> >,
95  public lindblad::_<RANK,NLINDBLADS-1,false>
96 {
97 private:
99 
100 public:
101  typedef typename Base::StateVectorLow StateVectorLow;
102 
103  typedef typename Base::LazyDensityOperator LazyDensityOperator;
104 
105  typedef typename Base::Rates Rates;
106 
107  typedef typename Base::Time Time;
108 
109 protected:
110  template<typename... KeyLabelsPack>
111  ElementLiouvillean(const std::string& keyTitle, KeyLabelsPack&&... keyLabelsPack) : Base(keyTitle,keyLabelsPack...) {}
112 
113  ElementLiouvillean(const std::string& keyTitle, typename Base::KeyLabelsInitializer il) : Base(keyTitle,il) {}
114 
115 private:
116  class Average
117  {
118  public:
119  Average(const ElementLiouvillean* ptr, Rates& rates, Time t, const LazyDensityOperator& matrix) : ptr_(ptr), rates_(rates), t_(t), matrix_(matrix) {}
120 
121  template<typename T> void operator()(T) const {rates_(T::value)=static_cast<const lindblad::_<RANK,T::value,false,NLINDBLADS>*const>(ptr_)->typeErasedRate(t_,matrix_);}
122 
123  private:
124  const ElementLiouvillean*const ptr_;
125  Rates& rates_;
126  const Time t_;
127  const LazyDensityOperator& matrix_;
128  };
129 
130  virtual const Rates rates_v(Time t, const LazyDensityOperator& matrix) const final {Rates rates(NLINDBLADS); mpl::for_each<tmptools::Ordinals<NLINDBLADS> >(Average(this,rates,t,matrix)); return rates;}
131 
132  class ActWithJ
133  {
134  public:
135  ActWithJ(const ElementLiouvillean* ptr, Time t, StateVectorLow& psi, size_t lindbladNo) : ptr_(ptr), t_(t), psi_(psi), lindbladNo_(lindbladNo) {}
136 
137  template<typename T>
138  void operator()(T) const {if (T::value==lindbladNo_) static_cast<const lindblad::_<RANK,T::value,false,NLINDBLADS>*const>(ptr_)->typeErasedActWithJ(t_,psi_);}
139 
140  private:
141  const ElementLiouvillean*const ptr_;
142  const Time t_;
143  StateVectorLow& psi_;
144  const size_t lindbladNo_;
145  };
146 
147  virtual void actWithJ_v(Time t, StateVectorLow& psi, size_t lindbladNo) const final {if (lindbladNo>=NLINDBLADS) throw ElementLiouvilleanException(Base::getTitle()); mpl::for_each<tmptools::Ordinals<NLINDBLADS> >(ActWithJ(this,t,psi,lindbladNo));}
148 
149 };
150 
151 
152 
154 
161 template<int RANK, bool IS_TIME_DEPENDENT>
162 class ElementLiouvillean<RANK,1,IS_TIME_DEPENDENT> : public ElementLiouvilleanAveragedCommon<LiouvilleanTimeDependenceDispatched<RANK,IS_TIME_DEPENDENT> >
163 {
164 private:
166 
167 public:
168  typedef typename Base::StateVectorLow StateVectorLow;
169 
170  typedef typename Base::LazyDensityOperator LazyDensityOperator;
171 
172  typedef typename Base::Rates Rates;
173 
174  typedef typename Base::Time Time;
175 
176 protected:
177  ElementLiouvillean(const std::string& keyTitle, const std::string& keyLabel) : Base(keyTitle,1,keyLabel) {}
178 
179 private:
180  virtual const Rates rates_v(Time t, const LazyDensityOperator& matrix) const final {Rates rates(1); rates(0)=rate(t,matrix); return rates;}
181 
182  virtual void actWithJ_v(Time t, StateVectorLow& psi, size_t lindbladNo) const final {if (lindbladNo) throw ElementLiouvilleanException(Base::getTitle()); doActWithJ(t,psi);}
183 
184  virtual void doActWithJ(Time, StateVectorLow&) const = 0;
185 
186  virtual double rate(Time, const LazyDensityOperator&) const = 0;
187 
188 };
189 
190 
192 
199 template<int RANK, int NLINDBLADS, bool IS_TIME_DEPENDENT>
200 class ElementLiouvilleanStrategies : public ElementLiouvilleanAveragedCommon<LiouvilleanTimeDependenceDispatched<RANK,IS_TIME_DEPENDENT> >
201 {
202 private:
204 
205 public:
206  typedef typename Base::StateVectorLow StateVectorLow;
207 
208  typedef typename Base::LazyDensityOperator LazyDensityOperator;
209 
210  typedef typename Base::Rates Rates;
211 
212  typedef typename Base::Time Time;
213 
215 
216  typedef typename mpl::if_c<IS_TIME_DEPENDENT,boost::function<void (double, StateVectorLow& )>,boost::function<void ( StateVectorLow& )> >::type JumpStrategy;
218  typedef typename mpl::if_c<IS_TIME_DEPENDENT,boost::function<double(double, const LazyDensityOperator&)>,boost::function<double(const LazyDensityOperator&)> >::type JumpRateStrategy;
219 
221  typedef blitz::TinyVector<JumpStrategy ,NLINDBLADS> JumpStrategies;
223  typedef blitz::TinyVector<JumpRateStrategy,NLINDBLADS> JumpRateStrategies;
224 
225 protected:
226  template<typename... KeyLabelsPack>
227  ElementLiouvilleanStrategies(const JumpStrategies& jumps, const JumpRateStrategies& jumpRates, const std::string& keyTitle, KeyLabelsPack&&... keyLabelsPack)
228  : Base(keyTitle,keyLabelsPack...), jumps_(jumps), jumpRates_(jumpRates) {}
229 
230  ElementLiouvilleanStrategies(const JumpStrategies& jumps, const JumpRateStrategies& jumpRates, const std::string& keyTitle, typename Base::KeyLabelsInitializer il)
231  : Base(keyTitle,il), jumps_(jumps), jumpRates_(jumpRates) {}
232 
233 private:
234  virtual const Rates rates_v(Time t, const LazyDensityOperator& matrix) const final;
235 
236  virtual void actWithJ_v(Time t, StateVectorLow& psi, size_t lindbladNo) const final;
237 
238  const JumpStrategies jumps_ ;
239  const JumpRateStrategies jumpRates_;
240 
241 };
242 
243 
244 } // structure
245 
246 
247 #endif // CPPQEDCORE_STRUCTURE_ELEMENTLIOUVILLEAN_H_INCLUDED
248 
249 
Metafunction dispatching two OneTime & NoTime according to the template parameter IS_TIME_DEPENDENT ...
A tagging class for Lindblad.
const Rates rates(double t, const StateVector &psi) const
Returns the set of jump rates where the Lindblads are in general time-dependent. ...
Definition: Liouvillean.h:61
mpl::if_c< IS_TIME_DEPENDENT, boost::function< void(double, StateVectorLow &)>, boost::function< void(StateVectorLow &)> >::type JumpStrategy
Strategy functional for acting with a given Lindblad operator (= performing a given jump) on a state...
Thrown if the Lindblad index is not smaller than the total number of Lindblads.
void typeErasedActWithJ(Time t, typename quantumdata::Types< RANK >::StateVectorLow &psi) const
calls the virtual doActWithJ for the given LINDBLAD_ORDINAL
Class reporting also the “what-ness” of the exception.
Definition: Exception.h:25
blitz::TinyVector< JumpStrategy,NLINDBLADS > JumpStrategies
Tiny vector of length NLINDBLADS containing the JumpStrategy instances.
blitz::TinyVector< JumpRateStrategy, NLINDBLADS > JumpRateStrategies
Tiny vector of length NLINDBLADS containing the JumpRateStrategy instances.
Comprises modules for describing quantum systems.
Definition: Averaged.h:17
double typeErasedRate(Time t, const quantumdata::LazyDensityOperator< RANK > &matrix) const
calls the virtual rate for the given LINDBLAD_ORDINAL
A class to encapsulate Base::LindbladNo, so that the latter has information about the number of Lindb...
Implements LiouvilleanAveragedCommon::displayKey and LiouvilleanAveragedCommon::nAvr with the help of...
Class defining the virtual functions corresponding to a single Lindblad…
Defines class of the same name.
mpl::if_c< IS_TIME_DEPENDENT, boost::function< double(double, const LazyDensityOperator &)>, boost::function< double(const LazyDensityOperator &)> >::type JumpRateStrategy
Strategy functional for calculating from a state the jump rate corresponding to a given Lindblad...
Common interface for calculating quantum averages.
Besides ElementLiouvillean, this is another solution based on the strategy idiom to control the numbe...
An implementation of Liouvillean for the case when the number of Lindblads is known @ compile time (w...
Defines class of the same name.
Base::DArray1D Rates
The 1D real array for storing the jump rates.
Definition: Liouvillean.h:55