KIDS  ver-0.0.1
KIDS : Kernel Integrated Dynamics Simulator
Loading...
Searching...
No Matches
Model_Bath.cpp
Go to the documentation of this file.
1#include "kids/Model_Bath.h"
2
3#include "kids/hash_fnv1a.h"
4#include "kids/macro_utils.h"
5#include "kids/vars_list.h"
6
7namespace PROJECT_NS {
8
9const std::string Model_Bath::getName() { return "Model_Bath"; }
10
12
13double Model_Bath::J_Debye(double w) { return 2 * lambda * omegac * w / (w * w + omegac * omegac); }
14
15double Model_Bath::J_Ohmic(double w) { return phys::math::pi * lambda / omegac * w * std::exp(-w / omegac); }
16
17double Model_Bath::J(double w, double* w_arr, double* c_arr, int Nb) {
18 if (w < 0) return -J(-w, w_arr, c_arr, Nb);
19 if (w_arr == nullptr || c_arr == nullptr || Nb <= 0 || w / w_arr[Nb - 1] > 0.1)
20 throw std::runtime_error("J(w) fitting error!");
21
22 double a = 10e0 * Nb * Nb / (w_arr[Nb - 1] * w_arr[Nb - 1]);
23 double Jw = 0.0;
24 for (int j = 0; j < Nb; ++j) {
25 Jw += c_arr[j] * c_arr[j] / w_arr[j] * std::exp(-a * (w - w_arr[j]) * (w - w_arr[j]));
26 }
27 Jw *= 0.5e0 * phys::math::halfpi * std::sqrt(a / phys::math::pi);
28 return Jw;
29}
30
31int Model_Bath::fun_Cw(kids_complex* Cw, double* w, int Nw, double* w_arr, double* c_arr, double beta, int Nb) {
32 double dw = std::min({1.0e-5, w_arr[0] / 10, w_arr[Nb - 1] / 1000});
33 double C0_Re = (J(dw, w_arr, c_arr, Nb) - J(-dw, w_arr, c_arr, Nb)) / (2 * beta * dw);
34 for (int i = 0; i < Nw; ++i) {
35 // the real part
36 Cw[i] = (w[i] == 0) ? C0_Re : J(w[i], w_arr, c_arr, Nb) * (1 + 1 / (exp(beta * w[i]) - 1.0f));
37 // the imaginary part
38 if (w[i] != 0) {
39 double sum = 0.0e0, tmp = 1.0e0, Cp, Cm;
40 double wp = w[i], wm = w[i];
41 int k = 0;
42 while (std::abs(tmp) > 1.0e-6 || std::abs(tmp / sum) > 1.0e-8) {
43 wp += dw, wm -= dw, k++;
44 Cp = (wp == 0) ? C0_Re : J(wp, w_arr, c_arr, Nb) * (1 + 1 / (exp(beta * wp) - 1.0f));
45 Cm = (wm == 0) ? C0_Re : J(wm, w_arr, c_arr, Nb) * (1 + 1 / (exp(beta * wm) - 1.0f));
46 tmp = (Cp - Cm) / (double) k;
47 sum += tmp;
48 }
49 Cw[i] += phys::math::im / phys::math::pi * (-sum);
50 }
51 }
52 return 0;
53}
54
55void Model_Bath::setInputParam_impl(std::shared_ptr<Param>& PM) {
56 // size information
57 Nb = _param->get_int("Nb", LOC());
58 bath_type = BathPolicy::_from(_param->get_string("bath_flag", LOC(), "Debye"));
59 omegac = _param->get_double("omegac", LOC(), phys::energy_d, 1.0f);
60 strength_type = StrengthPolicy::_from(_param->get_string("strength_flag", LOC(), "Lambda"));
61 classical_bath = _param->get_bool("classical_bath", LOC(), false);
62
63 switch (strength_type) {
64 case StrengthPolicy::Lambda: {
65 double strength = _param->get_double("strength", LOC(), phys::energy_d, 1.0f);
66 lambda = strength;
67 break;
68 }
69 case StrengthPolicy::Alpha: {
70 double strength = _param->get_double("strength", LOC(), 1.0f);
71 lambda = 0.5f * omegac * strength;
72 break;
73 }
74 case StrengthPolicy::Eta: {
75 double strength = _param->get_double("strength", LOC(), phys::energy_d, 1.0f);
76 lambda = 0.5f * strength;
77 break;
78 }
79 case StrengthPolicy::Erg: {
80 double strength = _param->get_double("strength", LOC(), phys::energy_d, 1.0f);
81 lambda = 0.25f * strength;
82 break;
83 }
84 }
85 double temperature = _param->get_double("temperature", LOC(), phys::temperature_d, 1.0f);
86 beta = 1.0f / (phys::au::k * temperature); // don't ignore k_Boltzman
87}
88
89void Model_Bath::setInputDataSet_impl(std::shared_ptr<DataSet>& DS) {
92 switch (bath_type) {
93 case BathPolicy::Debye: {
94 for (int j = 0; j < Nb; ++j) {
95 omegas[j] = omegac * std::tan(phys::math::halfpi * ((j + 1.0f) / (Nb + 1.0f)));
96 coeffs[j] = sqrt(2 * lambda / (Nb + 1.0f)) * omegas[j];
97 }
98 break;
99 }
100 case BathPolicy::Ohmic: {
101 for (int j = 0; j < Nb; ++j) {
102 omegas[j] = -omegac * std::log(1.0f - (j + 1.0f) / (Nb + 1.0f));
103 coeffs[j] = sqrt(2 * lambda / (Nb + 1.0f)) * omegas[j];
104 }
105 break;
106 }
107 case BathPolicy::Closure: {
108 break;
109 }
110 case BathPolicy::ReadFormula: {
111 break;
112 }
113 case BathPolicy::ReadFile: // #b850, #pbi, #rub
114 default: {
115 try {
116 std::string bath_readfile = _param->get_string("bath_readfile", LOC(), "bath.spectrum");
117 std::ifstream ifs(bath_readfile);
118
119 std::string firstline, unit_str1, unit_str2, DIS_FLAG;
120
121 // parse units of frequency & coefficients
122 getline(ifs, firstline);
123 std::stringstream sstr(firstline);
124 sstr >> unit_str1 >> unit_str2;
125
126 phys::uval uw = phys::us::parse(unit_str1);
127 // if (uw.dim != phys::energy_d) LOG(FATAL) << "need dimension of energy";
128 double w_unit = phys::us::conv(phys::au::unit, uw);
129
130 phys::uval uc = phys::us::parse(unit_str2);
131 // if (uc.dim != phys::energy_d) LOG(FATAL) << "need dimension of energy";
132 double c_unit = phys::us::conv(phys::au::unit, uc);
133
134 // read data lines
135 double val;
136 for (int j = 0; j < Nb; ++j) {
137 ifs >> DIS_FLAG;
138 if (DIS_FLAG == "WC") {
139 if (ifs >> val) omegas[j] = val / w_unit;
140 if (ifs >> val) coeffs[j] = val / pow(c_unit, 1.5e0);
141 } else if (DIS_FLAG == "WS") {
142 if (ifs >> val) omegas[j] = val / w_unit;
143 if (ifs >> val) coeffs[j] = 2.0f * sqrt(0.5f * omegas[j] * omegas[j] * omegas[j] * val);
144 } else if (DIS_FLAG == "WG") {
145 if (ifs >> val) omegas[j] = val / w_unit;
146 if (ifs >> val) coeffs[j] = 2.0f * sqrt(0.5f * omegas[j] * omegas[j] * omegas[j]) * val;
147 }
148 }
149 } catch (std::runtime_error& e) {
150 // LOG(FATAL) << "read spec.dat error";
151 }
152 }
153 }
154
157 for (int j = 0; j < Nb; ++j) {
158 /* note:
159 for finite temperature: Qoverbeta = 0.5*freq / dtanh(0.5*beta*freq)
160 for zero temperature: Qoverbeta = 0.5*freq
161 */
162 double Qoverbeta = (classical_bath)
163 ? ((beta > 0) ? 1.0f / beta : 0.0f)
164 : (0.5f * omegas[j] / (beta > 0 ? std::tanh(0.5f * beta * omegas[j]) : 1.0f));
165 x_sigma[j] = std::sqrt(Qoverbeta / (omegas[j] * omegas[j]));
166 p_sigma[j] = std::sqrt(Qoverbeta);
167 }
168}
169
170}; // namespace PROJECT_NS
std::shared_ptr< Param > _param
Shared pointer to the Param object associated with this kernel.
Definition Kernel.h:273
virtual int getType() const
Get the type of the kernel.
static int fun_Cw(kids_complex *Cw_arr, double *w, int Nw, double *w_arr, double *c_arr, double beta, int Nb)
StrengthPolicy::_type strength_type
Definition Model_Bath.h:37
BathPolicy::_type bath_type
Definition Model_Bath.h:36
double J_Ohmic(double w)
virtual const std::string getName()
Get the name of the kernel.
Definition Model_Bath.cpp:9
virtual void setInputParam_impl(std::shared_ptr< Param > &PM)
Virtual function to set input parameters for the kernel implementation.
virtual void setInputDataSet_impl(std::shared_ptr< DataSet > &DS)
Virtual function to set input data set for the kernel implementation.
static double J(double w, double *w_arr=nullptr, double *c_arr=nullptr, int Nb=0)
double J_Debye(double w)
static uval parse(const std::string &str)
Definition phys.h:790
CONSTEXPR_DECOR value_type conv(const uval &u)
Definition phys.h:772
#define LOC()
show the location information for debug
Definition fmt.h:49
#define FUNCTION_NAME
Definition macro_utils.h:9
VARIABLE< kids_real > p_sigma
VARIABLE< kids_real > x_sigma
VARIABLE< kids_real > omegas
VARIABLE< kids_real > coeffs
< http://warp.povusers.org/FunctionParser/fparser.html
Definition Context.h:39
std::complex< double > kids_complex
Alias for complex number type.
Definition Types.h:60
constexpr real_precision halfpi
Definition phys.h:32
constexpr real_precision pi
pi
Definition phys.h:30
constexpr std::complex< real_precision > im(0.0L, 1.0L)
Imaginary Unit.
constexpr dimension7 temperature_d
Definition phys.h:195
constexpr dimension7 energy_d
[M*L^2/T^2] force integrate length
Definition phys.h:251
constexpr uint32_t hash(const char *str)
Definition hash_fnv1a.h:12
declaration of variables used in the program.