Skip to content

Commit 09d57ca

Browse files
Merge pull request #1947 from CliMA/dy/integrals
Fix integrals for broadcasts and update docstrings
2 parents e0bf144 + 142e0cc commit 09d57ca

File tree

3 files changed

+35
-37
lines changed

3 files changed

+35
-37
lines changed

docs/make.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ withenv("GKSwstype" => "nul") do
5151
prettyurls = !isempty(get(ENV, "CI", "")),
5252
mathengine = mathengine,
5353
collapselevel = 1,
54+
size_threshold = 300_000, # default is 200_000
55+
size_threshold_warn = 200_000, # default is 100_000
5456
)
5557

5658
Documenter.makedocs(;

src/Operators/integrals.jl

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,45 @@ import RootSolvers
33
import ClimaComms
44

55
"""
6-
column_integral_definite!(∫field, ᶜfield, [init])
6+
column_integral_definite!(ϕ_top, ᶜ∂ϕ∂z, [ϕ_bot])
77
8-
Sets `∫field```{}= \\int_{z_{min}}^{z_{max}}\\,```ᶜfield```(z)\\,dz +{}```init`,
9-
where ``z_{min}`` and ``z_{max}`` are the values of `z` at the bottom and top of
10-
the domain, respectively. The input `ᶜfield` must lie on a cell-center space,
11-
and the output `∫field` must lie on the corresponding horizontal space. The
12-
default value of `init` is 0.
8+
Sets `ϕ_top```{}= \\int_{z_{bot}}^{z_{top}}\\,```ᶜ∂ϕ∂z```(z)\\,dz +{}```ϕ_bot`,
9+
where ``z_{bot}`` and ``z_{top}`` are the values of `z` at the bottom and top of
10+
the domain, respectively. The input `ᶜ∂ϕ∂z` should be a cell-center `Field` or
11+
`AbstractBroadcasted`, and the output `ϕ_top` should be a horizontal `Field`.
12+
The default value of `ϕ_bot` is 0.
1313
"""
14-
function column_integral_definite!(∫field, ᶜfield, init = rzero(eltype(∫field)))
15-
ᶜfield_times_Δz =
16-
Base.Broadcast.broadcasted(, ᶜfield, Fields.Δz_field(ᶜfield))
17-
column_reduce!(, ∫field, ᶜfield_times_Δz; init)
14+
function column_integral_definite!(ϕ_top, ᶜ∂ϕ∂z, ϕ_bot = rzero(eltype(ϕ_top)))
15+
ᶜΔϕ = Base.Broadcast.broadcasted(, ᶜ∂ϕ∂z, Fields.Δz_field(axes(ᶜ∂ϕ∂z)))
16+
column_reduce!(, ϕ_top, ᶜΔϕ; init = ϕ_bot)
1817
end
1918

2019
"""
21-
column_integral_indefinite!(ᶠ∫field, ᶜfield, [init])
20+
column_integral_indefinite!(ᶠϕ, ᶜ∂ϕ∂z, [ϕ_bot])
2221
23-
Sets `ᶠ∫field```(z) = \\int_{z_{min}}^z\\,```ᶜfield```(z')\\,dz' +{}```init`,
24-
where ``z_{min}`` is the value of `z` at the bottom of the domain. The input
25-
`ᶜfield` must lie on a cell-center space, and the output `ᶠ∫field` must lie on
26-
the corresponding cell-face space. The default value of `init` is 0.
22+
Sets `ᶠϕ```(z) = \\int_{z_{bot}}^z\\,```ᶜ∂ϕ∂z```(z')\\,dz' +{}```ϕ_bot`, where
23+
``z_{bot}`` is the value of `z` at the bottom of the domain. The input `ᶜ∂ϕ∂z`
24+
should be a cell-center `Field` or `AbstractBroadcasted`, and the output `ᶠϕ`
25+
should be a cell-face `Field`. The default value of `ϕ_bot` is 0.
2726
28-
column_integral_indefinite!(∂ϕ∂z, ᶠϕ, [ϕ₀], [rtol])
27+
column_integral_indefinite!(∂ϕ∂z, ᶠϕ, [ϕ_bot], [rtol])
2928
30-
Sets `ᶠϕ```(z) = \\int_{z_{min}}^z\\,```∂ϕ∂z```(```ᶠϕ```(z'), z')\\,dz' +{}```ϕ₀`
31-
for any scalar-valued two-argument function `∂ϕ∂z`. That is, the output `ᶠϕ` is
32-
such that `ᶜgradᵥ.(ᶠϕ) ≈ ∂ϕ∂z.(ᶜint.(ᶠϕ), ᶜz)`, where `ᶜgradᵥ = GradientF2C()`,
33-
`ᶜint = InterpolateF2C()`, and `ᶜz = Fields.coordinate_field(ᶜint.(ᶠϕ)).z`. The
34-
approximation is accurate to a relative tolerance of `rtol`. The default value
35-
of `ϕ₀` is 0, and the default value of `rtol` is 0.001.
29+
Sets
30+
`ᶠϕ```(z) = \\int_{z_{bot}}^z\\,```∂ϕ∂z```(```ᶠϕ```(z'), z')\\,dz' +{}```ϕ_bot`,
31+
where `∂ϕ∂z` can be any scalar-valued two-argument function. The output `ᶠϕ`
32+
satisfies `ᶜgradᵥ.(ᶠϕ) ≈ ∂ϕ∂z.(ᶜint.(ᶠϕ), ᶜz)`, where `ᶜgradᵥ = GradientF2C()`,
33+
`ᶜint = InterpolateF2C()`, and `ᶜz = Fields.coordinate_field(ᶜint.(ᶠϕ)).z`, and
34+
where the approximation is accurate to a relative tolerance of `rtol`. The
35+
default value of `ϕ_bot` is 0, and the default value of `rtol` is 0.001.
3636
"""
37-
function column_integral_indefinite!(
38-
ᶠ∫field,
39-
ᶜfield,
40-
init = rzero(eltype(ᶠ∫field)),
41-
)
42-
ᶜfield_times_Δz =
43-
Base.Broadcast.broadcasted(, ᶜfield, Fields.Δz_field(ᶜfield))
44-
column_accumulate!(, ᶠ∫field, ᶜfield_times_Δz; init)
37+
function column_integral_indefinite!(ᶠϕ, ᶜ∂ϕ∂z, ϕ_bot = rzero(eltype(ᶠϕ)))
38+
ᶜΔϕ = Base.Broadcast.broadcasted(, ᶜ∂ϕ∂z, Fields.Δz_field(axes(ᶜ∂ϕ∂z)))
39+
column_accumulate!(, ᶠϕ, ᶜΔϕ; init = ϕ_bot)
4540
end
4641
function column_integral_indefinite!(
4742
∂ϕ∂z::F,
4843
ᶠϕ,
49-
ϕ₀ = eltype(ᶠϕ)(0),
44+
ϕ_bot = eltype(ᶠϕ)(0),
5045
rtol = eltype(ᶠϕ)(0.001),
5146
) where {F <: Function}
5247
device = ClimaComms.device(ᶠϕ)
@@ -61,7 +56,7 @@ function column_integral_indefinite!(
6156
ᶜz = Fields.coordinate_field(center_space).z
6257
ᶜΔz = Fields.Δz_field(center_space)
6358
ᶜz_and_Δz = Base.Broadcast.broadcasted(tuple, ᶜz, ᶜΔz)
64-
column_accumulate!(ᶠϕ, ᶜz_and_Δz; init = ϕ₀) do ϕ_prev, (z, Δz)
59+
column_accumulate!(ᶠϕ, ᶜz_and_Δz; init = ϕ_bot) do ϕ_prev, (z, Δz)
6560
residual(ϕ_new) = (ϕ_new - ϕ_prev) / Δz - ∂ϕ∂z((ϕ_prev + ϕ_new) / 2, z)
6661
(; converged, root) = RootSolvers.find_zero(
6762
residual,

test/Operators/integrals.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,10 @@ function test_column_integral_definite!(center_space)
3434
ᶜz = Fields.coordinate_field(center_space).z
3535
ᶠz = Fields.coordinate_field(face_space).z
3636
z_top = Fields.level(ᶠz, Operators.right_idx(face_space))
37-
ᶜu = map(z -> (; one = one(z), powers = (z, z^2, z^3)), ᶜz)
38-
device = ClimaComms.device(ᶜu)
39-
∫u_ref = ClimaComms.allowscalar(device) do
40-
map(z -> (; one = z, powers = (z^2 / 2, z^3 / 3, z^4 / 4)), z_top)
37+
ᶜu = Base.Broadcast.broadcasted(ᶜz) do z
38+
(; one = one(z), powers = (z, z^2, z^3))
4139
end
40+
∫u_ref = map(z -> (; one = z, powers = (z^2 / 2, z^3 / 3, z^4 / 4)), z_top)
4241
∫u_test = similar(∫u_ref)
4342

4443
column_integral_definite!(∫u_test, ᶜu)
@@ -57,7 +56,9 @@ function test_column_integral_indefinite!(center_space)
5756
face_space = center_to_face_space(center_space)
5857
ᶜz = Fields.coordinate_field(center_space).z
5958
ᶠz = Fields.coordinate_field(face_space).z
60-
ᶜu = map(z -> (; one = one(z), powers = (z, z^2, z^3)), ᶜz)
59+
ᶜu = Base.Broadcast.broadcasted(ᶜz) do z
60+
(; one = one(z), powers = (z, z^2, z^3))
61+
end
6162
ᶠ∫u_ref = map(z -> (; one = z, powers = (z^2 / 2, z^3 / 3, z^4 / 4)), ᶠz)
6263
ᶠ∫u_test = similar(ᶠ∫u_ref)
6364

0 commit comments

Comments
 (0)