-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathphysics.h
More file actions
68 lines (55 loc) · 1.92 KB
/
Copy pathphysics.h
File metadata and controls
68 lines (55 loc) · 1.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#ifndef __CXX_UTIL_PHYSICS_H__
#define __CXX_UTIL_PHYSICS_H__
#include <armadillo>
#include <tuple>
#include "math_helper.h"
namespace cxut {
// sigma_x and sigma_p of the Wigner quasiprobability distribution of harmonic oscillators
inline std::tuple<double, double> ho_wigner(double const& mass, double const& omega, double const& kT = 0) {
double sigma_x, sigma_p;
if (kT < arma::datum::eps) {
sigma_x = std::sqrt(0.5 / mass / omega);
sigma_p = std::sqrt(0.5 * omega * mass);
} else {
sigma_x = std::sqrt( 0.5 / mass / omega / std::tanh(omega/2.0/kT) );
sigma_p = std::sqrt( 0.5 * mass * omega / std::tanh(omega/2.0/kT) );
}
return std::make_tuple(sigma_x, sigma_p);
}
// Boltzmann weight
inline arma::vec boltzmann(arma::vec const& E, double const& kT) {
arma::uword imin = E.index_min();
arma::vec v;
if ( std::abs(kT) < arma::datum::eps ) {
v.zeros(E.n_elem);
v(imin) = 1.0;
return v;
}
v = arma::exp(-(E-E(imin))/kT);
return v / accu(v);
}
// Fermi function
inline double fermi(double const& E, double const& mu, double const& kT) {
return ( std::abs(kT) < arma::datum::eps ) ?
(E <= mu) : 1.0 / ( std::exp( (E - mu) / kT ) + 1.0 );
}
inline arma::vec fermi(arma::vec const& E, double const& mu, double const& kT) {
return ( std::abs(kT) < arma::datum::eps ) ?
arma::conv_to<arma::vec>::from(E <= mu) : 1.0 / ( exp( (E - mu) / kT ) + 1.0 );
}
// solve for the chemical potential given E, N and kT
inline int findmu(double& mu, arma::vec const& E, arma::uword const& N, double const& kT = 0.0) {
if ( N > E.n_elem ) {
std::cerr << "findmu: there are more particles than energy levels." << std::endl;
return -1;
}
if ( std::abs(kT) < arma::datum::eps ) {
mu = arma::sort(E, "ascend").eval()(N-1);
return 0;
}
auto dn = [&] (double const& mu) { return arma::accu(fermi(E, mu, kT)) - N; };
mu = E(0);
return broydenroot(dn, mu, 1e-12);
}
}
#endif