-
Notifications
You must be signed in to change notification settings - Fork 0
/
circulation_GP.jl
166 lines (136 loc) · 5.09 KB
/
circulation_GP.jl
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# Compute circulation statistics from sample 256³ GP data.
using GPFields
using GPStatistics
using TimerOutputs
using HDF5
import Base.Threads
@info "Using $(Threads.nthreads()) threads"
if Threads.nthreads() == 1
@info "Set the JULIA_NUM_THREADS environment variable to change this."
end
function make_loop_sizes(; base, dims)
Rmax = min(dims...) - 1 # max loop size is N - 1
Nmax = floor(Int, log(base, Rmax))
unique(round.(Int, base .^ (0:Nmax)))
end
function main()
# ====================================================================== #
# Start of parameter section
# ====================================================================== #
dims = (256, 256, 256) # resolution of input fields
gp = ParamsGP(
dims,
L = (2π, 2π, 2π), # domain size
c = 1.0, # speed of sound
nxi = 1.5, # normalised healing length
)
# Resampling factor: increases the resolution of analysed fields.
# This makes sense for GP data, to avoid issues related to the singularity
# of the velocity field at vortex locations.
# Higher resampling factor is generally better (but slower, and uses more
# memory).
# For NS data, resampling should not be used (i.e. resampling_factor = 1).
resampling_factor = 4
# If true, compute statistics on resampled (fine) grid.
# This may be used to increase the number of statistics samples, but in
# general it doesn't make a big difference.
compute_in_resampled_grid = false
# Sizes of square loops to analyse
loop_sizes = make_loop_sizes(; base = 1.4, dims = dims)
# Generate convolution kernels associated to square loops
kernels = RectangularKernel.(loop_sizes .* gp.dx[1])
data_params = (
directory = "sample_data/GP", # directory where data is located
timestep = 1, # this corresponds to the "001" in the file names
load_velocity = false, # we're loading GP wave function fields, not velocity fields
)
output = (
statistics = "circulation_GP.h5", # circulation statistics are written to this file
)
circulation = (
max_slices = typemax(Int), # compute over all possible 2D cuts of the domain (better)
# max_slices = 4, # or compute over a subset of slices (faster)
eps_velocity = 0, # this is for regularisation of GP velocity fields (0 => no regularisation)
# Parameters for circulation moments.
moments = ParamsMoments(
CirculationField(),
integer = 10, # compute moment orders p = 1:10
fractional = nothing, # don't compute fractional moments
),
# Parameters for circulation histograms / PDFs.
histogram = (
Nedges = 4000, # number of bin edges
max_kappa = 20.5, # histogram extrema in units of quantum of circulation κ
),
)
# ====================================================================== #
# End of parameter section
# ====================================================================== #
@info "Loop sizes: $loop_sizes ($(length(loop_sizes)) sizes)"
@info "Resampling factor: $resampling_factor"
if resampling_factor > 1
@info "Computing in $(compute_in_resampled_grid ? "resampled" :
"original") grid"
end
to = TimerOutput()
kwargs = (
eps_vel = circulation.eps_velocity,
to = to,
)
# Which fields to analyse.
which = if data_params.load_velocity
# If a velocity field is loaded (NS):
(
VelocityLikeFields.Velocity,
)
else
# If a wave function field is loaded (GP), we compute circulation from
# velocity v and from regularised velocity v * √ρ.
(
VelocityLikeFields.Velocity,
VelocityLikeFields.RegVelocity,
# VelocityLikeFields.Momentum,
)
end
stats = let par = circulation
Nedges = par.histogram.Nedges
κ = gp.phys.κ
M = par.histogram.max_kappa
edges = LinRange(-M * κ, M * κ, Nedges)
histogram = ParamsHistogram(CirculationField(), bin_edges = edges)
stats_params = (
histogram,
par.moments,
)
init_statistics(
CirculationStats,
kernels,
stats_params;
which = which,
resampling_factor,
compute_in_resampled_grid,
)
end
# This is just to precompile functions and get better timings.
analyse!(stats, gp, data_params; max_slices=1, kwargs...)
reset_timer!(to)
reset!(stats)
# The actual analysis is done here.
analyse!(
stats, gp, data_params;
max_slices = circulation.max_slices,
kwargs...,
)
println(to)
# Write results
let outfile = output.statistics
mkpath(dirname(outfile))
@info "Saving $(outfile)"
h5open(outfile, "w") do ff
write(create_group(ff, "ParamsGP"), gp)
write(create_group(ff, "Circulation"), stats)
end
end
nothing
end
main()