• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wexlergroup / FreeBird.jl / 15026334252

14 May 2025 04:43PM UTC coverage: 95.771% (+0.8%) from 94.924%
15026334252

Pull #96

github

web-flow
Merge 47ea92959 into afefded03
Pull Request #96: Feature/distributed ns loop

95 of 107 new or added lines in 6 files covered. (88.79%)

1 existing line in 1 file now uncovered.

1540 of 1608 relevant lines covered (95.77%)

140537.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.92
/src/AnalysisTools/AnalysisTools.jl
1
"""
2
    AnalysisTools
3

4
Module for analyzing the output of the sampling.
5
"""
6
module AnalysisTools
7

8
using DataFrames
9
using CSV, Arrow
10

11
export read_output
12
export ωᵢ, partition_function, internal_energy, cv
13

14
"""
15
    read_output(filename::String)
16

17
Reads the output file and returns a DataFrame.
18
"""
19
function read_output(filename::String)
16✔
20
    if splitext(filename)[end] == ".csv"
16✔
21
        data = CSV.File(filename)
8✔
22
    elseif splitext(filename)[end] == ".arrow"
8✔
23
        data = Arrow.Table(filename)
8✔
24
    else
NEW
25
        error("Unsupported file format. Please provide a .csv or .arrow file.")
×
26
    end
27
    return DataFrame(data)
16✔
28
end
29

30
"""
31
    ωᵢ(iters::Vector{Int}, n_walkers::Int; n_cull::Int=1, ω0::Float64=1.0)
32

33
Calculates the \$\\omega\$ factors for the given number of iterations and walkers.
34
The \$\\omega\$ factors account for the fractions of phase-space volume sampled during
35
each nested sampling iteration, defined as:
36
```math
37
\\omega_i = \\frac{C}{K+C} \\left(\\frac{K}{K+C}\\right)^i
38
```
39
where \$K\$ is the number of walkers, \$C\$ is the number of culled walkers, 
40
and \$i\$ is the iteration number.
41

42
# Arguments
43
- `iters::Vector{Int}`: The iteration numbers.
44
- `n_walkers::Int`: The number of walkers.
45
- `n_cull::Int`: The number of culled walkers. Default is 1.
46
- `ω0::Float64`: The initial \$\\omega\$ factor. Default is 1.0.
47

48
# Returns
49
- A vector of \$\\omega\$ factors.
50
"""
51
function ωᵢ(iters::Vector{Int}, n_walkers::Int; n_cull::Int=1, ω0::Float64=1.0)
112✔
52
    ωi = ω0 * (n_cull/(n_walkers+n_cull)) * (n_walkers/(n_walkers+n_cull)).^iters
56✔
53
    return ωi
56✔
54
end
55

56
"""
57
    partition_function(β::Float64, ωi::Vector{Float64}, Ei::Vector{Float64})
58

59
Calculates the partition function for the given \$\\beta\$, \$\\omega\$ factors, and energies.
60
The partition function is defined as:
61
```math
62
Z(\\beta) = \\sum_i \\omega_i \\exp(-E_i \\beta)
63
```
64
where \$\\omega_i\$ is the \$i\$-th \$\\omega\$ factor, \$E_i\$ is the \$i\$-th energy, and \$\\beta\$ is the inverse temperature.
65

66
# Arguments
67
- `β::Float64`: The inverse temperature.
68
- `ωi::Vector{Float64}`: The \$\\omega\$ factors.
69
- `Ei::Vector{Float64}`: The energies.
70

71
# Returns
72
- The partition function.
73
"""
74
function partition_function(β::Float64, 
32✔
75
                            ωi::Vector{Float64}, 
76
                            Ei::Vector{Float64})
77
    z = sum(ωi.*exp.(-Ei.*β))
48✔
78
    return z
24✔
79
end
80

