00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef PHYSICS_BCS_H
00033 #define PHYSICS_BCS_H
00034
00035 #include <algorithm>
00036 #include <vector>
00037 #include <more/gen/iterator.h>
00038 #include <more/math/math.h>
00039
00040
00041 namespace more {
00042 namespace phys {
00043
00044
00045
00046
00047 template<typename T>
00048 struct BCS_solver
00049 {
00050 typedef T real_type;
00051 private:
00052 typedef std::vector<real_type> energy_container;
00053 typedef typename energy_container::iterator energy_iterator;
00054 public:
00055 typedef typename energy_container::size_type size_type;
00056
00057 BCS_solver(int N, real_type G,
00058 real_type cut_low, real_type cut_high,
00059 real_type cut_width)
00060 : m_is_solved(false),
00061 m_n_occ(N), m_G(G),
00062 m_do_smooth_cut(true),
00063 m_cut_low(cut_low), m_cut_high(cut_high),
00064 m_cut_width(cut_width),
00065 m_prec(s_prec_default),
00066 m_n_iter_max(200),
00067 m_is_verbose(false) {}
00068
00069 BCS_solver(int N, real_type G)
00070 : m_is_solved(false),
00071 m_n_occ(N), m_G(G),
00072 m_do_smooth_cut(false),
00073 m_prec(s_prec_default),
00074 m_n_iter_max(200),
00075 m_is_verbose(false) {}
00076
00077 BCS_solver()
00078 : m_is_solved(false),
00079 m_n_occ(0), m_G(0),
00080 m_do_smooth_cut(false),
00081 m_prec(s_prec_default),
00082 m_n_iter_max(200),
00083 m_is_verbose(false) {}
00084
00085
00086 void set_coupling_strength(real_type G) { m_G = G; }
00087
00088
00089 real_type coupling_strength() const { return m_G; }
00090
00091
00092
00093 void set_occupied_count(size_type n) { m_n_occ = n; }
00094
00095
00096 real_type occupied_count() const { return m_n_occ; }
00097
00098
00099 void set_precision(real_type prec) { m_prec = prec; }
00100
00101
00102 real_type precision() const { return m_prec; }
00103
00104
00105
00106
00107 void set_smooth_cutoff(real_type cut_low, real_type cut_high,
00108 real_type cut_width);
00109
00110
00111
00112 bool smooth_cut(real_type& cut_low, real_type& cut_high,
00113 real_type& cut_width);
00114
00115 void solve();
00116
00117
00118 template<typename Iterator>
00119 void solve(Iterator first, Iterator last)
00120 {
00121 m_energies.clear();
00122 m_energies.resize(std::distance(first, last));
00123 std::copy(first, last, m_energies.begin());
00124 solve();
00125 }
00126
00127
00128
00129 real_type sqr_v(real_type epsilon)
00130 {
00131 req_solved();
00132 real_type eml = epsilon - m_lambda;
00133 return .5 - .5*eml/sqrt(eml*eml + m_Delta2);
00134 }
00135
00136
00137
00138 real_type sqr_u(real_type epsilon)
00139 {
00140 req_solved();
00141 real_type eml = epsilon - m_lambda;
00142 return .5 + .5*eml/sqrt(eml*eml + m_Delta2);
00143 }
00144
00145 void write_to(std::ostream& out) const;
00146
00147
00148
00149 real_type pairing_energy() { req_solved(); return m_E_pair; }
00150
00151
00152
00153 real_type pairing_Delta() { req_solved(); return m_Delta; }
00154
00155
00156
00157 real_type Fermi_energy() { req_solved(); return m_lambda; }
00158
00159 real_type cut_function(real_type epsilon)
00160 {
00161 return internal_cut_function(epsilon-m_lambda);
00162 }
00163
00164
00165 void be_verbose(bool value = true) { m_is_verbose = value; }
00166
00167
00168 bool is_verbose() const { return m_is_verbose; }
00169
00170 private:
00171 bool m_is_solved;
00172 size_type m_n_occ;
00173 real_type m_G;
00174
00175 bool m_do_smooth_cut;
00176 real_type m_cut_low, m_cut_high, m_cut_width;
00177
00178 real_type m_E_pair, m_E_pair_nocorr;
00179 real_type m_Delta, m_Delta2;
00180 real_type m_lambda;
00181
00182 real_type m_prec;
00183 int m_n_iter_max;
00184 std::vector<real_type> m_energies;
00185
00186 bool m_is_verbose;
00187
00188 static real_type s_prec_default;
00189
00190 real_type
00191 internal_cut_function(real_type eml) const
00192 {
00193 if(m_do_smooth_cut)
00194 return 1/(1 + exp((eml-m_cut_high)/m_cut_width)
00195 + exp(-(eml-m_cut_low)/m_cut_width));
00196 else
00197 return 1.0;
00198 }
00199
00200 void
00201 req_solved() const
00202 {
00203 if (!m_is_solved)
00204 throw std::logic_error("more::phys::BCS_solver: "
00205 "The equations are not solved yet.");
00206 }
00207 };
00208
00209 template<typename T>
00210 inline std::ostream&
00211 operator<<(std::ostream& os, const BCS_solver<T>& bcs)
00212 {
00213 bcs.write_to(os); return os;
00214 }
00215
00216 }}
00217
00218 #endif