Filters

In this tutorial we show the result of applying filters available in the CliMA codebase in a 1 dimensional box advection setup. See Filters API for filters interface details.

using ClimateMachine
const clima_dir = dirname(dirname(pathof(ClimateMachine)));
include(joinpath(clima_dir, "tutorials", "Numerics", "DGMethods", "Box1D.jl"))

output_dir = @__DIR__;
mkpath(output_dir);

The unfiltered result of the box advection test for order 4 polynomial with central flux is

run_box1D(4, 0.0, 1.0, 1.0, joinpath(output_dir, "box_1D_4_no_filter.svg"))
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 7.0629054001769518e+00
│     norm(Q) / norm(Q₀) = 9.9694358982360343e-01
└     norm(Q) - norm(Q₀) = -2.1653317359557889e-02
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222224183e+01
│     difference            = 1.5774048733874224e-12
└     normalized difference = 3.1428059739576215e-14

The unfiltered result of the box advection test for order 4 polynomial with Rusanov flux (aka upwinding for advection) is

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_no_filter_upwind.svg"),
    numerical_flux_first_order = RusanovNumericalFlux(),
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 7.0513534001494351e+00
│     norm(Q) / norm(Q₀) = 9.9531300131582212e-01
└     norm(Q) - norm(Q₀) = -3.3205317387074551e-02
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222224467e+01
│     difference            = 1.8616219676914625e-12
└     normalized difference = 3.7090773206166522e-14

Below we show results for the same box advection test but using different filters.

As seen in the results, when the TMAR filter is used mass is not necessarily conserved (mass increases are possible).

TMARFilter() with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_tmar.svg");
    tmar_filter = true,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 7.0284834766751523e+00
│     norm(Q) / norm(Q₀) = 9.9208486468994128e-01
└     norm(Q) - norm(Q₀) = -5.6075240861357400e-02
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0273717773327959e+01
│     difference            = 8.2745551105354309e-02
└     normalized difference = 1.6486142316390080e-03

Running the TMAR filter with Rusanov the mass conservation since some of the are reduced, but mass is still not conserved. TMARFilter() with Rusanov numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_tmar_upwind.svg");
    tmar_filter = true,
    numerical_flux_first_order = RusanovNumericalFlux(),
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 7.0195965557948741e+00
│     norm(Q) / norm(Q₀) = 9.9083045757234900e-01
└     norm(Q) - norm(Q₀) = -6.4962161741635605e-02
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0231802188006398e+01
│     difference            = 4.0829965783792943e-02
└     normalized difference = 8.1349222730766366e-04

CutoffFilter(grid, Nc=1) with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_cutoff_1.svg");
    cutoff_filter = true,
    cutoff_param = 1,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 4.3749269099663506e+00
│     norm(Q) / norm(Q₀) = 6.1752991038623639e-01
└     norm(Q) - norm(Q₀) = -2.7096318075701591e+00
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222220196e+01
│     difference            = -2.4087398742267396e-12
└     normalized difference = -4.7991496629352872e-14

CutoffFilter(grid, Nc=3) with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_cutoff_3.svg");
    cutoff_filter = true,
    cutoff_param = 3,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 7.0138240459750554e+00
│     norm(Q) / norm(Q₀) = 9.9001565596649466e-01
└     norm(Q) - norm(Q₀) = -7.0734671561454299e-02
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222238884e+01
│     difference            = 1.6278534076263895e-11
└     normalized difference = 3.2433191379895996e-13

ExponentialFilter(grid, Nc=1, s=4) with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_exp_1_4.svg");
    exp_filter = true,
    exp_param_1 = 1,
    exp_param_2 = 4,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 6.9333444856505491e+00
│     norm(Q) / norm(Q₀) = 9.7865580088825321e-01
└     norm(Q) - norm(Q₀) = -1.5121423188596061e-01
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222221269e+01
│     difference            = -1.3358203432289883e-12
└     normalized difference = -2.6614753292974451e-14

ExponentialFilter(grid, Nc=1, s=8) with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_exp_1_8.svg");
    exp_filter = true,
    exp_param_1 = 1,
    exp_param_2 = 8,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 7.0143099503307322e+00
│     norm(Q) / norm(Q₀) = 9.9008424236334025e-01
└     norm(Q) - norm(Q₀) = -7.0248767205777440e-02
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222237839e+01
│     difference            = 1.5234036254696548e-11
└     normalized difference = 3.0352144180924054e-13

