Skip to content

Commit

Permalink
Merge branch 'main' into semidiscretization-doc
Browse files Browse the repository at this point in the history
  • Loading branch information
ArseniyKholod authored Feb 16, 2024
2 parents a502c36 + 29e173e commit e3ca61b
Show file tree
Hide file tree
Showing 13 changed files with 38 additions and 265 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/FormatCheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
# TODO: Change the call below to
# format(".")
run: |
julia -e 'using Pkg; Pkg.add(PackageSpec(name = "JuliaFormatter"))'
julia -e 'using Pkg; Pkg.add(PackageSpec(name = "JuliaFormatter", version="1.0.45"))'
julia -e 'using JuliaFormatter; format(["benchmark", "examples", "ext", "src", "test", "utils"])'
- name: Format check
run: |
Expand Down
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Trixi"
uuid = "a7f1ee26-1774-49b1-8366-f1abc58fbfcb"
authors = ["Michael Schlottke-Lakemper <[email protected]>", "Gregor Gassner <[email protected]>", "Hendrik Ranocha <[email protected]>", "Andrew R. Winters <[email protected]>", "Jesse Chan <[email protected]>"]
version = "0.6.9-pre"
version = "0.6.10-pre"

[deps]
CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
Expand Down Expand Up @@ -45,6 +45,7 @@ TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
Triangulate = "f7e6ffb2-c36d-4f8f-a77e-16e897189344"
TriplotBase = "981d1d27-644d-49a2-9326-4793e63143c3"
TriplotRecipes = "808ab39a-a642-4abf-81ff-4cb34ebbffa3"
TrixiBase = "9a0f1c46-06d5-4909-a5a3-ce25d3fa3284"

[weakdeps]
Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a"
Expand Down Expand Up @@ -95,6 +96,7 @@ TimerOutputs = "0.5.7"
Triangulate = "2.0"
TriplotBase = "0.1"
TriplotRecipes = "0.1"
TrixiBase = "0.1.1"
julia = "1.8"

[extras]
Expand Down
2 changes: 2 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Trixi2Vtk = "bc1476a1-1ca6-4cc3-950b-c312b255ff95"
TrixiBase = "9a0f1c46-06d5-4909-a5a3-ce25d3fa3284"

[compat]
CairoMakie = "0.6, 0.7, 0.8, 0.9, 0.10, 0.11"
Expand All @@ -23,3 +24,4 @@ OrdinaryDiffEq = "6.49.1"
Plots = "1.9"
Test = "1"
Trixi2Vtk = "0.3"
TrixiBase = "0.1.1"
4 changes: 3 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ end

using Trixi
using Trixi2Vtk
using TrixiBase

