-
Notifications
You must be signed in to change notification settings - Fork 29
/
output.jl
128 lines (108 loc) · 3.1 KB
/
output.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
"""
Output(prob, filename, fieldtuples...)
Define output for `prob` with fields and functions that calculate
the output in the list of tuples `fieldtuples = (fldname, func)...`.
"""
struct Output
prob::Problem
path::String
fields::Dict{Symbol,Function}
end
withoutjld2(path) = (length(path)>4 && path[end-4:end] == ".jld2") ? path[1:end-5] : path
"""
uniquepath(path)
Returns `path` with a number appended if `isfile(path)`, incremented until `path` does not exist.
"""
function uniquepath(path)
n = 1
if isfile(path)
path = withoutjld2(path) * "_$n.jld2"
end
while isfile(path)
n += 1
path = withoutjld2(path)[1:end-length("_$(n-1)")] * "_$n.jld2"
end
path
end
function Output(prob, path, fields::Dict{Symbol,Function})
truepath = uniquepath(withoutjld2(path)*".jld2") # ensure path ends in ".jld2"
saveproblem(prob, truepath)
Output(prob, filename, fields)
end
Output(prob, path, fields...) = Output(prob, path, Dict{Symbol,Function}([fields...]))
Output(prob, path, field::Tuple{Symbol,T}) where T = Output(prob, path, Dict{Symbol,Function}([field]))
getindex(out::Output, key) = out.fields[key](out.prob)
"""
saveoutput(out)
Save the fields in `out.fields` to `out.path`.
"""
function saveoutput(out)
groupname = "snapshots"
jldopen(out.path, "a+") do path
path["$groupname/t/$(out.prob.clock.step)"] = out.prob.clock.t
for fieldname in keys(out.fields)
path["$groupname/$fieldname/$(out.prob.clock.step)"] = out[fieldname]
end
end
nothing
end
"""
savefields(file, field)
Saves some parameters of `prob.field`.
"""
function savefields(file::JLD2.JLDFile{JLD2.MmapIO}, grid::TwoDGrid)
for field in [:nx, :ny, :Lx, :Ly, :x, :y]
file["grid/$field"] = getfield(grid, field)
end
nothing
end
function savefields(file::JLD2.JLDFile{JLD2.MmapIO}, grid::OneDGrid)
for field in [:nx, :Lx, :x]
file["grid/$field"] = getfield(grid, field)
end
nothing
end
function savefields(file::JLD2.JLDFile{JLD2.MmapIO}, params::AbstractParams)
for name in fieldnames(typeof(params))
field = getfield(params, name)
if !(typeof(field) <: Function)
file["params/$name"] = field
end
end
nothing
end
function savefields(file::JLD2.JLDFile{JLD2.MmapIO}, clock::Clock)
file["clock/dt"] = clock.dt # Timestepper
nothing
end
function savefields(file::JLD2.JLDFile{JLD2.MmapIO}, eqn::Equation)
file["eqn/L"] = eqn.L
file["eqn/dims"] = eqn.dims
file["eqn/T"] = eqn.T
nothing
end
"""
saveproblem(prob, filename)
Save certain aspects of a problem.
"""
function saveproblem(prob, filename)
file = jldopen(filename, "a+")
for field in [:eqn, :clock, :grid, :params]
savefields(file, getfield(prob, field))
end
close(file)
nothing
end
saveproblem(out::Output) = saveproblem(out.prob, out.path)
"""
savediagnostic(diag, diagname)
Save diagnostics in `diag` to file, labeled by `diagname`.
"""
function savediagnostic(diag, diagname, filename)
jldopen(filename, "a+") do file
file["diags/$diagname/steps"] = diag.steps
file["diags/$diagname/t"] = diag.t
file["diags/$diagname/data"] = diag.data
end
nothing
end