Skip to content

Commit c11f4e1

Browse files
authored
Add better support for inplace vector fields (#4)
1 parent ad20c81 commit c11f4e1

File tree

8 files changed

+162
-82
lines changed

8 files changed

+162
-82
lines changed

.github/workflows/CI.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
tags: '*'
8+
pull_request:
9+
10+
jobs:
11+
test:
12+
name: Julia ${{ matrix.version }} - ${{ matrix.os }}
13+
runs-on: ${{ matrix.os }}
14+
continue-on-error: ${{ matrix.version == 'nightly' }}
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
version:
19+
- '1.0'
20+
- '1'
21+
- 'nightly'
22+
os:
23+
- ubuntu-latest
24+
- macOS-latest
25+
- windows-latest
26+
steps:
27+
- uses: actions/checkout@v2
28+
- uses: julia-actions/setup-julia@latest
29+
with:
30+
version: ${{ matrix.version }}
31+
- uses: julia-actions/julia-buildpkg@latest
32+
- uses: julia-actions/julia-runtest@latest
33+
- uses: julia-actions/julia-processcoverage@v1
34+
- uses: codecov/codecov-action@v1
35+
if: ${{ matrix.version == '1' && matrix.os == 'ubuntu-latest' }}
36+
with:
37+
file: lcov.info

.travis.yml

Lines changed: 0 additions & 23 deletions
This file was deleted.

Project.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "StreamMacros"
22
uuid = "1418a599-1564-4a75-98e9-b890cf8b552f"
3-
authors = ["Alvaro de Diego"]
4-
version = "0.1.2"
3+
authors = ["Alvaro de Diego", "Daniel Karrasch"]
4+
version = "0.2.0"
55

66
[deps]
77
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
@@ -15,7 +15,8 @@ SymEngine = "0.6, 0.7, 0.8"
1515
julia = "1"
1616

1717
[extras]
18+
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
1819
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1920

2021
[targets]
21-
test = ["Test"]
22+
test = ["InteractiveUtils", "Test"]

README.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,34 @@
11
# StreamMacros.jl
22

3-
[![build status](https://travis-ci.org/CoherentStructures/StreamMacros.jl.svg?branch=master)](https://travis-ci.org/CoherentStructures/StreamMacros.jl)
4-
[![codecov.io](http://codecov.io/github/CoherentStructures/StreamMacros.jl/coverage.svg?branch=master)](http://codecov.io/github/CoherentStructures/StreamMacros.jl?branch=master)
5-
[![stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://coherentstructures.github.io/StreamMacros.jl/stable)
6-
[![dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://coherentstructures.github.io/StreamMacros.jl/dev)
3+
*Convenience macros for defining velocity fields via their stream function.*
74

8-
Provides some convenience macros for defining velocity fields via their stream function.
5+
[![build status](https://github.com/CoherentStructures/StreamMacros.jl/workflows/CI/badge.svg?branch=master)](https://github.com/CoherentStructures/StreamMacros.jl/actions?query=workflow%3ACI)
6+
[![code coverage](http://codecov.io/github/CoherentStructures/StreamMacros.jl/coverage.svg?branch=master)](http://codecov.io/github/CoherentStructures/StreamMacros.jl?branch=master)
7+
[![stable docs](https://img.shields.io/badge/docs-stable-blue.svg)](https://coherentstructures.github.io/StreamMacros.jl/stable)
8+
[![dev docs](https://img.shields.io/badge/docs-dev-blue.svg)](https://coherentstructures.github.io/StreamMacros.jl/dev)
9+
10+
## Installation
911

10-
# Installation
1112
Install by typing
1213

13-
]add https://github.com/CoherentStructures/StreamMacros.jl
14+
```julia
15+
]add https://github.com/CoherentStructures/StreamMacros.jl.git
16+
```
1417

1518
in the Julia REPL.
1619

17-
# Examples
20+
## Examples
21+
1822
The basic usage pattern is
1923

2024
```julia
2125
output = @velo_from_stream <stream_name> begin
2226
<stream_name> = ...
23-
# additional definitions
27+
# additional definitions
2428
end
2529
```
2630

27-
as in e.g.
31+
as in
2832

2933
```julia
3034
using StreamMacros

docs/Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
StreamMacros = "1418a599-1564-4a75-98e9-b890cf8b552f"
34

45
[compat]
5-
Documenter = "0.24"
6+
Documenter = "0.24, 0.25, 0.26"

src/StreamMacros.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ const ODE = DiffEqBase
1111
export
1212
@define_stream,
1313
@velo_from_stream,
14+
@velo!_from_stream,
1415
@var_velo_from_stream,
16+
@var_velo!_from_stream,
1517
@vorticity_from_stream
1618

1719
include("macros.jl")

src/macros.jl

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,31 @@ macro velo_from_stream(name::Symbol)
102102
end
103103
end
104104

105+
"""
106+
@velo!_from_stream(name::Symbol, [code::Expr])
107+
108+
Same as [`@velo_from_stream`](@ref), but returns the in-place version of the velocity field.
109+
"""
110+
macro velo!_from_stream(H::Symbol, formulas::Expr)
111+
V, _ = streamline_derivatives(H, formulas)
112+
V = sym_subst.(V, [[:x, :y, :p]], [[:(u[1]), :(u[2]), :(p[1])]])
113+
quote
114+
ODE.ODEFunction{true}(
115+
(du, u, p, t) -> begin
116+
du[1] = $(V[1])
117+
du[2] = $(V[2])
118+
return du
119+
end,
120+
)
121+
end
122+
end
123+
macro velo!_from_stream(name::Symbol)
124+
haskey(stream_dict, name) || (@error "stream $name not defined")
125+
quote
126+
@velo!_from_stream $name $(stream_dict[name])
127+
end
128+
end
129+
105130
"""
106131
@var_velo_from_stream(name::Symbol, [code::Expr])
107132
@@ -167,6 +192,43 @@ macro var_velo_from_stream(name::Symbol)
167192
end
168193
end
169194

195+
"""
196+
@var_velo!_from_stream(name::Symbol, [code::Expr])
197+
198+
Same as [`@var_velo_from_stream`](@ref), but returns the in-place version of the (extended)
199+
velocity field.
200+
"""
201+
macro var_velo!_from_stream(H::Symbol, formulas::Expr)
202+
V, DV = streamline_derivatives(H, formulas)
203+
204+
# substitute :x and :y by access to the first column of a matrix u
205+
V = sym_subst.(V, [[:x, :y, :p]], [[:(u[1, 1]), :(u[2, 1]), :(p[1])]])
206+
DV = sym_subst.(DV, [[:x, :y, :p]], [[:(u[1, 1]), :(u[2, 1]), :(p[1])]])
207+
208+
quote
209+
ODE.ODEFunction{true}(
210+
(du, u, p, t) -> begin
211+
# take as input a 2x3 matrix which is interpreted in the following way:
212+
# [ x[1] X[1,1] X[1,2]
213+
# x[2] X[2,1] X[2,2] ]
214+
du[1,1] = $(V[1])
215+
du[2,1] = $(V[2])
216+
du[1,2] = $(DV[1,1]) * u[1,2] + $(DV[1,2]) * u[2,2]
217+
du[2,2] = $(DV[2,1]) * u[1,2] + $(DV[2,2]) * u[2,2]
218+
du[1,3] = $(DV[1,1]) * u[1,3] + $(DV[1,2]) * u[2,3]
219+
du[2,3] = $(DV[2,1]) * u[1,3] + $(DV[2,2]) * u[2,3]
220+
return du
221+
end,
222+
)
223+
end
224+
end
225+
macro var_velo!_from_stream(name::Symbol)
226+
haskey(stream_dict, name) || (@error "stream $name not defined")
227+
quote
228+
@var_velo!_from_stream $(name) $(stream_dict[name])
229+
end
230+
end
231+
170232
"""
171233
@vorticity_from_stream(name::Symbol, [code::Expr])
172234
@@ -341,10 +403,6 @@ simple_simplifier(expr) = expr
341403

342404

343405
expr_grad(expr, coord_vars::Vector{Symbol}) = expr_diff.(expr, coord_vars)
344-
function hessian(expr, coord_vars)
345-
∇expr = expr_grad(expr, coord_vars)
346-
∇²expr = expr_grad(expr)
347-
end
348406

349407
####t####################################################################################
350408
# Functions for symbolic manipulation of expressions #

test/runtests.jl

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,44 @@
11
using StreamMacros
2+
using InteractiveUtils
23
using DiffEqBase
34
using StaticArrays
45
using Test
56

67
@testset "StreamMacros.jl" begin
7-
bickley = @velo_from_stream stream begin
8-
stream = psi₀ + psi₁
9-
psi₀ = - U₀ * L₀ * tanh(y / L₀)
10-
psi₁ = U₀ * L₀ * sech(y / L₀)^2 * re_sum_term
11-
12-
re_sum_term = Σ₁ + Σ₂ + Σ₃
13-
14-
Σ₁ = ε₁ * cos(k₁*(x - c₁*t))
15-
Σ₂ = ε₂ * cos(k₂*(x - c₂*t))
16-
Σ₃ = ε₃ * cos(k₃*(x - c₃*t))
17-
18-
k₁ = 2/r₀ ; k₂ = 4/r₀ ; k₃ = 6/r₀
19-
20-
ε₁ = 0.0075 ; ε₂ = 0.15 ; ε₃ = 0.3
21-
c₂ = 0.205U₀ ; c₃ = 0.461U₀ ; c₁ = c₃ + (5-1)*(c₂-c₃)
22-
23-
U₀ = 62.66e-6 ; L₀ = 1770e-3 ; r₀ = 6371e-3
8+
du = zeros(2); u= rand(2); t = rand(); DU = zeros(2,3); U = rand(2,3)
9+
@define_stream bstream begin
10+
bstream = psi₀ + psi₁
11+
psi₀ = - U₀ * L₀ * tanh(y / L₀)
12+
psi₁ = U₀ * L₀ * sech(y / L₀)^2 * re_sum_term
13+
14+
re_sum_term = Σ₁ + Σ₂ + Σ₃
15+
16+
Σ₁ = ε₁ * cos(k₁*(x - c₁*t))
17+
Σ₂ = ε₂ * cos(k₂*(x - c₂*t))
18+
Σ₃ = ε₃ * cos(k₃*(x - c₃*t))
19+
20+
k₁ = 2/r₀ ; k₂ = 4/r₀ ; k₃ = 6/r₀
21+
22+
ε₁ = 0.0075 ; ε₂ = 0.15 ; ε₃ = 0.3
23+
c₂ = 0.205U₀ ; c₃ = 0.461U₀ ; c₁ = c₃ + (5-1)*(c₂-c₃)
24+
25+
U₀ = 62.66e-6 ; L₀ = 1770e-3 ; r₀ = 6371e-3
2426
end
25-
@test bickley isa ODEFunction
27+
bickley = @velo_from_stream bstream
28+
bickley! = @velo!_from_stream bstream
29+
@test bickley isa ODEFunction{false}
30+
@test bickley! isa ODEFunction{true}
2631
@test bickley(SVector(0.0,0.0), nothing, 0.0) isa SVector
32+
@test bickley(SVector(0.0,0.0), nothing, 0.0) == bickley!(ones(2), [0.0, 0.0], nothing, 0.0)
33+
VERSION v"1.1" && @test iszero(@allocated bickley!(du, u, nothing, t))
2734

28-
bickley2 = @var_velo_from_stream stream begin
29-
stream = psi₀ + psi₁
30-
psi₀ = - U₀ * L₀ * tanh(y / L₀)
31-
psi₁ = U₀ * L₀ * sech(y / L₀)^2 * re_sum_term
32-
33-
re_sum_term = Σ₁ + Σ₂ + Σ₃
34-
35-
Σ₁ = ε₁ * cos(k₁*(x - c₁*t))
36-
Σ₂ = ε₂ * cos(k₂*(x - c₂*t))
37-
Σ₃ = ε₃ * cos(k₃*(x - c₃*t))
38-
39-
k₁ = 2/r₀ ; k₂ = 4/r₀ ; k₃ = 6/r₀
40-
41-
ε₁ = 0.0075 ; ε₂ = 0.15 ; ε₃ = 0.3
42-
c₂ = 0.205U₀ ; c₃ = 0.461U₀ ; c₁ = c₃ + (5-1)*(c₂-c₃)
43-
44-
U₀ = 62.66e-6 ; L₀ = 1770e-3 ; r₀ = 6371e-3
45-
end
46-
@test bickley2 isa ODEFunction
47-
@test (bickley2(SMatrix{2,3}(0.0,0.0,0.0,0.0,0.0,0.0), nothing, 0.0)
48-
isa SMatrix{2,3})
35+
bickley2 = @var_velo_from_stream bstream
36+
bickley2! = @var_velo!_from_stream bstream
37+
@test bickley2 isa ODEFunction{false}
38+
@test bickley2! isa ODEFunction{true}
39+
@test (bickley2(SMatrix{2,3}(0.0,0.0,0.0,0.0,0.0,0.0), nothing, 0.0) isa SMatrix{2,3})
40+
@test bickley2(SMatrix{2,3}(0.0,0.0,0.0,0.0,0.0,0.0), nothing, 0.0) == bickley2!(ones(2,3), zeros(2,3), nothing, 0.0)
41+
VERSION v"1.1" && @test iszero(@allocated bickley2!(DU, U, nothing, t))
4942

5043
@test StreamMacros.expr_diff(:(x^2 + sin(x) + y), :x) == :(2x + cos(x))
5144

@@ -55,10 +48,13 @@ using Test
5548

5649
t1 = @var_velo_from_stream test_stream
5750
t2 = @velo_from_stream test_stream
58-
@test t1 isa ODEFunction
59-
@test t2 isa ODEFunction
51+
@test t1 isa ODEFunction{false}
52+
@test t2 isa ODEFunction{false}
6053
ω = @vorticity_from_stream test_stream
6154
@test ω(rand(), rand(), rand()) == 4
55+
# works only locally, not on github CI
56+
# ct = code_typed(ω, (Float64, Float64, Float64))
57+
# @test first(ct).first.code[1] == :(return 4)
6258

6359
@define_stream Ψ_rot_dgyre begin
6460
st = window(t, 0, 1)*t^2*(3-2*t) + heaviside(t-1)
@@ -69,6 +65,10 @@ using Test
6965
Ψ_rot_dgyre = (1-st) * Ψ_P + st * Ψ_F
7066
end
7167
rot_double_gyre = @velo_from_stream Ψ_rot_dgyre
68+
rot_double_gyre! = @velo!_from_stream Ψ_rot_dgyre
69+
@test rot_double_gyre(SVector{2}(0.0,0.0), nothing, 0.0) == rot_double_gyre!(ones(2), zeros(2), nothing, 0.0)
70+
VERSION v"1.1" && @test iszero(@allocated rot_double_gyre!(du, u, nothing, t))
71+
7272
dgyrepast = @velo_from_stream Ψ_P begin
7373
Ψ_P = sin(2π*x)*sin*y)
7474
end

0 commit comments

Comments
 (0)