forked from trixi-framework/Trixi.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauxiliary.jl
192 lines (151 loc) · 5.32 KB
/
auxiliary.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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
include("containers.jl")
include("math.jl")
# Enable debug timings `@timeit_debug timer() "name" stuff...`.
# This allows us to disable timings completely by executing
# `TimerOutputs.disable_debug_timings(Trixi)`
# and to enable them again by executing
# `TimerOutputs.enable_debug_timings(Trixi)`
timeit_debug_enabled() = true
# Store main timer for global timing of functions
const main_timer = TimerOutput()
# Always call timer() to hide implementation details
timer() = main_timer
"""
PerformanceCounter
A `PerformanceCounter` be used to track the runtime performance of some calls.
Add a new runtime measurement via `put!(counter, runtime)` and get the averaged
runtime of all measurements added so far via `take!(counter)`, resetting the
`counter`.
"""
mutable struct PerformanceCounter
ncalls_since_readout::Int
runtime::Float64
end
PerformanceCounter() = PerformanceCounter(0, 0.0)
function Base.take!(counter::PerformanceCounter)
time_per_call = counter.runtime / counter.ncalls_since_readout
counter.ncalls_since_readout = 0
counter.runtime = 0.0
return time_per_call
end
function Base.put!(counter::PerformanceCounter, runtime::Real)
counter.ncalls_since_readout += 1
counter.runtime += runtime
end
# Initialize top-level parameters structure for program-wide parameters
const parameters = Dict{Symbol,Any}()
# Parse parameters file into global dict
parse_parameters_file(filename) = parse_parameters_file(filename, mpi_parallel())
function parse_parameters_file(filename, mpi_parallel::Val{false})
parameters[:default] = parsefile(filename)
parameters[:default]["parameters_file"] = filename
end
function parse_parameters_file(filename, mpi_parallel::Val{true})
if mpi_isroot()
buffer = read(filename)
MPI.Bcast!(Ref(length(buffer)), mpi_root(), mpi_comm())
MPI.Bcast!(buffer, mpi_root(), mpi_comm())
else
count = MPI.Bcast!(Ref(0), mpi_root(), mpi_comm())
buffer = Vector{UInt8}(undef, count[])
MPI.Bcast!(buffer, mpi_root(), mpi_comm())
end
parameters[:default] = parse(String(buffer))
parameters[:default]["parameters_file"] = filename
end
# Return parameter by name, optionally taking a default value and a range of valid values.
#
# If no default value is specified, the parameter is required and the program
# stops if the parameter was not found. The range of valid parameters is used
# to restrict parameters to sane values.
function parameter(name, default=nothing; valid=nothing)
if haskey(parameters[:default], name)
# If parameter exists, use its value
value = parameters[:default][name]
else
# Otherwise check whether a default is given and abort if not
if default === nothing
error("requested parameter '$name' does not exist and no default value was provided")
else
value = default
end
end
# If a range of valid values has been specified, check parameter value against it
if valid !== nothing
if !(value in valid)
error("'$value' is not a valid value for parameter '$name' (valid: $valid)")
end
end
return value
end
"""
examples_dir()
Return the directory where the example files provided with Trixi.jl are located. If Trixi is
installed as a regular package (with `]add Trixi`), these files are read-only and should *not* be
modified. To find out which files are available, use, e.g., `readdir`:
# Examples
```julia
julia> readdir(examples_dir())
4-element Array{String,1}:
"2d"
"3d"
"README.md"
"paper-self-gravitating-gas-dynamics"
```
"""
examples_dir() = joinpath(pathof(Trixi) |> dirname |> dirname, "examples")
"""
get_examples()
Return a list of all example parameter files that are provided by Trixi.
"""
function get_examples()
examples = String[]
for (root, dirs, files) in walkdir(examples_dir())
for f in files
if endswith(f, ".toml")
push!(examples, joinpath(root, f))
end
end
end
return examples
end
"""
default_example()
Return the path to an example parameter file that can be used to quickly see Trixi in action.
"""
default_example() = joinpath(examples_dir(), "2d", "elixir_advection_basic.jl")
"""
setparameter(name::String, value)
Set parameter with the specified `name` to the specified `value`.
"""
function setparameter(name::String, value) # TODO: Taal remove
parameters[:default][name] = value
end
# Return true if parameter exists.
parameter_exists(name::String) = haskey(parameters[:default], name) # TODO: Taal remove
# Print informative message at startup
function print_startup_message()
s = """
████████╗██████╗ ██╗██╗ ██╗██╗
╚══██╔══╝██╔══██╗██║╚██╗██╔╝██║
██║ ██████╔╝██║ ╚███╔╝ ██║
██║ ██╔══██╗██║ ██╔██╗ ██║
██║ ██║ ██║██║██╔╝ ██╗██║
╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝╚═╝
"""
mpi_println(s)
end
"""
get_name(x)
Returns a name of `x` ready for pretty printing.
By default, return `string(y)` if `x isa Val{y}` and return `string(x)` otherwise.
# Examples
```jldoctest
julia> Trixi.get_name("test")
"test"
julia> Trixi.get_name(Val(:test))
"test"
```
"""
get_name(x) = string(x)
get_name(::Val{x}) where x = string(x)