ExponentialFilter(grid, Nc=1, s=32) with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_exp_1_32.svg");
    exp_filter = true,
    exp_param_1 = 1,
    exp_param_2 = 32,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 7.0543517922303387e+00
│     norm(Q) / norm(Q₀) = 9.9573623051053284e-01
└     norm(Q) - norm(Q₀) = -3.0206925306170973e-02
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222231650e+01
│     difference            = 9.0452090262260754e-12
└     normalized difference = 1.8021585607423658e-13

BoydVandevenFilter(grid, Nc=1, s=4) with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_boyd_1_4.svg");
    boyd_filter = true,
    boyd_param_1 = 1,
    boyd_param_2 = 4,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 6.9612435701255597e+00
│     norm(Q) / norm(Q₀) = 9.8259381390887390e-01
└     norm(Q) - norm(Q₀) = -1.2331514741094995e-01
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222250601e+01
│     difference            = 2.7995383788947947e-11
└     normalized difference = 5.5777727645914540e-13

BoydVandevenFilter(grid, Nc=1, s=8) with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_boyd_1_8.svg");
    boyd_filter = true,
    boyd_param_1 = 1,
    boyd_param_2 = 8,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 6.9798736717024212e+00
│     norm(Q) / norm(Q₀) = 9.8522349097411532e-01
└     norm(Q) - norm(Q₀) = -1.0468504583408844e-01
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222227160e+01
│     difference            = 4.5545789362222422e-12
└     normalized difference = 9.0744983302109700e-14

BoydVandevenFilter(grid, Nc=1, s=32) with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_boyd_1_32.svg");
    boyd_filter = true,
    boyd_param_1 = 1,
    boyd_param_2 = 32,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 7.0120419256480133e+00
│     norm(Q) / norm(Q₀) = 9.8976410602554621e-01
└     norm(Q) - norm(Q₀) = -7.2516791888496357e-02
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0190972222248590e+01
│     difference            = 2.5984547846746864e-11
└     normalized difference = 5.1771357868301902e-13

ExponentialFilter(grid, Nc=1, s=8) and TMARFilter() with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_tmar_exp_1_8.svg");
    exp_filter = true,
    tmar_filter = true,
    exp_param_1 = 1,
    exp_param_2 = 8,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 6.9859473293754455e+00
│     norm(Q) / norm(Q₀) = 9.8608080021738409e-01
└     norm(Q) - norm(Q₀) = -9.8611388161064184e-02
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0255956701555064e+01
│     difference            = 6.4984479332458989e-02
└     normalized difference = 1.2947443824107953e-03

BoydVandevenFilter(grid, Nc=1, s=8) and TMARFilter() with central numerical flux:

run_box1D(
    4,
    0.0,
    1.0,
    1.0,
    joinpath(output_dir, "box_1D_4_tmar_boyd_1_8.svg");
    boyd_filter = true,
    tmar_filter = true,
    boyd_param_1 = 1,
    boyd_param_2 = 8,
)
┌ Info: Model composition
│     param_set = Main.ex-showcase_filters.EarthParameterSet()
│     init_q = 0.0
│     amplitude = 1.0
└     velo = 1.0
┌ Info: Establishing single stack configuration for Box1D
│     precision        = Float64
│     polynomial order = 4
│     domain_min       = 0.00 m x0.00 m x0.00 m
│     domain_max       = 1.00 m x1.00 m x350.00 m
│     #vert elems      = 128
│     MPI ranks        = 1
│     min(Δ_horz)      = 0.17 m
└     min(Δ_vert)      = 0.47 m
[ Info: Initializing Box1D
┌ Info: Starting Box1D
│     dt              = 4.71698e-01
│     timeend         =   450.00
│     number of steps = 954
└     norm(Q)         = 7.0845587175365097e+00
┌ Info: Finished
│     norm(Q)            = 6.9548646819395490e+00
│     norm(Q) / norm(Q₀) = 9.8169342075238542e-01
└     norm(Q) - norm(Q₀) = -1.2969403559696069e-01
┌ Info: Mass Conservation:
│     initial mass          = 5.0190972222222605e+01
│     final mass            = 5.0269145317360795e+01
│     difference            = 7.8173095138190263e-02
└     normalized difference = 1.5575130681285800e-03


This page was generated using Literate.jl.