81
"""
82
    internal_energy(β::Float64, ωi::Vector{Float64}, ei::Vector{Float64})
83

84
Calculates the internal energy from the partition function for the given \$\\beta\$, \$\\omega\$ factors, and energies.
85
The internal energy is defined as:
86
```math
87
U(\\beta) = \\frac{\\sum_i \\omega_i E_i \\exp(-E_i \\beta)}{\\sum_i \\omega_i \\exp(-E_i \\beta)}
88
```
89
where \$\\omega_i\$ is the \$i\$-th \$\\omega\$ factor, \$E_i\$ is the \$i\$-th energy, and \$\\beta\$ is the inverse temperature.
90

91
# Arguments
92
- `β::Float64`: The inverse temperature.
93
- `ωi::Vector{Float64}`: The \$\\omega\$ factors.
94
- `Ei::Vector{Float64}`: The energies in eV.
95

96
# Returns
97
- The internal energy.
98
"""
99
function internal_energy(β::Float64, 
24✔
100
                         ωi::Vector{Float64}, 
101
                         Ei::Vector{Float64})
102
    u = sum(ωi.*Ei.*exp.(-Ei.*β))/sum(ωi.*exp.(-Ei.*β))
40✔
103
    return u
24✔
104
end
105

106
"""
107
    cv(β::Float64, omega_i::Vector{Float64}, Ei::Vector{Float64}, dof::Int)
108

109
Calculates the constant-volume heat capacity for the given \$\\beta\$, \$\\omega\$ factors, energies, and degrees of freedom.
110
The heat capacity is defined as:
111
```math
112
C_V(\\beta) = \\frac{\\mathrm{dof} \\cdot k_B}{2} + k_B \\beta^2 \\left(\\frac{\\sum_i \\omega_i E_i^2 \\exp(-E_i \\beta)}{Z(\\beta)} - U(\\beta)^2\\right)
113
```
114
where \$\\mathrm{dof}\$ is the degrees of freedom, \$k_B\$ is the Boltzmann constant (in units of eV/K), \$\\beta\$ is the inverse temperature, 
115
\$\\omega_i\$ is the \$i\$-th \$\\omega\$ factor, \$E_i\$ is the \$i\$-th energy, \$Z(\\beta)\$ is the partition function, and \$U(\\beta)\$ is the internal energy.
116

117
# Arguments
118
- `β::Float64`: The inverse temperature.
119
- `ωi::Vector{Float64}`: The \$\\omega\$ factors.
120
- `Ei::Vector{Float64}`: The energies in eV.
121
- `dof::Int`: The degrees of freedom, equals to the number of dimensions times the number of particles.
122

123
# Returns
124
- The constant-volume heat capacity.
125
"""
126
function cv(β::Float64,
128✔
127
            ωi::Vector{Float64}, 
128
            Ei::Vector{Float64},
129
            dof::Int64;
130
            kb::Float64=8.617333262e-5)
131
    expo = ωi.*exp.(-Ei.*β)
120✔
132
    ei_expo = Ei.*expo
112✔
133
    ei2_expo = Ei.*ei_expo
112✔
134
    z = sum(expo)
104✔
135
    u = sum(ei_expo)/z
104✔
136
    cv = dof*kb/2.0 + kb*β^2 * (sum(ei2_expo)/z - u^2)
104✔
137
    return cv
56✔
138
end
139

