CliMA / CliMA/ClimaCore.jl

Update Simple FCT: lin combination of UpwindBiasedProductC2F + Upwind3rdOrderBiasedProductC2F convergence test to use same order approximation

Open
#2,092 6 comments 0 reactions 0 assignees View on GitHub
bug unit tests
Dominant language
Julia
Stars
117
Forks
19
Avg merge
3d 4h
Merged PRs (30d)
41

Description

I spoke with @akshaysridhar today about this [FCT test](https://github.com/CliMA/ClimaCore.jl/blob/a932c51ac0bf780586539629de2c0cf7a411bb5b/test/Operators/finitedifference/convergence_column.jl#L691-L760), and plotted the computed vs exact solutions:

Screenshot 2024-11-22 at 2 05 39 PM

Here's the full modified script in case it's helpful:

```julia
#=
julia --check-bounds=yes --project=.buildkite
using Revise; include("../cc_fd_biased_prod.jl")
=#
using Test
using ClimaCorePlots
using LazyBroadcast: @lazy
using Plots
using StaticArrays, IntervalSets, LinearAlgebra

using ClimaComms
ClimaComms.@import_required_backends
import ClimaCore: slab, Domains, Meshes, Topologies, Spaces, Fields, Operators
import ClimaCore.Domains: Geometry
import ClimaCore.DataLayouts: vindex

device = ClimaComms.device()

function stencil_location(space, bc, idx)
(li, lw, rw, ri) = Operators.window_bounds(space, bc)
if !Topologies.isperiodic(Spaces.vertical_topology(space))
if idx in li:(lw - 1)
return Operators.LeftBoundaryWindow{Spaces.left_boundary_name(space)}()
end
end
if idx in lw:rw
return Interior()
end
if !Topologies.isperiodic(Spaces.vertical_topology(space))
if idx in (rw + 1):ri
return Operators.RightBoundaryWindow{Spaces.right_boundary_name(space)}()
end
end
error("Uncaught case")
end

"""
convergence_rate(err, Δh)

Estimate convergence rate given vectors `err` and `Δh`

err = C Δh^p+ H.O.T
err_k ≈ C Δh_k^p
err_k/err_m ≈ Δh_k^p/Δh_m^p
log(err_k/err_m) ≈ log((Δh_k/Δh_m)^p)
log(err_k/err_m) ≈ p*log(Δh_k/Δh_m)
log(err_k/err_m)/log(Δh_k/Δh_m) ≈ p

"""
convergence_rate(err, Δh) =
[log(err[i] / err[i - 1]) / log(Δh[i] / Δh[i - 1]) for i in 2:length(Δh)]

FT = Float64
n_elems_seq = 2 .^ (4, 6, 8, 10)
stretch_fns = (Meshes.Uniform(), Meshes.ExponentialStretching(1.0))
device = ClimaComms.device()

i = 1
stretch_fn = stretch_fns[1]
err_adv_wc = zeros(FT, length(n_elems_seq))
Δh = zeros(FT, length(n_elems_seq))
Plots.plot()
for (k, n) in enumerate(n_elems_seq)
domain = Domains.IntervalDomain(
Geometry.ZPoint{FT}(-pi),
Geometry.ZPoint{FT}(pi);
boundary_names = (:bottom, :top),
)
mesh = Meshes.IntervalMesh(domain, stretch_fn; nelems = n)

cs = Spaces.CenterFiniteDifferenceSpace(device, mesh)
fs = Spaces.FaceFiniteDifferenceSpace(cs)

zc = Fields.coordinate_field(cs).z
C = FT(1.0) # flux-correction coefficient (falling back to third-order upwinding)

# UpwindBiasedProductC2F & Upwind3rdOrderBiasedProductC2F Center -> Face operator
# Unitary, constant advective velocity
w = Geometry.WVector.(ones(fs))
# parent(w) .= parent(w) * -1
Δz = FT(2pi / n)
c = sin.(zc)

zcontra3 = Geometry.Contravariant3Vector(FT(0.0))

first_order_fluxᶠ = Operators.UpwindBiasedProductC2F(
bottom = Operators.Extrapolate(),
top = Operators.Extrapolate(),
)
third_order_fluxᶠ = Operators.Upwind3rdOrderBiasedProductC2F(
bottom = Operators.FirstOrderOneSided(),
top = Operators.FirstOrderOneSided(),
)

divf2c = Operators.DivergenceF2C(
bottom = Operators.SetValue(
zcontra3,
),
top = Operators.SetValue(
zcontra3,
),
)

adv_wc = @lazy @. divf2c.(third_order_fluxᶠ(w, c))
zero_bc = Operators.SetBoundaryOperator(;
bottom = Operators.SetValue(zcontra3), top = Operators.SetValue(zcontra3)
)
zbc = zero_bc.(third_order_fluxᶠ.(w, c)).components.data.:1
zbc .= zbc ./ maximum(zbc) .* maximum(c)
Δh[k] = Spaces.local_geometry_data(fs).J[vindex(1)]

exact = cos.(zc)
err = parent(Fields.field_values(abs.(Base.materialize(adv_wc) .- exact)))

if k==1
Plots.plot!(cos.(zc); label = "exact")
end
Plots.plot!(Base.materialize(adv_wc); label = "computed, dh=$(round(Δh[k]; digits=4))")
Plots.plot!(c; label = "c, dh=$(round(Δh[k]; digits=4))")
Plots.plot!(zbc; label = "zbc, dh=$(round(Δh[k]; digits=4))")

# Error
err_adv_wc[k] = norm(Base.materialize(adv_wc) .- cos.(zc))
end
Plots.plot!(; legend = :topleft)
Plots.png("convergence_ubp.png")
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with test/Operators/finitedifference/convergence_column.jl at lines 691-760 and compare it with the modified script in the issue. Run the FCT convergence test, inspect the computed versus exact solutions and convergence behavior, then update the test so the linear combination uses the same order approximation. Done means the test reflects the intended approximation and its convergence results are consistent.

Written by the indexing model from the issue text.

Assessment

Tech stack
julia
Domain
testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.