# Get Trixi.jl root directory
trixi_root_dir = dirname(@__DIR__)
Expand Down Expand Up @@ -83,7 +84,7 @@ tutorials = create_tutorials(files)
# Make documentation
makedocs(
# Specify modules for which docstrings should be shown
modules = [Trixi, Trixi2Vtk],
modules = [Trixi, TrixiBase, Trixi2Vtk],
# Set sitename to Trixi.jl
sitename = "Trixi.jl",
# Provide additional formatting options
Expand Down Expand Up @@ -129,6 +130,7 @@ makedocs(
"Troubleshooting and FAQ" => "troubleshooting.md",
"Reference" => [
"Trixi.jl" => "reference-trixi.md",
"TrixiBase.jl" => "reference-trixibase.md",
"Trixi2Vtk.jl" => "reference-trixi2vtk.md"
],
"Authors" => "authors.md",
Expand Down
10 changes: 6 additions & 4 deletions docs/src/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ Trixi.jl is distributed with several examples in the form of elixirs, small
Julia scripts containing everything to set up and run a simulation. Working
interactively from the Julia REPL with these scripts can be quite convenient
while for exploratory research and development of Trixi.jl. For example, you
can use the convenience function [`trixi_include`](@ref) to `include` an elixir
with some modified arguments. To enable this, it is helpful to use a consistent
naming scheme in elixirs, since [`trixi_include`](@ref) can only perform simple
replacements. Some standard variables names are
can use the convenience function
[`trixi_include`](@ref)
to `include` an elixir with some modified arguments. To enable this, it is
helpful to use a consistent naming scheme in elixirs, since
[`trixi_include`](@ref)
can only perform simple replacements. Some standard variables names are

- `polydeg` for the polynomial degree of a solver
- `surface_flux` for the numerical flux at surfaces
Expand Down
9 changes: 9 additions & 0 deletions docs/src/reference-trixibase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# TrixiBase.jl API

```@meta
CurrentModule = TrixiBase
```

```@autodocs
Modules = [TrixiBase]
```
4 changes: 3 additions & 1 deletion src/Trixi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ using Triangulate: Triangulate, TriangulateIO, triangulate
export TriangulateIO # for type parameter in DGMultiMesh
using TriplotBase: TriplotBase
using TriplotRecipes: DGTriPseudocolor
@reexport using TrixiBase: trixi_include
using TrixiBase: TrixiBase
@reexport using SimpleUnPack: @unpack
using SimpleUnPack: @pack!
using DataStructures: BinaryHeap, FasterForward, extract_all!
Expand Down Expand Up @@ -129,7 +131,7 @@ include("callbacks_step/callbacks_step.jl")
include("callbacks_stage/callbacks_stage.jl")
include("semidiscretization/semidiscretization_euler_gravity.jl")

# `trixi_include` and special elixirs such as `convergence_test`
# Special elixirs such as `convergence_test`
include("auxiliary/special_elixirs.jl")

# Plot recipes and conversion functions to visualize results with Plots.jl
Expand Down
3 changes: 0 additions & 3 deletions src/auxiliary/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -577,9 +577,6 @@ function _precompile_manual_()
@assert Base.precompile(Tuple{typeof(show), Base.TTY, lbm_collision_callback_type})
@assert Base.precompile(Tuple{typeof(show), IOContext{Base.TTY}, MIME"text/plain",
lbm_collision_callback_type})

# infrastructure, special elixirs
@assert Base.precompile(Tuple{typeof(trixi_include), String})
end

@assert Base.precompile(Tuple{typeof(init_mpi)})
Expand Down
158 changes: 5 additions & 153 deletions src/auxiliary/special_elixirs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,58 +5,6 @@
@muladd begin
#! format: noindent

# Note: We can't call the method below `Trixi.include` since that is created automatically
# inside `module Trixi` to `include` source files and evaluate them within the global scope
# of `Trixi`. However, users will want to evaluate in the global scope of `Main` or something
# similar to manage dependencies on their own.
"""
trixi_include([mod::Module=Main,] elixir::AbstractString; kwargs...)
`include` the file `elixir` and evaluate its content in the global scope of module `mod`.
You can override specific assignments in `elixir` by supplying keyword arguments.
It's basic purpose is to make it easier to modify some parameters while running Trixi.jl from the
REPL. Additionally, this is used in tests to reduce the computational burden for CI while still
providing examples with sensible default values for users.
Before replacing assignments in `elixir`, the keyword argument `maxiters` is inserted
into calls to `solve` and `Trixi.solve` with it's default value used in the SciML ecosystem
for ODEs, see the "Miscellaneous" section of the
[documentation](https://docs.sciml.ai/DiffEqDocs/stable/basics/common_solver_opts/).
# Examples
```jldoctest
julia> redirect_stdout(devnull) do
trixi_include(@__MODULE__, joinpath(examples_dir(), "tree_1d_dgsem", "elixir_advection_extended.jl"),
tspan=(0.0, 0.1))
sol.t[end]
end
[ Info: You just called `trixi_include`. Julia may now compile the code, please be patient.
0.1
```
"""
function trixi_include(mod::Module, elixir::AbstractString; kwargs...)
# Check that all kwargs exist as assignments
code = read(elixir, String)
expr = Meta.parse("begin \n$code \nend")
expr = insert_maxiters(expr)

for (key, val) in kwargs
# This will throw an error when `key` is not found
find_assignment(expr, key)
end

# Print information on potential wait time only in non-parallel case
if !mpi_isparallel()
@info "You just called `trixi_include`. Julia may now compile the code, please be patient."
end
Base.include(ex -> replace_assignments(insert_maxiters(ex); kwargs...), mod, elixir)
end

function trixi_include(elixir::AbstractString; kwargs...)
trixi_include(Main, elixir; kwargs...)
end

"""
convergence_test([mod::Module=Main,] elixir::AbstractString, iterations; kwargs...)
Expand Down Expand Up @@ -177,112 +125,15 @@ end

# Helper methods used in the functions defined above

# Apply the function `f` to `expr` and all sub-expressions recursively.
walkexpr(f, expr::Expr) = f(Expr(expr.head, (walkexpr(f, arg) for arg in expr.args)...))
walkexpr(f, x) = f(x)

# Insert the keyword argument `maxiters` into calls to `solve` and `Trixi.solve`
# with default value `10^5` if it is not already present.
function insert_maxiters(expr)
maxiters_default = 10^5

expr = walkexpr(expr) do x
if x isa Expr
is_plain_solve = x.head === Symbol("call") && x.args[1] === Symbol("solve")
is_trixi_solve = (x.head === Symbol("call") && x.args[1] isa Expr &&
x.args[1].head === Symbol(".") &&
x.args[1].args[1] === Symbol("Trixi") &&
x.args[1].args[2] isa QuoteNode &&
x.args[1].args[2].value === Symbol("solve"))

if is_plain_solve || is_trixi_solve
# Do nothing if `maxiters` is already set as keyword argument...
for arg in x.args
# This detects the case where `maxiters` is set as keyword argument
# without or before a semicolon
if (arg isa Expr && arg.head === Symbol("kw") &&
arg.args[1] === Symbol("maxiters"))
return x
end

# This detects the case where maxiters is set as keyword argument
# after a semicolon
if (arg isa Expr && arg.head === Symbol("parameters"))
# We need to check each keyword argument listed here
for nested_arg in arg.args
if (nested_arg isa Expr &&
nested_arg.head === Symbol("kw") &&
nested_arg.args[1] === Symbol("maxiters"))
return x
end
end
end
end

# ...and insert it otherwise.
push!(x.args, Expr(Symbol("kw"), Symbol("maxiters"), maxiters_default))
end
end
return x
end

return expr
end

# Replace assignments to `key` in `expr` by `key = val` for all `(key,val)` in `kwargs`.
function replace_assignments(expr; kwargs...)
# replace explicit and keyword assignments
expr = walkexpr(expr) do x
if x isa Expr
for (key, val) in kwargs
if (x.head === Symbol("=") || x.head === :kw) &&
x.args[1] === Symbol(key)
x.args[2] = :($val)
# dump(x)
end
end
end
return x
end

return expr
end

# find a (keyword or common) assignment to `destination` in `expr`
# and return the assigned value
function find_assignment(expr, destination)
# declare result to be able to assign to it in the closure
local result
found = false

# find explicit and keyword assignments
walkexpr(expr) do x
if x isa Expr
if (x.head === Symbol("=") || x.head === :kw) &&
x.args[1] === Symbol(destination)
result = x.args[2]
found = true
# dump(x)
end
end
return x
end

if !found
throw(ArgumentError("assignment `$destination` not found in expression"))
end

result
end

# searches the parameter that specifies the mesh reslution in the elixir
# Searches for the assignment that specifies the mesh resolution in the elixir
function extract_initial_resolution(elixir, kwargs)
code = read(elixir, String)
expr = Meta.parse("begin \n$code \nend")

try
# get the initial_refinement_level from the elixir
initial_refinement_level = find_assignment(expr, :initial_refinement_level)
initial_refinement_level = TrixiBase.find_assignment(expr,
:initial_refinement_level)

if haskey(kwargs, :initial_refinement_level)
return kwargs[:initial_refinement_level]
Expand All @@ -294,7 +145,8 @@ function extract_initial_resolution(elixir, kwargs)
if isa(e, ArgumentError)
try
# get cells_per_dimension from the elixir
cells_per_dimension = eval(find_assignment(expr, :cells_per_dimension))
cells_per_dimension = eval(TrixiBase.find_assignment(expr,
:cells_per_dimension))

if haskey(kwargs, :cells_per_dimension)
return kwargs[:cells_per_dimension]
Expand Down
4 changes: 2 additions & 2 deletions src/callbacks_step/trivial.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"""
TrivialCallback()
A callback that does nothing. This can be useful to disable some callbacks
easily via [`trixi_include`](@ref).
A callback that does nothing. This can be useful to disable some callbacks easily via
[`trixi_include`](@ref).
"""
function TrivialCallback()
DiscreteCallback(trivial_callback, trivial_callback,
Expand Down
Loading

0 comments on commit e3ca61b

Please sign in to comment.