140
"""
141
    cv(df::DataFrame, βs::Vector{Float64}, dof::Int, n_walkers::Int)
142

143
(Nested Sampling) Calculates the constant-volume heat capacity at constant volume for the given DataFrame, inverse temperatures, degrees of freedom, and number of walkers.
144
The heat capacity is defined as:
145
```math
146
C_V(\\beta) = \\frac{\\mathrm{dof} \\cdot k_B}{2} + k_B \\beta^2 \\left(\\frac{\\sum_i \\omega_i E_i^2 \\exp(-E_i \\beta)}{Z(\\beta)} - U(\\beta)^2\\right)
147
```
148
where \$\\mathrm{dof}\$ is the degrees of freedom, \$k_B\$ is the Boltzmann constant (in units of eV/K), \$\\beta\$ is the inverse temperature,
149
\$\\omega_i\$ is the \$i\$-th \$\\omega\$ factor, \$E_i\$ is the \$i\$-th energy, \$Z(\\beta)\$ is the partition function, and \$U(\\beta)\$ is the internal energy.
150

151
# Arguments
152
- `df::DataFrame`: The DataFrame containing the output data.
153
- `βs::Vector{Float64}`: The inverse temperatures.
154
- `dof::Int`: The degrees of freedom, equals to the number of dimensions times the number of particles. For a lattice, it is zero.
155
- `n_walkers::Int`: The number of walkers.
156
- `n_cull::Int`: The number of culled walkers. Default is 1.
157
- `ω0::Float64`: The initial \$\\omega\$ factor. Default is 1.0.
158

159
# Returns
160
- A vector of constant-volume heat capacities.
161
"""
162
function cv(df::DataFrame, 
16✔
163
            βs::Vector{Float64}, 
164
            dof::Int, n_walkers::Int; 
165
            n_cull::Int=1, 
166
            ω0::Float64=1.0, 
167
            kb::Float64=8.617333262e-5)
168
    ωi = ωᵢ(df.iter, n_walkers; n_cull=n_cull, ω0=ω0)
8✔
169
    Ei = df.emax .- minimum(df.emax)
8✔
170
    cvs = Vector{Float64}(undef, length(βs))
12✔
171
    Threads.@threads for (i, b) in collect(enumerate(βs))
20✔
172
        cvs[i] = cv(b, ωi, Ei, dof; kb=kb)
24✔
173
    end
174
    return cvs
8✔
175
end
176

177
"""
178
    cv(Ts::Vector{Float64}, dof::Int, energy_bins::Vector{Float64}, entropy::Vector{Float64})
179

180
(Wang-Landau Sampling) Calculates the constant-volume heat capacity at constant volume for the given temperatures, degrees of 
181
freedom, energy bins, and entropy. The kinetic energy is treated classically, and is added to the heat capacity as \$dof \\cdot k_B/2\$.
182

183
# Arguments
184
- `Ts::Vector{Float64}`: The temperatures in Kelvin.
185
- `dof::Int`: The degrees of freedom, equals to the number of dimensions times the number of particles. For a lattice, it is zero.
186
- `energy_bins::Vector{Float64}`: The energy bins in eV.
187
- `entropy::Vector{Float64}`: The entropy.
188

189
# Returns
190
- A vector of constant-volume heat capacities.
191
"""
192
function cv(Ts::Vector{Float64}, dof::Int, energy_bins::Vector{Float64}, entropy::Vector{Float64})
8✔
193
    kb = 8.617333262e-5 # eV/K
8✔
194
    β = 1 ./(kb.*Ts)
16✔
195
    E_rel = energy_bins .- minimum(energy_bins)
16✔
196
    S_shifted = entropy .- minimum(entropy[entropy .> 0])
16✔
197
    g = exp.(S_shifted)
16✔
198
    Z = zeros(length(Ts))
16✔
199
    E_avg = zeros(length(Ts))
16✔
200
    E2_avg = zeros(length(Ts))
16✔
201
    Cv = zeros(length(Ts))
16✔
202
    for (i, temp) in enumerate(Ts)
8✔
203
        Z[i] = sum(exp.(-E_rel ./ (kb * temp)) .* g)
20✔
204
        E_avg[i] = sum(E_rel .* exp.(-E_rel ./ (kb * temp)) .* g) / Z[i]
20✔
205
        E2_avg[i] = sum(E_rel.^2 .* exp.(-E_rel ./ (kb * temp)) .* g) / Z[i]
20✔
206
        Cv[i] = (E2_avg[i] .- E_avg[i].^2) ./ (kb * temp.^2) .+ dof*kb/2
16✔
207
    end
24✔
208
    return Cv
8✔
209
end
210

211

212
end # module AnalysisTools
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc