diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 43768fae..c261cb88 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.6.7","generation_timestamp":"2024-06-10T19:31:48","documenter_version":"1.4.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.6.7","generation_timestamp":"2024-06-14T15:19:54","documenter_version":"1.4.1"}} \ No newline at end of file diff --git a/dev/ad/index.html b/dev/ad/index.html index d7587b02..22bbdd5c 100644 --- a/dev/ad/index.html +++ b/dev/ad/index.html @@ -85,14 +85,14 @@ @assert ForwardDiff.partials(f_df, 1) ≈ D * v # the Jacobian of `f(u) = D * u` is `D`

You can of course also use this with nonlinear functions, e.g.,

f(u, D) = u .* (D * (u.^2))
 
 f_df = f(u_v, D)
8-element StructArray(::Vector{Float64}, ::Vector{ForwardDiff.Partials{1, Float64}}) with eltype ForwardDiff.Dual{Nothing, Float64, 1}:
-   Dual{Nothing}(0.6650868699388505,1.7220143831332893)
-  Dual{Nothing}(12.115982270742396,-22.67684512357635)
-  Dual{Nothing}(15.453463033253659,22.590202976422688)
- Dual{Nothing}(-25.70172828056758,2.582974492409163)
-  Dual{Nothing}(-0.7991798798007577,-9.865358330502753)
-   Dual{Nothing}(0.1793509494139822,-1.4969080395696006)
-   Dual{Nothing}(0.008898740388859672,0.08391375449061213)
-  Dual{Nothing}(-1.0526189910737827,-0.6620714057873776)

The Jacobian of this function is

using LinearAlgebra
+ Dual{Nothing}(-1.0803574671683276,5.352332694973359)
+  Dual{Nothing}(0.9834603055010078,-0.52978595264932)
+ Dual{Nothing}(-0.9147808707906251,1.658525901851851)
+  Dual{Nothing}(0.3968332383135114,-11.836379590271717)
+ Dual{Nothing}(-2.3521922204436465,25.76026066601995)
+ Dual{Nothing}(-5.931592247894148,21.39488977054527)
+  Dual{Nothing}(1.0805319966370046,12.93213364958514)
+  Dual{Nothing}(0.9483238461186805,-0.008488662503189026)

The Jacobian of this function is

using LinearAlgebra
 
 J = Diagonal(D * u.^2) + 2 .* u .* Matrix(D) * Diagonal(u)
 
@@ -116,4 +116,4 @@
       Status `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl/docs/Manifest.toml`
   [f6369f11] ForwardDiff v0.10.36
   [09ab397b] StructArrays v0.6.18
-  [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl`
+ [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` diff --git a/dev/api_reference/index.html b/dev/api_reference/index.html index 5c4a8af7..bac92203 100644 --- a/dev/api_reference/index.html +++ b/dev/api_reference/index.html @@ -12,35 +12,37 @@ pages={3454}, publisher={The Open Journal}, url={https://github.com/ranocha/SummationByPartsOperators.jl} -}source
SummationByPartsOperators.BeljaddLeFlochMishraParés2017Type
BeljaddLeFlochMishraParés2017()

Coefficients of the periodic operators given in

  • Beljadid, LeFloch, Mishra, Parés (2017) Schemes with Well-Controlled Dissipation. Hyperbolic Systems in Nonconservative Form. Communications in Computational Physics 21.4, pp. 913-946.
source
SummationByPartsOperators.BurgersNonperiodicSemidiscretizationType
BurgersNonperiodicSemidiscretization(D, Di, split_form, left_bc, right_bc)

A semidiscretization of Burgers' equation $\partial_t u(t,x) + \partial_x \frac{u(t,x)^2}{2} = 0$ with boundary conditions left_bc(t), right_bc(t).

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.BurgersPeriodicSemidiscretizationType
BurgersPeriodicSemidiscretization(D, Di, split_form)

A semidiscretization of Burgers' equation $\partial_t u(t,x) + \partial_x \frac{u(t,x)^2}{2} = 0$ with periodic boundary conditions.

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.ConstantFilterType
ConstantFilter

Represents the action of a modal filter on values in a nodal basis with fixed strength.

source
SummationByPartsOperators.ConstantFilterMethod
ConstantFilter(D::FourierDerivativeOperator, filter)

Create a modal filter with constant parameters adapted to the Fourier derivative operator D with parameters given by the filter function filter.

source
SummationByPartsOperators.ConstantFilterMethod
ConstantFilter(D::LegendreDerivativeOperator, filter, TmpEltype=T)

Create a modal filter with constant parameters adapted to the Legendre derivative operator D with parameters given by the filter function filter.

source
SummationByPartsOperators.CubicNonperiodicSemidiscretizationType
CubicNonperiodicSemidiscretization(D, Di, split_form, left_bc, right_bc)

A semidiscretization of the cubic conservation law $\partial_t u(t,x) + \partial_x u(t,x)^3 = 0$ with nonperiodic boundary conditions left_bc(t), right_bc(t).

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.CubicPeriodicSemidiscretizationType
CubicPeriodicSemidiscretization(D, Di, split_form)

A semidiscretization of the cubic conservation law $\partial_t u(t,x) + \partial_x u(t,x)^3 = 0$ with periodic boundary conditions.

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.DerivativeCoefficientRowType
DerivativeCoefficientRow{T,Start,Length}

A struct representing a row in the boundary block of an SBP derivative operator with scalar type T.

source
SummationByPartsOperators.DerivativeCoefficientsType
DerivativeCoefficients

The coefficients of a derivative operator on a nonperiodic grid.

source
SummationByPartsOperators.DerivativeOperatorType
DerivativeOperator

A derivative operator on a nonperiodic finite difference grid. See derivative_operator.

source
SummationByPartsOperators.DienerDorbandSchnetterTiglio2007Type
DienerDorbandSchnetterTiglio2007()

Coefficients of the SBP operators given in

  • Diener, Dorband, Schnetter, Tiglio (2007) Optimized high-order derivative and dissipation operators satisfying summation by parts, and applications in three-dimensional multi-block evolutions. Journal of Scientific Computing 32.1, pp. 109-145.

See also (second- and fourth-order operators)

  • Mattsson, Nordström (2004) Summation by parts operators for finite difference approximations of second derivatives. Journal of Computational Physics 199, pp. 503-540.

The dissipation operators proposed by Diener, Dorband, Schnetter, Tiglio (2007) for the diagonal-norm operators are the same as the ones of

  • Mattsson, Svärd, Nordström (2004) Stable and Accurate Artificial Dissipation. Journal of Scientific Computing 21.1, pp. 57-79.
source
SummationByPartsOperators.DissipationOperatorType
DissipationOperator

A dissipation operator on a nonperiodic finite difference grid. See dissipation_operator.

source
SummationByPartsOperators.ExponentialFilterType
ExponentialFilter

Represents the exponential filter function σ(η) = exp(-α*η^p).

source
SummationByPartsOperators.FactorisationWrapperType
FactorisationWrapper

A small wrapper around a a factorisation fact, allowing to represent multiplication by the inverse of fact.

source
SummationByPartsOperators.FastModeType
FastMode()

A (probably) faster execution mode that might depend on packages such as LoopVectorization.jl.

source
SummationByPartsOperators.Fornberg1998Type
Fornberg1998()

Coefficients of the periodic operators given in

  • Fornberg (1998) Calculation of Weights in Finite Difference Formulas. SIAM Rev. 40.3, pp. 685-691.
source
SummationByPartsOperators.FourierConstantViscosityType
FourierConstantViscosity

Fourier viscosity operator with constant coefficients for the periodic 1st derivative Fourier operator.

source
SummationByPartsOperators.FourierDerivativeOperatorType
FourierDerivativeOperator{T}

A derivative operator on a periodic grid with real scalar type T computing the first derivative using a spectral Fourier expansion via real discrete Fourier transforms.

See also fourier_derivative_operator.

source
SummationByPartsOperators.FourierDerivativeOperatorMethod
FourierDerivativeOperator(xmin::T, xmax::T, N::Integer) where {T<:Real}

Construct the FourierDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N÷2+1 complex Fourier modes.

See also fourier_derivative_operator.

source
SummationByPartsOperators.FourierDerivativeOperator2DType
FourierDerivativeOperator2D{T<:Real}

A derivative operator on a two-dimensional periodic grid with scalar type T computing the first derivatives using a spectral Fourier expansion via real discrete Fourier transforms.

source
SummationByPartsOperators.FourierDerivativeOperator2DMethod
FourierDerivativeOperator2D(xmin, xmax, Nx, ymin, ymax, Ny)

Construct the FourierDerivativeOperator on a uniform grid between xmin and xmax using Nx nodes and ymin and ymax using Ny nodes.

source
SummationByPartsOperators.Holoborodko2008Type
Holoborodko2008()

Coefficients of the periodic operators given in

  • Holoborodko (2008) Smooth Noise Robust Differentiators. http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
source
SummationByPartsOperators.LegendreDerivativeOperatorType
LegendreDerivativeOperator{T<:Real}

A derivative operator on a nonperiodic Lobatto-Legendre grid with scalar type T computing the first derivative using a Legendre expansion.

source
SummationByPartsOperators.LegendreDerivativeOperatorMethod
LegendreDerivativeOperator(xmin::T, xmax::T, N::Int) where {T<:Real}

Construct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.

source
SummationByPartsOperators.LegendreSecondDerivativeOperatorType
LegendreSecondDerivativeOperator{T<:Real}

A derivative operator on a nonperiodic Lobatto-Legendre grid with scalar type T computing the second derivative using a Legendre expansion.

source
SummationByPartsOperators.LinearlyCombinedDerivativeOperatorsType
LinearlyCombinedDerivativeOperators

Form linear combinations of several derivative operators lazily.

source
SummationByPartsOperators.MadayTadmor1989Type
MadayTadmor1989()

Coefficients of the Fourier spectral viscosity given in

  • Maday, Tadmor (1989) Analysis of the Spectral Vanishing Viscosity Method for Periodic Conservation Laws. SIAM Journal on Numerical Analysis 26.4, pp. 854-870.
source
SummationByPartsOperators.MatrixDerivativeOperatorType
MatrixDerivativeOperator{T <: Real}
-MatrixDerivativeOperator(xmin, xmax, nodes, weights, D, accuracy_order, source)

A derivative operator on a nonperiodic grid with scalar type T computing a derivative as matrix vector product. This type is designed to make it easy to experiment with new operators given in matrix form.

An instance of this type can be constructed by passing the endpoints xmin, xmax of the desired grid as well as the nodes, weights, and the derivative operator D::Matrix on a reference interval, assuming that the nodes contain the boundary points of the reference interval. source is the source of coefficients and can be nothing for experimentation.

source
SummationByPartsOperators.Mattsson2012Type
Mattsson2012()

Coefficients of the SBP operators given in

  • Mattsson (2012) Summation by Parts Operators for Finite Difference Approximations of Second-Derivatives with Variable Coefficients. Journal of Scientific Computing 51, pp. 650-682.
source
SummationByPartsOperators.Mattsson2014Type
Mattsson2014()

Coefficients of the SBP operators given in

  • Mattsson (2014) Diagonal-norm summation by parts operators for finite difference approximations of third and fourth derivatives. Journal of Computational Physics 274, pp. 432-454.
source
SummationByPartsOperators.Mattsson2017Type
Mattsson2017(version::Symbol)

Coefficients of the upwind SBP operators given in

  • Mattsson (2017) Diagonal-norm upwind SBP operators. Journal of Computational Physics 335, pp. 283-310.

You can choose between the different versions :central, :plus, and :minus.

source
SummationByPartsOperators.MattssonAlmquistCarpenter2014ExtendedType
MattssonAlmquistCarpenter2014Extended()

Coefficients of the extended SBP operators given in

  • Mattsson, Almquist, Carpenter (2014) Optimal diagonal-norm SBP operators. Journal of Computational Physics 264, pp. 91-111.
source
SummationByPartsOperators.MattssonAlmquistCarpenter2014OptimalType
MattssonAlmquistCarpenter2014Optimal()

Coefficients of the optimal SBP operators with nonuniform grid given in

  • Mattsson, Almquist, Carpenter (2014) Optimal diagonal-norm SBP operators. Journal of Computational Physics 264, pp. 91-111.
source
SummationByPartsOperators.MattssonAlmquistVanDerWeide2018AccurateType
MattssonAlmquistVanDerWeide2018Accurate()

Coefficients of the optimized SBP operators with nonuniform grid given in

  • Mattsson, Almquist, van der Weide (2018) Boundary optimized diagonal-norm SBP operators. Journal of Computational Physics 374, pp. 1261-1266.
source
SummationByPartsOperators.MattssonAlmquistVanDerWeide2018MinimalType
MattssonAlmquistVanDerWeide2018Minimal()

Coefficients of the optimized SBP operators with nonuniform grid given in

  • Mattsson, Almquist, van der Weide (2018) Boundary optimized diagonal-norm SBP operators. Journal of Computational Physics 374, pp. 1261-1266.
source
SummationByPartsOperators.MattssonNordström2004Type
MattssonNordström2004()

Coefficients of the SBP operators given in

  • Mattsson, Nordström (2004) Summation by parts operators for finite difference approximations of second derivatives. Journal of Computational Physics 199, pp. 503-540.
source
SummationByPartsOperators.MattssonSvärdNordström2004Type
MattssonSvärdNordström2004()

Coefficients of the SBP operators given in

  • Mattsson, Svärd, Nordström (2004) Stable and Accurate Artificial Dissipation. Journal of Scientific Computing 21.1, pp. 57-79.
source
SummationByPartsOperators.MattssonSvärdShoeybi2008Type
MattssonSvärdShoeybi2008()

Coefficients of the SBP operators given in

  • Mattsson, Svärd, Shoeybi (2008) Stable and accurate schemes for the compressible Navier-Stokes equations. Journal of Computational Physics 227, pp. 2293-2316.
source
SummationByPartsOperators.PeriodicDerivativeCoefficientsType
PeriodicDerivativeCoefficients

The coefficients of a derivative operator on a periodic grid.

source
SummationByPartsOperators.PeriodicDerivativeOperatorType
PeriodicDerivativeOperator

A derivative operator on a uniform periodic grid. See periodic_derivative_operator and periodic_central_derivative_operator.

source
SummationByPartsOperators.PeriodicDissipationOperatorType
PeriodicDissipationOperator

A dissipation operator on a periodic finite difference grid. See dissipation_operator.

source
SummationByPartsOperators.PeriodicUpwindOperatorsType
PeriodicUpwindOperators
-PeriodicUpwindOperators(D_minus, D_central, D_plus)

A struct bundling the individual operators available for periodic upwind SBP operators. The individual operators are available as D.minus, D.plus (and optionally D.central, if provided), where D::PeriodicUpwindOperators.

The combined struct behaves as much as possible as an operator itself as long as no ambiguities arise. For example, upwind operators need to use the same grid and mass matrix, so mass_matrix, grid, xmin, xmax etc. are available but mul! is not.

It is recommended to construct an instance of PeriodicUpwindOperators using upwind_operators. An instance can also be constructed manually by passing the operators in the order D_minus, D_central, D_plus.

See also upwind_operators, UpwindOperators

source
SummationByPartsOperators.QuarticNonconvexPeriodicSemidiscretizationType
QuarticNonconvexPeriodicSemidiscretization(D, Di, split_form)

A semidiscretization of the quartic nonconvex conservation law $\partial_t u(t,x) + \partial_x ( u(t,x)^4 - 10 u(t,x)^2 + 3 u(t,x) ) = 0$ with periodic boundary conditions.

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.SafeModeType
SafeMode()

A safe execution mode relying only on basic functionality of Julia.

source
SummationByPartsOperators.SharanBradyLivescu2022Type
SharanBradyLivescu2022(alpha_left, alpha_right)

Coefficients of the cut-cell SBP operators given in

  • Sharan, Brady, Livescu (2022) High-order dimensionally-split Cartesian embedded boundary method for non-dissipative schemes. Journal of Computational Physics 464, 111341.

Here, alpha_left * Δx is the spacing between the left endpoint and the second node, while alpha_right * Δx is the spacing between the right endpoint and the last node.

source
SummationByPartsOperators.SourceOfCoefficientsType
SourceOfCoefficients

All sources of coefficients (articles) are subtypes of this abstract type.

source
SummationByPartsOperators.Tadmor1989Type
Tadmor1989()

Coefficients of the Fourier spectral viscosity given in

  • Tadmor (1989) Convergence of Spectral Methods for Nonlinear Conservation Laws. SIAM Journal on Numerical Analysis 26.1, pp. 30-44.
source
SummationByPartsOperators.Tadmor1993Type
Tadmor1993()

Coefficients of the Fourier super spectral viscosity given in

  • Tadmor (1993) Super Viscosity and Spectral Approximations of Nonlinear Conservation Laws. Numerical Methods for Fluid Dynamics IV, pp. 69-82.
source
SummationByPartsOperators.TadmorWaagan2012ConvergentType
TadmorWaagan2012Convergent()

Coefficients of the Fourier spectral viscosity given in

  • Tadmor, Waagan (2012) Adaptive Spectral Viscosity for Hyperbolic Conservation Laws. SIAM Journal on Scientific Computing 34.2, pp. A993-A1009.

See also

  • Schochet (1990) The Rate of Convergence of Spectral-Viscosity Methods for Periodic Scalar Conservation Laws. SIAM Journal on Numerical Analysis 27.5, pp. 1142-1159.
source
SummationByPartsOperators.TadmorWaagan2012StandardType
TadmorWaagan2012Standard()

Coefficients of the Fourier spectral viscosity given in

  • Tadmor, Waagan (2012) Adaptive Spectral Viscosity for Hyperbolic Conservation Laws. SIAM Journal on Scientific Computing 34.2, pp. A993-A1009.
source
SummationByPartsOperators.ThreadedModeType
ThreadedMode()

An execution mode using multiple threads and possibly further optimizations, cf. FastMode.

source
SummationByPartsOperators.UniformMesh1DType
UniformMesh1D(xmin::Real, xmax::Real, Nx::Integer)
-UniformMesh1D(; xmin::Real, xmax::Real, Nx::Integer)

A uniform mesh in one space dimension of Nx cells between xmin and xmax.

source
SummationByPartsOperators.UniformPeriodicMesh1DType
UniformPeriodicMesh1D(xmin::Real, xmax::Real, Nx::Integer)
-UniformPeriodicMesh1D(; xmin::Real, xmax::Real, Nx::Integer)

A uniform periodic mesh in one space dimension of Nx cells between xmin and xmax.

source
SummationByPartsOperators.UpwindOperatorsType
UpwindOperators
-UpwindOperators(D_minus, D_central, D_plus)

A struct bundling the individual operators available for non-periodic upwind SBP operators. The individual operators are available as D.minus, D.plus (and optionally D.central, if provided), where D::UpwindOperators.

The combined struct behaves as much as possible as an operator itself as long as no ambiguities arise. For example, upwind operators need to use the same grid and mass matrix, so mass_matrix, grid, xmin, xmax etc. are available but mul! is not.

It is recommended to construct an instance of UpwindOperators using upwind_operators. An instance can also be constructed manually by passing the operators in the order D_minus, D_central, D_plus.

See also upwind_operators, PeriodicUpwindOperators

source
SummationByPartsOperators.VarCoefDerivativeCoefficientsType
VarCoefDerivativeCoefficients

The coefficients of a variable coefficient derivative operator on a nonperiodic grid.

source
SummationByPartsOperators.VarCoefDerivativeOperatorType
VarCoefDerivativeOperator

A dissipation operator on a nonperiodic finite difference grid.

source
SummationByPartsOperators.VariableLinearAdvectionNonperiodicSemidiscretizationType
VariableLinearAdvectionNonperiodicSemidiscretization(D, Di, a, split_form,
-                                                     left_bc, right_bc)

A semidiscretization of the linear advection equation $\partial_t u(t,x) + \partial_x ( a(x) u(t,x) ) = 0$ with boundary conditions left_bc(t), right_bc(t).

D is an SBP derivative operator, Di an associated dissipation operator or nothing, a(x) the variable coefficient, and split_form::Union{Val(false), Val(true)} determines whether the canonical split form or the conservative form should be used.

source
SummationByPartsOperators.VariableLinearAdvectionPeriodicSemidiscretizationType
VariableLinearAdvectionPeriodicSemidiscretization(D, Di, a, split_form)

A semidiscretization of the linear advection equation $\partial_t u(t,x) + \partial_x ( a(x) u(t,x) ) = 0$ with periodic boundary conditions.

D is a periodic SBP derivative operator, Di an associated dissipation operator or nothing, a(x) the variable coefficient, and split_form::Union{Val(false), Val(true)} determines whether the canonical split form or the conservative form should be used.

source
SummationByPartsOperators.WaveEquationNonperiodicSemidiscretizationType
WaveEquationNonperiodicSemidiscretization(D, left_bc, right_bc)

A semidiscretization of the linear wave equation $\partial_t^2 u(t,x) = \partial_x^2 u(t,x)$.

D is assumed to be a second-derivative SBP operator and the boundary conditions can be Val(:HomogeneousNeumann), Val(:HomogeneousDirichlet), or Val(:NonReflecting).

source
LinearAlgebra.mul!Function
mul!(du, D::DerivativeOperator, u, α=true, β=false)

Efficient in-place version of du = α * D * u + β * du. Note that du must not be aliased with u.

source
PolynomialBases.compute_coefficients!Method
compute_coefficients!(uval, u, D::AbstractDerivativeOperator)

Compute the nodal values of the function u at the grid associated to the derivative operator D and stores the result in uval.

source
PolynomialBases.compute_coefficientsMethod
compute_coefficients(u, D::AbstractDerivativeOperator)

Compute the nodal values of the function u at the grid associated to the derivative operator D.

source
PolynomialBases.evaluate_coefficients!Method
evaluate_coefficients!(xplot, uplot, u, D::AbstractDerivativeOperator)

Evaluates the nodal coefficients u at a grid associated to the derivative operator D and stores the result in xplot, uplot. Returns xplot, uplot, where xplot contains the nodes and uplot the corresponding values of u.

source
PolynomialBases.evaluate_coefficientsMethod
evaluate_coefficients(u, D::AbstractDerivativeOperator)

Evaluates the nodal coefficients u at a grid associated to the derivative operator D. Returns xplot, uplot, where xplot contains the nodes and uplot the corresponding values of u.

source
PolynomialBases.integrateMethod
integrate(func, u, D::DerivativeOperator)

Map the function func to the coefficients u and integrate with respect to the quadrature rule associated with the SBP derivative operator D.

source
PolynomialBases.integrateMethod
integrate(func, u, D::PeriodicDerivativeOperator)

Map the function func to the coefficients u and integrate with respect to the quadrature rule associated with the periodic derivative operator D.

source
PolynomialBases.integrateMethod
integrate(func, u, D::AbstractPeriodicDerivativeOperator)

Map the function func to the coefficients u and integrate with respect to the quadrature rule associated with the derivative operator D.

source
SummationByPartsOperators.accuracy_orderFunction
accuracy_order(D)

Return the order of accuracy of a derivative operator D. For SBP finite difference operators, this refers to the interior order of accuracy.

source
SummationByPartsOperators.couple_continuouslyFunction
couple_continuously(D, mesh)

Return a derivative operator corresponding to a continuous coupling of D on the cells of the given mesh as in (nodal) continuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are CG spectral element methods (CGSEM). However, a continuous coupling of arbitrary SBP operators is supported.

The mesh can be a UniformMesh1D or a UniformPeriodicMesh1D.

References

source
SummationByPartsOperators.couple_discontinuouslyFunction
couple_discontinuously(D, mesh, [coupling=Val(:central)])

Return a derivative operator corresponding to a discontinuous coupling of D on the cells of the given mesh as in (nodal) discontinuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are DG spectral element methods (DGSEM). However, a discontinuous coupling of arbitrary SBP operators is supported.

The mesh can be a UniformMesh1D or a UniformPeriodicMesh1D. The coupling can be

  • Val(:central) (default), resulting in classical SBP properties
  • Val(:minus) or Val(:plus), resulting in upwind SBP operators

References

source
SummationByPartsOperators.derivative_leftMethod
derivative_left(D::AbstractNonperiodicDerivativeOperator, der_order)

Get a representation of the linear functional evaluation the Nth derivative at the left boundary node as (dense) vector.

source
SummationByPartsOperators.derivative_leftMethod
derivative_left(D::DerivativeOperator, u, der_order::Val{N})

Compute the N-th derivative of the function given by the coefficients u at the left boundary of the grid.

source
SummationByPartsOperators.derivative_operatorFunction
derivative_operator(source_of_coefficients,
+}
source
SummationByPartsOperators.BeljaddLeFlochMishraParés2017Type
BeljaddLeFlochMishraParés2017()

Coefficients of the periodic operators given in

  • Beljadid, LeFloch, Mishra, Parés (2017) Schemes with Well-Controlled Dissipation. Hyperbolic Systems in Nonconservative Form. Communications in Computational Physics 21.4, pp. 913-946.
source
SummationByPartsOperators.BurgersNonperiodicSemidiscretizationType
BurgersNonperiodicSemidiscretization(D, Di, split_form, left_bc, right_bc)

A semidiscretization of Burgers' equation $\partial_t u(t,x) + \partial_x \frac{u(t,x)^2}{2} = 0$ with boundary conditions left_bc(t), right_bc(t).

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.BurgersPeriodicSemidiscretizationType
BurgersPeriodicSemidiscretization(D, Di, split_form)

A semidiscretization of Burgers' equation $\partial_t u(t,x) + \partial_x \frac{u(t,x)^2}{2} = 0$ with periodic boundary conditions.

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.ConstantFilterType
ConstantFilter

Represents the action of a modal filter on values in a nodal basis with fixed strength.

source
SummationByPartsOperators.ConstantFilterMethod
ConstantFilter(D::FourierDerivativeOperator, filter)

Create a modal filter with constant parameters adapted to the Fourier derivative operator D with parameters given by the filter function filter.

source
SummationByPartsOperators.ConstantFilterMethod
ConstantFilter(D::LegendreDerivativeOperator, filter, TmpEltype=T)

Create a modal filter with constant parameters adapted to the Legendre derivative operator D with parameters given by the filter function filter.

source
SummationByPartsOperators.CubicNonperiodicSemidiscretizationType
CubicNonperiodicSemidiscretization(D, Di, split_form, left_bc, right_bc)

A semidiscretization of the cubic conservation law $\partial_t u(t,x) + \partial_x u(t,x)^3 = 0$ with nonperiodic boundary conditions left_bc(t), right_bc(t).

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.CubicPeriodicSemidiscretizationType
CubicPeriodicSemidiscretization(D, Di, split_form)

A semidiscretization of the cubic conservation law $\partial_t u(t,x) + \partial_x u(t,x)^3 = 0$ with periodic boundary conditions.

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.DerivativeCoefficientRowType
DerivativeCoefficientRow{T,Start,Length}

A struct representing a row in the boundary block of an SBP derivative operator with scalar type T.

source
SummationByPartsOperators.DerivativeCoefficientsType
DerivativeCoefficients

The coefficients of a derivative operator on a nonperiodic grid.

source
SummationByPartsOperators.DerivativeOperatorType
DerivativeOperator

A derivative operator on a nonperiodic finite difference grid. See derivative_operator.

source
SummationByPartsOperators.DienerDorbandSchnetterTiglio2007Type
DienerDorbandSchnetterTiglio2007()

Coefficients of the SBP operators given in

  • Diener, Dorband, Schnetter, Tiglio (2007) Optimized high-order derivative and dissipation operators satisfying summation by parts, and applications in three-dimensional multi-block evolutions. Journal of Scientific Computing 32.1, pp. 109-145.

See also (second- and fourth-order operators)

  • Mattsson, Nordström (2004) Summation by parts operators for finite difference approximations of second derivatives. Journal of Computational Physics 199, pp. 503-540.

The dissipation operators proposed by Diener, Dorband, Schnetter, Tiglio (2007) for the diagonal-norm operators are the same as the ones of

  • Mattsson, Svärd, Nordström (2004) Stable and Accurate Artificial Dissipation. Journal of Scientific Computing 21.1, pp. 57-79.
source
SummationByPartsOperators.DissipationOperatorType
DissipationOperator

A dissipation operator on a nonperiodic finite difference grid. See dissipation_operator.

source
SummationByPartsOperators.ExponentialFilterType
ExponentialFilter

Represents the exponential filter function σ(η) = exp(-α*η^p).

source
SummationByPartsOperators.FactorisationWrapperType
FactorisationWrapper

A small wrapper around a a factorisation fact, allowing to represent multiplication by the inverse of fact.

source
SummationByPartsOperators.FastModeType
FastMode()

A (probably) faster execution mode that might depend on packages such as LoopVectorization.jl.

source
SummationByPartsOperators.Fornberg1998Type
Fornberg1998()

Coefficients of the periodic operators given in

  • Fornberg (1998) Calculation of Weights in Finite Difference Formulas. SIAM Rev. 40.3, pp. 685-691.
source
SummationByPartsOperators.FourierConstantViscosityType
FourierConstantViscosity

Fourier viscosity operator with constant coefficients for the periodic 1st derivative Fourier operator.

source
SummationByPartsOperators.FourierDerivativeOperatorType
FourierDerivativeOperator{T}

A derivative operator on a periodic grid with real scalar type T computing the first derivative using a spectral Fourier expansion via real discrete Fourier transforms.

See also fourier_derivative_operator.

source
SummationByPartsOperators.FourierDerivativeOperatorMethod
FourierDerivativeOperator(xmin::T, xmax::T, N::Integer) where {T<:Real}

Construct the FourierDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N÷2+1 complex Fourier modes.

See also fourier_derivative_operator.

source
SummationByPartsOperators.FourierDerivativeOperator2DType
FourierDerivativeOperator2D{T<:Real}

A derivative operator on a two-dimensional periodic grid with scalar type T computing the first derivatives using a spectral Fourier expansion via real discrete Fourier transforms.

source
SummationByPartsOperators.FourierDerivativeOperator2DMethod
FourierDerivativeOperator2D(xmin, xmax, Nx, ymin, ymax, Ny)

Construct the FourierDerivativeOperator on a uniform grid between xmin and xmax using Nx nodes and ymin and ymax using Ny nodes.

source
SummationByPartsOperators.GlaubitzNordströmÖffner2023Type
GlaubitzNordströmÖffner2023()

Function space SBP (FSBP) operators given in

  • Glaubitz, Nordström, Öffner (2023) Summation-by-parts operators for general function spaces. SIAM Journal on Numerical Analysis 61, 2, pp. 733-754.

See also

  • Glaubitz, Nordström, Öffner (2024) An optimization-based construction procedure for function space based summation-by-parts operators on arbitrary grids. arXiv, arXiv:2405.08770v1.

See function_space_operator.

source
SummationByPartsOperators.Holoborodko2008Type
Holoborodko2008()

Coefficients of the periodic operators given in

  • Holoborodko (2008) Smooth Noise Robust Differentiators. http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
source
SummationByPartsOperators.LegendreDerivativeOperatorType
LegendreDerivativeOperator{T<:Real}

A derivative operator on a nonperiodic Lobatto-Legendre grid with scalar type T computing the first derivative using a Legendre expansion.

source
SummationByPartsOperators.LegendreDerivativeOperatorMethod
LegendreDerivativeOperator(xmin::T, xmax::T, N::Int) where {T<:Real}

Construct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.

source
SummationByPartsOperators.LegendreSecondDerivativeOperatorType
LegendreSecondDerivativeOperator{T<:Real}

A derivative operator on a nonperiodic Lobatto-Legendre grid with scalar type T computing the second derivative using a Legendre expansion.

source
SummationByPartsOperators.LinearlyCombinedDerivativeOperatorsType
LinearlyCombinedDerivativeOperators

Form linear combinations of several derivative operators lazily.

source
SummationByPartsOperators.MadayTadmor1989Type
MadayTadmor1989()

Coefficients of the Fourier spectral viscosity given in

  • Maday, Tadmor (1989) Analysis of the Spectral Vanishing Viscosity Method for Periodic Conservation Laws. SIAM Journal on Numerical Analysis 26.4, pp. 854-870.
source
SummationByPartsOperators.MatrixDerivativeOperatorType
MatrixDerivativeOperator{T <: Real}
+MatrixDerivativeOperator(xmin, xmax, nodes, weights, D, accuracy_order, source)

A derivative operator on a nonperiodic grid with scalar type T computing a derivative as matrix vector product. This type is designed to make it easy to experiment with new operators given in matrix form.

An instance of this type can be constructed by passing the endpoints xmin, xmax of the desired grid as well as the nodes, weights, and the derivative operator D::Matrix on a reference interval, assuming that the nodes contain the boundary points of the reference interval. source is the source of coefficients and can be nothing for experimentation.

source
SummationByPartsOperators.Mattsson2012Type
Mattsson2012()

Coefficients of the SBP operators given in

  • Mattsson (2012) Summation by Parts Operators for Finite Difference Approximations of Second-Derivatives with Variable Coefficients. Journal of Scientific Computing 51, pp. 650-682.
source
SummationByPartsOperators.Mattsson2014Type
Mattsson2014()

Coefficients of the SBP operators given in

  • Mattsson (2014) Diagonal-norm summation by parts operators for finite difference approximations of third and fourth derivatives. Journal of Computational Physics 274, pp. 432-454.
source
SummationByPartsOperators.Mattsson2017Type
Mattsson2017(version::Symbol)

Coefficients of the upwind SBP operators given in

  • Mattsson (2017) Diagonal-norm upwind SBP operators. Journal of Computational Physics 335, pp. 283-310.

You can choose between the different versions :central, :plus, and :minus.

source
SummationByPartsOperators.MattssonAlmquistCarpenter2014ExtendedType
MattssonAlmquistCarpenter2014Extended()

Coefficients of the extended SBP operators given in

  • Mattsson, Almquist, Carpenter (2014) Optimal diagonal-norm SBP operators. Journal of Computational Physics 264, pp. 91-111.
source
SummationByPartsOperators.MattssonAlmquistCarpenter2014OptimalType
MattssonAlmquistCarpenter2014Optimal()

Coefficients of the optimal SBP operators with nonuniform grid given in

  • Mattsson, Almquist, Carpenter (2014) Optimal diagonal-norm SBP operators. Journal of Computational Physics 264, pp. 91-111.
source
SummationByPartsOperators.MattssonAlmquistVanDerWeide2018AccurateType
MattssonAlmquistVanDerWeide2018Accurate()

Coefficients of the optimized SBP operators with nonuniform grid given in

  • Mattsson, Almquist, van der Weide (2018) Boundary optimized diagonal-norm SBP operators. Journal of Computational Physics 374, pp. 1261-1266.
source
SummationByPartsOperators.MattssonAlmquistVanDerWeide2018MinimalType
MattssonAlmquistVanDerWeide2018Minimal()

Coefficients of the optimized SBP operators with nonuniform grid given in

  • Mattsson, Almquist, van der Weide (2018) Boundary optimized diagonal-norm SBP operators. Journal of Computational Physics 374, pp. 1261-1266.
source
SummationByPartsOperators.MattssonNordström2004Type
MattssonNordström2004()

Coefficients of the SBP operators given in

  • Mattsson, Nordström (2004) Summation by parts operators for finite difference approximations of second derivatives. Journal of Computational Physics 199, pp. 503-540.
source
SummationByPartsOperators.MattssonSvärdNordström2004Type
MattssonSvärdNordström2004()

Coefficients of the SBP operators given in

  • Mattsson, Svärd, Nordström (2004) Stable and Accurate Artificial Dissipation. Journal of Scientific Computing 21.1, pp. 57-79.
source
SummationByPartsOperators.MattssonSvärdShoeybi2008Type
MattssonSvärdShoeybi2008()

Coefficients of the SBP operators given in

  • Mattsson, Svärd, Shoeybi (2008) Stable and accurate schemes for the compressible Navier-Stokes equations. Journal of Computational Physics 227, pp. 2293-2316.
source
SummationByPartsOperators.PeriodicDerivativeCoefficientsType
PeriodicDerivativeCoefficients

The coefficients of a derivative operator on a periodic grid.

source
SummationByPartsOperators.PeriodicDerivativeOperatorType
PeriodicDerivativeOperator

A derivative operator on a uniform periodic grid. See periodic_derivative_operator and periodic_central_derivative_operator.

source
SummationByPartsOperators.PeriodicDissipationOperatorType
PeriodicDissipationOperator

A dissipation operator on a periodic finite difference grid. See dissipation_operator.

source
SummationByPartsOperators.PeriodicUpwindOperatorsType
PeriodicUpwindOperators
+PeriodicUpwindOperators(D_minus, D_central, D_plus)

A struct bundling the individual operators available for periodic upwind SBP operators. The individual operators are available as D.minus, D.plus (and optionally D.central, if provided), where D::PeriodicUpwindOperators.

The combined struct behaves as much as possible as an operator itself as long as no ambiguities arise. For example, upwind operators need to use the same grid and mass matrix, so mass_matrix, grid, xmin, xmax etc. are available but mul! is not.

It is recommended to construct an instance of PeriodicUpwindOperators using upwind_operators. An instance can also be constructed manually by passing the operators in the order D_minus, D_central, D_plus.

See also upwind_operators, UpwindOperators

source
SummationByPartsOperators.QuarticNonconvexPeriodicSemidiscretizationType
QuarticNonconvexPeriodicSemidiscretization(D, Di, split_form)

A semidiscretization of the quartic nonconvex conservation law $\partial_t u(t,x) + \partial_x ( u(t,x)^4 - 10 u(t,x)^2 + 3 u(t,x) ) = 0$ with periodic boundary conditions.

D is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.

source
SummationByPartsOperators.SafeModeType
SafeMode()

A safe execution mode relying only on basic functionality of Julia.

source
SummationByPartsOperators.SharanBradyLivescu2022Type
SharanBradyLivescu2022(alpha_left, alpha_right)

Coefficients of the cut-cell SBP operators given in

  • Sharan, Brady, Livescu (2022) High-order dimensionally-split Cartesian embedded boundary method for non-dissipative schemes. Journal of Computational Physics 464, 111341.

Here, alpha_left * Δx is the spacing between the left endpoint and the second node, while alpha_right * Δx is the spacing between the right endpoint and the last node.

source
SummationByPartsOperators.SourceOfCoefficientsType
SourceOfCoefficients

All sources of coefficients (articles) are subtypes of this abstract type.

source
SummationByPartsOperators.Tadmor1989Type
Tadmor1989()

Coefficients of the Fourier spectral viscosity given in

  • Tadmor (1989) Convergence of Spectral Methods for Nonlinear Conservation Laws. SIAM Journal on Numerical Analysis 26.1, pp. 30-44.
source
SummationByPartsOperators.Tadmor1993Type
Tadmor1993()

Coefficients of the Fourier super spectral viscosity given in

  • Tadmor (1993) Super Viscosity and Spectral Approximations of Nonlinear Conservation Laws. Numerical Methods for Fluid Dynamics IV, pp. 69-82.
source
SummationByPartsOperators.TadmorWaagan2012ConvergentType
TadmorWaagan2012Convergent()

Coefficients of the Fourier spectral viscosity given in

  • Tadmor, Waagan (2012) Adaptive Spectral Viscosity for Hyperbolic Conservation Laws. SIAM Journal on Scientific Computing 34.2, pp. A993-A1009.

See also

  • Schochet (1990) The Rate of Convergence of Spectral-Viscosity Methods for Periodic Scalar Conservation Laws. SIAM Journal on Numerical Analysis 27.5, pp. 1142-1159.
source
SummationByPartsOperators.TadmorWaagan2012StandardType
TadmorWaagan2012Standard()

Coefficients of the Fourier spectral viscosity given in

  • Tadmor, Waagan (2012) Adaptive Spectral Viscosity for Hyperbolic Conservation Laws. SIAM Journal on Scientific Computing 34.2, pp. A993-A1009.
source
SummationByPartsOperators.ThreadedModeType
ThreadedMode()

An execution mode using multiple threads and possibly further optimizations, cf. FastMode.

source
SummationByPartsOperators.UniformMesh1DType
UniformMesh1D(xmin::Real, xmax::Real, Nx::Integer)
+UniformMesh1D(; xmin::Real, xmax::Real, Nx::Integer)

A uniform mesh in one space dimension of Nx cells between xmin and xmax.

source
SummationByPartsOperators.UniformPeriodicMesh1DType
UniformPeriodicMesh1D(xmin::Real, xmax::Real, Nx::Integer)
+UniformPeriodicMesh1D(; xmin::Real, xmax::Real, Nx::Integer)

A uniform periodic mesh in one space dimension of Nx cells between xmin and xmax.

source
SummationByPartsOperators.UpwindOperatorsType
UpwindOperators
+UpwindOperators(D_minus, D_central, D_plus)

A struct bundling the individual operators available for non-periodic upwind SBP operators. The individual operators are available as D.minus, D.plus (and optionally D.central, if provided), where D::UpwindOperators.

The combined struct behaves as much as possible as an operator itself as long as no ambiguities arise. For example, upwind operators need to use the same grid and mass matrix, so mass_matrix, grid, xmin, xmax etc. are available but mul! is not.

It is recommended to construct an instance of UpwindOperators using upwind_operators. An instance can also be constructed manually by passing the operators in the order D_minus, D_central, D_plus.

See also upwind_operators, PeriodicUpwindOperators

source
SummationByPartsOperators.VarCoefDerivativeCoefficientsType
VarCoefDerivativeCoefficients

The coefficients of a variable coefficient derivative operator on a nonperiodic grid.

source
SummationByPartsOperators.VarCoefDerivativeOperatorType
VarCoefDerivativeOperator

A dissipation operator on a nonperiodic finite difference grid.

source
SummationByPartsOperators.VariableLinearAdvectionNonperiodicSemidiscretizationType
VariableLinearAdvectionNonperiodicSemidiscretization(D, Di, a, split_form,
+                                                     left_bc, right_bc)

A semidiscretization of the linear advection equation $\partial_t u(t,x) + \partial_x ( a(x) u(t,x) ) = 0$ with boundary conditions left_bc(t), right_bc(t).

D is an SBP derivative operator, Di an associated dissipation operator or nothing, a(x) the variable coefficient, and split_form::Union{Val(false), Val(true)} determines whether the canonical split form or the conservative form should be used.

source
SummationByPartsOperators.VariableLinearAdvectionPeriodicSemidiscretizationType
VariableLinearAdvectionPeriodicSemidiscretization(D, Di, a, split_form)

A semidiscretization of the linear advection equation $\partial_t u(t,x) + \partial_x ( a(x) u(t,x) ) = 0$ with periodic boundary conditions.

D is a periodic SBP derivative operator, Di an associated dissipation operator or nothing, a(x) the variable coefficient, and split_form::Union{Val(false), Val(true)} determines whether the canonical split form or the conservative form should be used.

source
SummationByPartsOperators.WaveEquationNonperiodicSemidiscretizationType
WaveEquationNonperiodicSemidiscretization(D, left_bc, right_bc)

A semidiscretization of the linear wave equation $\partial_t^2 u(t,x) = \partial_x^2 u(t,x)$.

D is assumed to be a second-derivative SBP operator and the boundary conditions can be Val(:HomogeneousNeumann), Val(:HomogeneousDirichlet), or Val(:NonReflecting).

source
LinearAlgebra.mul!Function
mul!(du, D::DerivativeOperator, u, α=true, β=false)

Efficient in-place version of du = α * D * u + β * du. Note that du must not be aliased with u.

source
PolynomialBases.compute_coefficients!Method
compute_coefficients!(uval, u, D::AbstractDerivativeOperator)

Compute the nodal values of the function u at the grid associated to the derivative operator D and stores the result in uval.

source
PolynomialBases.compute_coefficientsMethod
compute_coefficients(u, D::AbstractDerivativeOperator)

Compute the nodal values of the function u at the grid associated to the derivative operator D.

source
PolynomialBases.evaluate_coefficients!Method
evaluate_coefficients!(xplot, uplot, u, D::AbstractDerivativeOperator)

Evaluates the nodal coefficients u at a grid associated to the derivative operator D and stores the result in xplot, uplot. Returns xplot, uplot, where xplot contains the nodes and uplot the corresponding values of u.

source
PolynomialBases.evaluate_coefficientsMethod
evaluate_coefficients(u, D::AbstractDerivativeOperator)

Evaluates the nodal coefficients u at a grid associated to the derivative operator D. Returns xplot, uplot, where xplot contains the nodes and uplot the corresponding values of u.

source
PolynomialBases.integrateMethod
integrate(func, u, D::DerivativeOperator)

Map the function func to the coefficients u and integrate with respect to the quadrature rule associated with the SBP derivative operator D.

source
PolynomialBases.integrateMethod
integrate(func, u, D::PeriodicDerivativeOperator)

Map the function func to the coefficients u and integrate with respect to the quadrature rule associated with the periodic derivative operator D.

source
PolynomialBases.integrateMethod
integrate(func, u, D::AbstractPeriodicDerivativeOperator)

Map the function func to the coefficients u and integrate with respect to the quadrature rule associated with the derivative operator D.

source
SummationByPartsOperators.accuracy_orderFunction
accuracy_order(D)

Return the order of accuracy of a derivative operator D. For SBP finite difference operators, this refers to the interior order of accuracy.

source
SummationByPartsOperators.couple_continuouslyFunction
couple_continuously(D, mesh)

Return a derivative operator corresponding to a continuous coupling of D on the cells of the given mesh as in (nodal) continuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are CG spectral element methods (CGSEM). However, a continuous coupling of arbitrary SBP operators is supported.

The mesh can be a UniformMesh1D or a UniformPeriodicMesh1D.

References

source
SummationByPartsOperators.couple_discontinuouslyFunction
couple_discontinuously(D, mesh, [coupling=Val(:central)])

Return a derivative operator corresponding to a discontinuous coupling of D on the cells of the given mesh as in (nodal) discontinuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are DG spectral element methods (DGSEM). However, a discontinuous coupling of arbitrary SBP operators is supported.

The mesh can be a UniformMesh1D or a UniformPeriodicMesh1D. The coupling can be

  • Val(:central) (default), resulting in classical SBP properties
  • Val(:minus) or Val(:plus), resulting in upwind SBP operators

References

source
SummationByPartsOperators.derivative_leftMethod
derivative_left(D::AbstractNonperiodicDerivativeOperator, der_order)

Get a representation of the linear functional evaluation the Nth derivative at the left boundary node as (dense) vector.

source
SummationByPartsOperators.derivative_leftMethod
derivative_left(D::DerivativeOperator, u, der_order::Val{N})

Compute the N-th derivative of the function given by the coefficients u at the left boundary of the grid.

source
SummationByPartsOperators.derivative_operatorFunction
derivative_operator(source_of_coefficients,
                     derivative_order, accuracy_order,
                     xmin, xmax, N, mode=FastMode())
 derivative_operator(source_of_coefficients;
                     derivative_order, accuracy_order,
-                    xmin, xmax, N, mode=FastMode())

Create a DerivativeOperator approximating the derivative_order-th derivative on a grid between xmin and xmax with N grid points up to order of accuracy accuracy_order. with coefficients given by source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.derivative_orderFunction
derivative_order(D)

Return the order of the derivative associated to the derivative operator D. For example, it will return 1 for a first-derivative SBP operator.

source
SummationByPartsOperators.derivative_rightMethod
derivative_right(D::AbstractNonperiodicDerivativeOperator, der_order)

Get a representation of the linear functional evaluation the Nth derivative at the right boundary node as (dense) vector.

source
SummationByPartsOperators.derivative_rightMethod
derivative_right(D::DerivativeOperator, u, der_order::Val{N})

Compute the N-th derivative of the function given by the coefficients u at the right boundary of the grid.

source
SummationByPartsOperators.dissipation_operatorFunction
dissipation_operator(source_of_coefficients, order, xmin, xmax, N,
-                     left_weights, right_weights, mode=FastMode())

Create a negative semidefinite DissipationOperator using undivided differences approximating a weighted order-th derivative on a grid between xmin and xmax with N grid points up to order of accuracy 2 with coefficients given by source_of_coefficients. The norm matrix is given by left_weights and right_weights. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.dissipation_operatorMethod
dissipation_operator(D::PeriodicDerivativeOperator;
+                    xmin, xmax, N, mode=FastMode())

Create a DerivativeOperator approximating the derivative_order-th derivative on a grid between xmin and xmax with N grid points up to order of accuracy accuracy_order. with coefficients given by source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.derivative_orderFunction
derivative_order(D)

Return the order of the derivative associated to the derivative operator D. For example, it will return 1 for a first-derivative SBP operator.

source
SummationByPartsOperators.derivative_rightMethod
derivative_right(D::AbstractNonperiodicDerivativeOperator, der_order)

Get a representation of the linear functional evaluation the Nth derivative at the right boundary node as (dense) vector.

source
SummationByPartsOperators.derivative_rightMethod
derivative_right(D::DerivativeOperator, u, der_order::Val{N})

Compute the N-th derivative of the function given by the coefficients u at the right boundary of the grid.

source
SummationByPartsOperators.dissipation_operatorFunction
dissipation_operator(source_of_coefficients, order, xmin, xmax, N,
+                     left_weights, right_weights, mode=FastMode())

Create a negative semidefinite DissipationOperator using undivided differences approximating a weighted order-th derivative on a grid between xmin and xmax with N grid points up to order of accuracy 2 with coefficients given by source_of_coefficients. The norm matrix is given by left_weights and right_weights. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.dissipation_operatorMethod
dissipation_operator(D::PeriodicDerivativeOperator;
                      strength=one(eltype(D)),
                      order=accuracy_order(D),
-                     mode=D.coefficients.mode)

Create a negative semidefinite DissipationOperator using undivided differences approximating a order-th derivative with strength strength adapted to the derivative operator D. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.dissipation_operatorMethod
dissipation_operator([source_of_coefficients=MattssonSvärdNordström2004()],
+                     mode=D.coefficients.mode)

Create a negative semidefinite DissipationOperator using undivided differences approximating a order-th derivative with strength strength adapted to the derivative operator D. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.dissipation_operatorMethod
dissipation_operator([source_of_coefficients=MattssonSvärdNordström2004()],
                      D::DerivativeOperator{T};
                      strength=one(T),
                      order::Int=accuracy_order(D),
-                     mode=D.coefficients.mode)

Create a negative semidefinite DissipationOperator using undivided differences approximating a weighted order-th derivative adapted to the derivative operator D with coefficients given in source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.fornbergMethod
fornberg(x::Vector{T}, m::Int) where {T}

Calculate the weights of a finite difference approximation of the mth derivative with maximal order of accuracy at 0 using the nodes x, see Fornberg (1998) Calculation of Weights in Finite Difference Formulas SIAM Rev. 40.3, pp. 685-691.

source
SummationByPartsOperators.fourier_derivative_matrixFunction
fourier_derivative_matrix(N, xmin::Real=0.0, xmax::Real=2π)

Compute the Fourier derivative matrix with respect to the corresponding nodal basis using N nodes, see Kopriva (2009) Implementing Spectral Methods for PDEs, Algorithm 18.

source
SummationByPartsOperators.fourier_derivative_operatorMethod
fourier_derivative_operator(xmin::Real, xmax::Real, N::Integer)
-fourier_derivative_operator(; xmin::Real, xmax::Real, N::Integer)

Construct the FourierDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N÷2+1 complex Fourier modes.

source
SummationByPartsOperators.gridFunction
grid(D)

Return the grid associated to a derivative operator D.

source
SummationByPartsOperators.left_boundary_weightFunction
left_boundary_weight(D)

Return the left-boundary weight of the (diagonal) mass matrix M associated to the derivative operator D.

source
SummationByPartsOperators.legendre_derivative_operatorMethod
legendre_derivative_operator(xmin::Real, xmax::Real, N::Integer)
-legendre_derivative_operator(; xmin::Real, xmax::Real, N::Integer)

Construct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.

source
SummationByPartsOperators.legendre_second_derivative_operatorMethod
legendre_second_derivative_operator(xmin::Real, xmax::Real, N::Integer)
-legendre_second_derivative_operator(; xmin::Real, xmax::Real, N::Integer)

Construct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.

source
SummationByPartsOperators.mass_matrixMethod
mass_matrix(D::Union{DerivativeOperator,VarCoefDerivativeOperator})

Create the diagonal mass matrix for the SBP derivative operator D.

source
SummationByPartsOperators.mul_transpose_derivative_left!Method
mul_transpose_derivative_left!(u, D::DerivativeOperator, der_order::Val{N}, α=true, β=false)

Set the grid function u to α times the transposed N-th derivative functional applied to u plus β times u in the domain of the N-th derivative functional at the left boundary of the grid. Thus, the coefficients α, β have the same meaning as in mul!.

source
SummationByPartsOperators.mul_transpose_derivative_right!Method
mul_transpose_derivative_right!(u, D::DerivativeOperator, der_order::Val{N}, α=true, β=false)

Set the grid function u to α times the transposed N-th derivative functional applied to u plus β times u in the domain of the N-th derivative functional at the right boundary of the grid. Thus, the coefficients α, β have the same meaning as in mul!.

source
SummationByPartsOperators.periodic_central_derivative_coefficientsFunction
periodic_central_derivative_coefficients(derivative_order, accuracy_order, T=Float64, mode=FastMode())

Create the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).

source
SummationByPartsOperators.periodic_central_derivative_operatorFunction
periodic_central_derivative_operator(derivative_order, accuracy_order,
-                                     xmin, xmax, N, mode=FastMode())

Create a PeriodicDerivativeOperator approximating the derivative_order-th derivative on a uniform grid between xmin and xmax with N grid points up to order of accuracy accuracy_order. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.periodic_derivative_coefficientsFunction
periodic_derivative_coefficients(derivative_order, accuracy_order,
+                     mode=D.coefficients.mode)

Create a negative semidefinite DissipationOperator using undivided differences approximating a weighted order-th derivative adapted to the derivative operator D with coefficients given in source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.fornbergMethod
fornberg(x::Vector{T}, m::Int) where {T}

Calculate the weights of a finite difference approximation of the mth derivative with maximal order of accuracy at 0 using the nodes x, see Fornberg (1998) Calculation of Weights in Finite Difference Formulas SIAM Rev. 40.3, pp. 685-691.

source
SummationByPartsOperators.fourier_derivative_matrixFunction
fourier_derivative_matrix(N, xmin::Real=0.0, xmax::Real=2π)

Compute the Fourier derivative matrix with respect to the corresponding nodal basis using N nodes, see Kopriva (2009) Implementing Spectral Methods for PDEs, Algorithm 18.

source
SummationByPartsOperators.fourier_derivative_operatorMethod
fourier_derivative_operator(xmin::Real, xmax::Real, N::Integer)
+fourier_derivative_operator(; xmin::Real, xmax::Real, N::Integer)

Construct the FourierDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N÷2+1 complex Fourier modes.

source
SummationByPartsOperators.function_space_operatorFunction
function_space_operator(basis_functions, nodes, source;
+                        derivative_order = 1, accuracy_order = 0,
+                        options = Optim.Options(g_tol = 1e-14, iterations = 10000))

Construct an operator that represents a first-derivative operator in a function space spanned by the basis_functions, which is an iterable of functions. The operator is constructed on the interval [x_min, x_max] with the nodes nodes, where x_min is taken as the minimal value in nodes and x_max the maximal value. Note that the nodes will be sorted internally. The accuracy_order is the order of the accuracy of the operator, which can optionally be passed, but does not have any effect on the operator. The operator is constructed solving an optimization problem with Optim.jl. You can specify the options for the optimization problem with the options argument, see also the documentation of Optim.jl.

The operator that is returned follows the general interface. Currently, it is wrapped in a MatrixDerivativeOperator, but this might change in the future. In order to use this function, the package Optim must be loaded.

See also GlaubitzNordströmÖffner2023.

Julia 1.9

This function requires at least Julia 1.9.

Experimental implementation

This is an experimental feature and may change in future releases.

source
SummationByPartsOperators.gridFunction
grid(D)

Return the grid associated to a derivative operator D.

source
SummationByPartsOperators.left_boundary_weightFunction
left_boundary_weight(D)

Return the left-boundary weight of the (diagonal) mass matrix M associated to the derivative operator D.

source
SummationByPartsOperators.legendre_derivative_operatorMethod
legendre_derivative_operator(xmin::Real, xmax::Real, N::Integer)
+legendre_derivative_operator(; xmin::Real, xmax::Real, N::Integer)

Construct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.

source
SummationByPartsOperators.legendre_second_derivative_operatorMethod
legendre_second_derivative_operator(xmin::Real, xmax::Real, N::Integer)
+legendre_second_derivative_operator(; xmin::Real, xmax::Real, N::Integer)

Construct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.

source
SummationByPartsOperators.mass_matrixMethod
mass_matrix(D::Union{DerivativeOperator,VarCoefDerivativeOperator})

Create the diagonal mass matrix for the SBP derivative operator D.

source
SummationByPartsOperators.mul_transpose_derivative_left!Method
mul_transpose_derivative_left!(u, D::DerivativeOperator, der_order::Val{N}, α=true, β=false)

Set the grid function u to α times the transposed N-th derivative functional applied to u plus β times u in the domain of the N-th derivative functional at the left boundary of the grid. Thus, the coefficients α, β have the same meaning as in mul!.

source
SummationByPartsOperators.mul_transpose_derivative_right!Method
mul_transpose_derivative_right!(u, D::DerivativeOperator, der_order::Val{N}, α=true, β=false)

Set the grid function u to α times the transposed N-th derivative functional applied to u plus β times u in the domain of the N-th derivative functional at the right boundary of the grid. Thus, the coefficients α, β have the same meaning as in mul!.

source
SummationByPartsOperators.periodic_central_derivative_coefficientsFunction
periodic_central_derivative_coefficients(derivative_order, accuracy_order, T=Float64, mode=FastMode())

Create the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).

source
SummationByPartsOperators.periodic_central_derivative_operatorFunction
periodic_central_derivative_operator(derivative_order, accuracy_order,
+                                     xmin, xmax, N, mode=FastMode())

Create a PeriodicDerivativeOperator approximating the derivative_order-th derivative on a uniform grid between xmin and xmax with N grid points up to order of accuracy accuracy_order. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.periodic_derivative_coefficientsFunction
periodic_derivative_coefficients(derivative_order, accuracy_order,
                                  left_offset=-(accuracy_order+1)÷2,
-                                 T=Float64, mode=FastMode())

Create the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()`.

source
SummationByPartsOperators.periodic_derivative_coefficientsMethod
periodic_derivative_coefficients(source::Holoborodko2008, derivative_order, accuracy_order;
+                                 T=Float64, mode=FastMode())

Create the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()`.

source
SummationByPartsOperators.periodic_derivative_coefficientsMethod
periodic_derivative_coefficients(source::Holoborodko2008, derivative_order, accuracy_order;
                                  T=Float64, mode=FastMode(),
-                                 stencil_width=accuracy_order+3)

Create the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T given by Holoborodko2008. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()`.

source
SummationByPartsOperators.periodic_derivative_operatorFunction
periodic_derivative_operator(derivative_order, accuracy_order, grid,
-                             left_offset=-(accuracy_order+1)÷2, mode=FastMode())

Create a PeriodicDerivativeOperator approximating the derivative_order-th derivative on the uniform grid up to order of accuracy accuracy_order where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).

source
SummationByPartsOperators.periodic_derivative_operatorFunction
periodic_derivative_operator(derivative_order, accuracy_order,
+                                 stencil_width=accuracy_order+3)

Create the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T given by Holoborodko2008. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()`.

source
SummationByPartsOperators.periodic_derivative_operatorFunction
periodic_derivative_operator(derivative_order, accuracy_order, grid,
+                             left_offset=-(accuracy_order+1)÷2, mode=FastMode())

Create a PeriodicDerivativeOperator approximating the derivative_order-th derivative on the uniform grid up to order of accuracy accuracy_order where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).

source
SummationByPartsOperators.periodic_derivative_operatorFunction
periodic_derivative_operator(derivative_order, accuracy_order,
                              xmin, xmax, N,
                              left_offset=-(accuracy_order+1)÷2,
                              mode=FastMode())
@@ -52,7 +54,7 @@
 Periodic first-derivative operator of order 2 on a grid in [0.0, 1.0] using 11 nodes,
 stencils with 1 nodes to the left, 1 nodes to the right, and coefficients of Fornberg (1998)
   Calculation of Weights in Finite Difference Formulas.
-  SIAM Rev. 40.3, pp. 685-691.
source
SummationByPartsOperators.periodic_derivative_operatorMethod
periodic_derivative_operator(source::Holoborodko2008,
+  SIAM Rev. 40.3, pp. 685-691.
source
SummationByPartsOperators.periodic_derivative_operatorMethod
periodic_derivative_operator(source::Holoborodko2008,
                              derivative_order, accuracy_order,
                              xmin, xmax, N; mode=FastMode(), kwargs...)
 periodic_derivative_operator(source::Holoborodko2008;
@@ -62,7 +64,7 @@
 Periodic first-derivative operator of order 2 on a grid in [0.0, 1.0] using 11 nodes,
 stencils with 2 nodes to the left, 2 nodes to the right, and coefficients of   Holoborodko (2008)
   Smooth Noise Robust Differentiators.
-  http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
source
SummationByPartsOperators.right_boundary_weightFunction
right_boundary_weight(D)

Return the left-boundary weight of the (diagonal) mass matrix M associated to the derivative operator D.

source
SummationByPartsOperators.semidiscretizeMethod
semidiscretize(u0func, semi::AbstractSemidiscretization, tspan)

Apply the semidiscretization semi to the initial data given by u0func and return an ODEProblem with time span tspan.

source
SummationByPartsOperators.source_of_coefficientsMethod
source_of_coefficients(D)

Return the source of coefficients of the derivative operator D. If you use the operator D for your research, please cite this source in addition to SummationByPartsOperators.

source
SummationByPartsOperators.upwind_operatorsMethod
upwind_operators(source_type, args...; derivative_order = 1, kwargs...)

Create UpwindOperators from the given source type. The positional arguments args... and keyword arguments kwargs... are passed directly to derivative_operator.

Examples

julia> D = upwind_operators(Mattsson2017, accuracy_order = 2,
+  http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
source
SummationByPartsOperators.right_boundary_weightFunction
right_boundary_weight(D)

Return the left-boundary weight of the (diagonal) mass matrix M associated to the derivative operator D.

source
SummationByPartsOperators.semidiscretizeMethod
semidiscretize(u0func, semi::AbstractSemidiscretization, tspan)

Apply the semidiscretization semi to the initial data given by u0func and return an ODEProblem with time span tspan.

source
SummationByPartsOperators.source_of_coefficientsMethod
source_of_coefficients(D)

Return the source of coefficients of the derivative operator D. If you use the operator D for your research, please cite this source in addition to SummationByPartsOperators.

source
SummationByPartsOperators.upwind_operatorsMethod
upwind_operators(source_type, args...; derivative_order = 1, kwargs...)

Create UpwindOperators from the given source type. The positional arguments args... and keyword arguments kwargs... are passed directly to derivative_operator.

Examples

julia> D = upwind_operators(Mattsson2017, accuracy_order = 2,
                             xmin = 0//1, xmax = 9//1, N = 10)
 Upwind SBP first-derivative operators of order 2 on a grid in [0//1, 9//1] using 10 nodes
 and coefficients of Mattsson2017
@@ -92,7 +94,7 @@
   0//1   0//1   0//1   0//1   1//4  -1//1   0//1   1//1  -1//4   0//1
   0//1   0//1   0//1   0//1   0//1   1//4  -1//1   0//1   1//1  -1//4
   0//1   0//1   0//1   0//1   0//1   0//1   1//5  -4//5   0//1   3//5
-  0//1   0//1   0//1   0//1   0//1   0//1   0//1   1//1  -3//1   2//1
source
SummationByPartsOperators.upwind_operatorsMethod
upwind_operators(periodic_derivative_operator;
+  0//1   0//1   0//1   0//1   0//1   0//1   0//1   1//1  -3//1   2//1
source
SummationByPartsOperators.upwind_operatorsMethod
upwind_operators(periodic_derivative_operator;
                  derivative_order = 1, accuracy_order,
                  xmin, xmax, N,
                  mode = FastMode()))

Create PeriodicUpwindOperators from operators constructed by periodic_derivative_operator. The keyword arguments are passed directly to periodic_derivative_operator.

Examples

julia> D = upwind_operators(periodic_derivative_operator, accuracy_order = 2,
@@ -121,6 +123,6 @@
   0//1   0//1   1//4  -1//1   0//1   1//1  -1//4   0//1
   0//1   0//1   0//1   1//4  -1//1   0//1   1//1  -1//4
  -1//4   0//1   0//1   0//1   1//4  -1//1   0//1   1//1
-  1//1  -1//4   0//1   0//1   0//1   1//4  -1//1   0//1
source
SummationByPartsOperators.var_coef_derivative_operatorFunction
var_coef_derivative_operator(source_of_coefficients, derivative_order, accuracy_order,
+  1//1  -1//4   0//1   0//1   0//1   1//4  -1//1   0//1
source
SummationByPartsOperators.var_coef_derivative_operatorFunction
var_coef_derivative_operator(source_of_coefficients, derivative_order, accuracy_order,
                              xmin, xmax, N, left_weights, right_weights, bfunc,
-                             mode=FastMode())

Create a VarCoefDerivativeOperator approximating a derivative_order-th derivative with variable coefficients bfunc on a grid between xmin and xmax with N grid points up to order of accuracy accuracy_order with coefficients given by source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.xmaxFunction
xmax(D)

Return the right boundary xmax of the domain specified when constructing the derivative operator D. Note that this might be different from the rightmost node of the grid of D when not all boundary nodes are included, e.g., for periodic derivative operators.

source
SummationByPartsOperators.xminFunction
xmin(D)

Return the left boundary xmin of the domain specified when constructing the derivative operator D. Note that this might be different from the leftmost node of the grid of D when not all boundary nodes are included, e.g., for periodic derivative operators.

source
+ mode=FastMode())

Create a VarCoefDerivativeOperator approximating a derivative_order-th derivative with variable coefficients bfunc on a grid between xmin and xmax with N grid points up to order of accuracy accuracy_order with coefficients given by source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().

source
SummationByPartsOperators.xmaxFunction
xmax(D)

Return the right boundary xmax of the domain specified when constructing the derivative operator D. Note that this might be different from the rightmost node of the grid of D when not all boundary nodes are included, e.g., for periodic derivative operators.

source
SummationByPartsOperators.xminFunction
xmin(D)

Return the left boundary xmin of the domain specified when constructing the derivative operator D. Note that this might be different from the leftmost node of the grid of D when not all boundary nodes are included, e.g., for periodic derivative operators.

source
diff --git a/dev/applications/index.html b/dev/applications/index.html index fd68855c..5c2c3681 100644 --- a/dev/applications/index.html +++ b/dev/applications/index.html @@ -1,2 +1,2 @@ -Applications & references · SummationByPartsOperators.jl

Applications

Here is a (non-exhaustive) list of research using SummationByPartsOperators.jl.

  • Jesse Chan, Hendrik Ranocha, Andrés M. Rueda-Ramírez, Gregor Gassner, Tim Warburton (2022). On the Entropy Projection and the Robustness of High Order Entropy Stable Discontinuous Galerkin Schemes for Under-Resolved Flows. arXiv: 2203.10238 [math.NA] DOI: 10.3389/fphy.2022.898028 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.6364108
  • Hendrik Ranocha, Manuel Quezada de Luna, and David I Ketcheson (2021). On the Rate of Error Growth in Time for Numerical Solutions of Nonlinear Dispersive Wave Equations. arXiv: 2102.07376 [math.NA] DOI: 10.1007/s42985-021-00126-3 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.4540467
  • Hendrik Ranocha, Dimitrios Mitsotakis, and David I Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3908803
  • Philippe G LeFloch and Hendrik Ranocha (2021). Kinetic functions for nonclassical shocks, entropy stability, and discrete summation by parts. DOI: 10.1007/s10915-021-01463-6
  • Jan Nordström and Hendrik Ranocha (2021). A New Class of A Stable Summation by Parts Time Integration Schemes with Strong Initial Conditions. DOI: 10.1007/s10915-021-01454-7 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3699173
  • Hendrik Ranocha (2021). On Strong Stability of Explicit Runge-Kutta Methods for Nonlinear Semibounded Operators. DOI: 10.1093/imanum/drz070
  • Hendrik Ranocha and David I Ketcheson (2020). Energy Stability of Explicit Runge-Kutta Methods for Nonautonomous or Nonlinear Problems. DOI: 10.1137/19M1290346 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3464243
  • Hendrik Ranocha, Katharina Ostaszewski, and Philip Heinisch (2020). Discrete Vector Calculus and Helmholtz Hodge Decomposition for Classical Finite Difference Summation by Parts Operators. DOI: 10.1007/s42967-019-00057-2 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3375170
  • Hendrik Ranocha and Gregor J Gassner (2020). Preventing pressure oscillations does not fix local linear stability issues of entropy-based split-form high-order schemes. arXiv: 2009.13139 [math.NA] A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.4054366
  • Philipp Öffner and Hendrik Ranocha (2019). Error Boundedness of Discontinuous Galerkin Methods with Variable Coefficients. DOI: 10.1007/s10915-018-00902-1

If you use this package for your own research, please cite it as described in the documentation and make a PR to add your work to the list above.

+Applications & references · SummationByPartsOperators.jl

Applications

Here is a (non-exhaustive) list of research using SummationByPartsOperators.jl.

  • Jesse Chan, Hendrik Ranocha, Andrés M. Rueda-Ramírez, Gregor Gassner, Tim Warburton (2022). On the Entropy Projection and the Robustness of High Order Entropy Stable Discontinuous Galerkin Schemes for Under-Resolved Flows. arXiv: 2203.10238 [math.NA] DOI: 10.3389/fphy.2022.898028 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.6364108
  • Hendrik Ranocha, Manuel Quezada de Luna, and David I Ketcheson (2021). On the Rate of Error Growth in Time for Numerical Solutions of Nonlinear Dispersive Wave Equations. arXiv: 2102.07376 [math.NA] DOI: 10.1007/s42985-021-00126-3 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.4540467
  • Hendrik Ranocha, Dimitrios Mitsotakis, and David I Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3908803
  • Philippe G LeFloch and Hendrik Ranocha (2021). Kinetic functions for nonclassical shocks, entropy stability, and discrete summation by parts. DOI: 10.1007/s10915-021-01463-6
  • Jan Nordström and Hendrik Ranocha (2021). A New Class of A Stable Summation by Parts Time Integration Schemes with Strong Initial Conditions. DOI: 10.1007/s10915-021-01454-7 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3699173
  • Hendrik Ranocha (2021). On Strong Stability of Explicit Runge-Kutta Methods for Nonlinear Semibounded Operators. DOI: 10.1093/imanum/drz070
  • Hendrik Ranocha and David I Ketcheson (2020). Energy Stability of Explicit Runge-Kutta Methods for Nonautonomous or Nonlinear Problems. DOI: 10.1137/19M1290346 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3464243
  • Hendrik Ranocha, Katharina Ostaszewski, and Philip Heinisch (2020). Discrete Vector Calculus and Helmholtz Hodge Decomposition for Classical Finite Difference Summation by Parts Operators. DOI: 10.1007/s42967-019-00057-2 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3375170
  • Hendrik Ranocha and Gregor J Gassner (2020). Preventing pressure oscillations does not fix local linear stability issues of entropy-based split-form high-order schemes. arXiv: 2009.13139 [math.NA] A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.4054366
  • Philipp Öffner and Hendrik Ranocha (2019). Error Boundedness of Discontinuous Galerkin Methods with Variable Coefficients. DOI: 10.1007/s10915-018-00902-1

If you use this package for your own research, please cite it as described in the documentation and make a PR to add your work to the list above.

diff --git a/dev/benchmarks/index.html b/dev/benchmarks/index.html index 5f35827e..91080563 100644 --- a/dev/benchmarks/index.html +++ b/dev/benchmarks/index.html @@ -26,23 +26,23 @@ println() end
doit (generic function with 1 method)

First, we benchmark the implementation from SummationByPartsOperators.jl.

doit(D_SBP, "D_SBP:", du, u)
D_SBP:
 BenchmarkTools.Trial: 10000 samples with 995 evaluations.
- Range (minmax):  28.274 ns58.925 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     29.059 ns               GC (median):    0.00%
- Time  (mean ± σ):   29.607 ns ±  2.212 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  29.089 ns58.703 ns   GC (min … max): 0.00% … 0.00%
+ Time  (median):     29.775 ns               GC (median):    0.00%
+ Time  (mean ± σ):   29.901 ns ±  1.093 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  ▂▆██▇▆▄▃▁                                                 ▃
-  ██████████▇▆▆▆▅▄▅▄▁▁▃▁▁▁▁▃▃▁▁▃▁▁▁▄▆▇████████████▆▇█▇▇████ █
-  28.3 ns      Histogram: log(frequency) by time      39.5 ns <
+      ▁▄▄▄▇▇████▆▅▄▃▃▁▁                                     
+  ▂▃▅▇██████████████████▆▆▅▄▃▃▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▂▁▂▂▂▂▂▂▁▂▂ ▄
+  29.1 ns         Histogram: frequency by time        32.1 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

Next, we compare this to the runtime obtained using a sparse matrix representation of the derivative operator. Depending on the hardware etc., this can be an order of magnitude slower than the optimized implementation from SummationByPartsOperators.jl.

doit(D_sparse, "D_sparse:", du, u)
D_sparse:
-BenchmarkTools.Trial: 10000 samples with 606 evaluations.
- Range (minmax):  198.771 ns454.281 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     200.871 ns                GC (median):    0.00%
- Time  (mean ± σ):   203.593 ns ±  17.099 ns   GC (mean ± σ):  0.00% ± 0.00%
+BenchmarkTools.Trial: 10000 samples with 656 evaluations.
+ Range (minmax):  187.959 ns388.363 ns   GC (min … max): 0.00% … 0.00%
+ Time  (median):     194.541 ns                GC (median):    0.00%
+ Time  (mean ± σ):   196.902 ns ±  14.960 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  ▂▇█▆▅▄▃▂▁▁        ▁                                         ▂
-  ████████████▇▇▇▆▇███▇▇▇▆▆▆▆▅▅▅▄▅▄▄▄▄▄▄▃▃▃▄▄▂▅▄▄▂▄▄▄▄▄▄▄▄▃▃▂ █
-  199 ns        Histogram: log(frequency) by time        241 ns <
+      ▂▇██                                                   
+  ▁▁▃▆████▆▄▃▂▂▂▁▁▁▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▂
+  188 ns           Histogram: frequency by time          240 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

Finally, we benchmark the implementation of the same derivative operator in DiffEqOperators.jl.

doit(D_DEO, "D_DEO:", du, u)
D_DEO:
 ┌ Warning: #= /home/runner/.julia/packages/DiffEqOperators/lHq9u/src/derivative_operators/convolutions.jl:412 =#:
@@ -53,14 +53,14 @@
 `LoopVectorization.check_args` on your inputs failed; running fallback `@inbounds @fastmath` loop instead.
 Use `warn_check_args=false`, e.g. `@turbo warn_check_args=false ...`, to disable this warning.
 @ DiffEqOperators ~/.julia/packages/LoopVectorization/QgYWB/src/condense_loopset.jl:1166
-BenchmarkTools.Trial: 10000 samples with 104 evaluations.
- Range (minmax):  780.692 ns79.178 μs   GC (min … max): 0.00% … 98.13%
- Time  (median):     799.856 ns               GC (median):    0.00%
- Time  (mean ± σ):   855.191 ns ±  1.830 μs   GC (mean ± σ):  5.20% ±  2.41%
+BenchmarkTools.Trial: 10000 samples with 102 evaluations.
+ Range (minmax):  782.735 ns79.749 μs   GC (min … max): 0.00% … 98.31%
+ Time  (median):     800.804 ns               GC (median):    0.00%
+ Time  (mean ± σ):   854.872 ns ±  1.714 μs   GC (mean ± σ):  4.45% ±  2.20%
 
-     ▁▄██                                 
-  ▁▂▄██████▅▃▃▂▂▂▂▁▁▁▁▁▁▂▂▂▂▂▂▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▂
-  781 ns          Histogram: frequency by time          940 ns <
+   ▄▇██▆▅▄▃▃▃▂▁▂▁▁▂▃▂▂▁▁▁                     ▁              ▂
+  ▆███████████████████████████▇████▆▇▇▆▇▇████████▇▆▆▆▆▆▄▅▃▄▅ █
+  783 ns        Histogram: log(frequency) by time       990 ns <
 
  Memory estimate: 416 bytes, allocs estimate: 6.

These results were obtained using the following versions.

using InteractiveUtils
 versioninfo()
@@ -103,33 +103,33 @@
   println()
 end
doit (generic function with 1 method)

First, we benchmark the implementation from SummationByPartsOperators.jl.

doit(D_SBP, "D_SBP:", du, u)
D_SBP:
 BenchmarkTools.Trial: 10000 samples with 203 evaluations.
- Range (minmax):  381.256 ns524.724 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     386.384 ns                GC (median):    0.00%
- Time  (mean ± σ):   387.657 ns ±   8.129 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  382.143 ns587.552 ns   GC (min … max): 0.00% … 0.00%
+ Time  (median):     386.586 ns                GC (median):    0.00%
+ Time  (mean ± σ):   388.468 ns ±  10.913 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-      ▂▆█                                                     
-  ▂▂▃▅███▇▅▃▃▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▁▁▁▁▁▁▁▁▁▂▂▂▂▂▂▂▁▁▁▂▁▁▁▂▂▂▂▂▂▂▂▂▂ ▃
-  381 ns           Histogram: frequency by time          427 ns <
+   ▄▆██▄▃▁                                                   ▂
+  █████████▆▆▇▆█▅▇▆▄▅▁▁▃▄▁▄▁▁▁▄▄▅▅▆▆▆▅▆▄▄▅▇█▇█▇▆▃▅▆▅▄▄▅▄▃▃▃▄ █
+  382 ns        Histogram: log(frequency) by time        439 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

Again, we compare this to a representation of the derivative operator as a sparse matrix. No surprise - it is again much slower, as in periodic domains.

doit(D_sparse, "D_sparse:", du, u)
D_sparse:
 BenchmarkTools.Trial: 10000 samples with 7 evaluations.
- Range (minmax):  4.531 μs 11.791 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     4.621 μs                GC (median):    0.00%
- Time  (mean ± σ):   4.652 μs ± 281.179 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  4.460 μs 11.619 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     4.487 μs                GC (median):    0.00%
+ Time  (mean ± σ):   4.509 μs ± 190.759 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-   ▄▇█▂ ▁                                                   ▂
-  ████████▆▃▁▃▄▅▅▅▄▅▄▁▄▁▄▃▄▁▄▁▁▁▁▁▁▃▁▁▁▃▁▁▁▁▁▁▁▁▃▅▅▆▆▆▅▅▃▄▅ █
-  4.53 μs      Histogram: log(frequency) by time      5.91 μs <
+  ▆                                                         ▁
+  █▄▄▅█▇▃▁▄▁▃▃▅▆▅▄▅▄▃▁▃▁▃▃▃▁▁▁▁▁▃▁▃▁▁▁▁▃▁▁▁▁▃▁▃▁▁▃▁▁▄▃▄▅▅▅▆ █
+  4.46 μs      Histogram: log(frequency) by time      5.66 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

FInally, we compare it to a representation as banded matrix. Disappointingly, this is still much slower than the optimized implementation from SummationByPartsOperators.jl.

doit(D_banded, "D_banded:", du, u)
D_banded:
 BenchmarkTools.Trial: 10000 samples with 5 evaluations.
- Range (minmax):  6.636 μs 12.295 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     6.654 μs                GC (median):    0.00%
- Time  (mean ± σ):   6.677 μs ± 252.214 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  6.640 μs 12.580 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     6.656 μs                GC (median):    0.00%
+ Time  (mean ± σ):   6.686 μs ± 298.370 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  █       ▁                                                  ▁
-  █▃▁▃▁▁██▁▁▁▁▁▁▁▁▃▁▁▁▃▅▅▄▅▄▃▄▃▁▁▁▁▄▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▁▁▃▁▁▆ █
-  6.64 μs      Histogram: log(frequency) by time      7.71 μs <
+  █                                                           ▁
+  █▄▃▇█▃▁▁▁▁▁▄▅▅▄▄▄▄▄▁▃▁▁▁▃▁▃▃▁▃▁▃▃▁▁▄▃▁▃▁▃▁▁▁▁▁▁▁▁▁▁▁▃▄▄▅▅ █
+  6.64 μs      Histogram: log(frequency) by time       8.3 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

These results were obtained using the following versions.

using InteractiveUtils
 versioninfo()
@@ -175,56 +175,56 @@
 end
doit (generic function with 1 method)

At first, let us benchmark the derivative and dissipation operators implemented in SummationByPartsOperators.jl.

doit(D_SBP, "D_SBP:", du, u)
 doit(Di_SBP, "Di_SBP:", du, u)
D_SBP:
 BenchmarkTools.Trial: 10000 samples with 203 evaluations.
- Range (minmax):  382.044 ns545.158 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     386.685 ns                GC (median):    0.00%
- Time  (mean ± σ):   388.093 ns ±   7.842 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  386.483 ns625.207 ns   GC (min … max): 0.00% … 0.00%
+ Time  (median):     390.734 ns                GC (median):    0.00%
+ Time  (mean ± σ):   392.099 ns ±   8.936 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-      ▃█                                                      
-  ▂▂▃▇██▅▄▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▁▁▂▂▁▁▂▂▁▂▂▁▁▁▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
-  382 ns           Histogram: frequency by time          427 ns <
+     ▃▇                                                       
+  ▂▃▆██▅▄▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▁▂▂▁▁▁▁▂▁▂▂▁▁▁▁▂▁▁▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
+  386 ns           Histogram: frequency by time          435 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 Di_SBP:
 BenchmarkTools.Trial: 10000 samples with 10 evaluations.
- Range (minmax):  1.012 μs 2.845 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     1.020 μs               GC (median):    0.00%
- Time  (mean ± σ):   1.024 μs ± 51.916 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  1.016 μs 3.007 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     1.026 μs               GC (median):    0.00%
+ Time  (mean ± σ):   1.034 μs ± 74.660 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-       ▂▆█                                               
-  ▂▂▃▄▇█████▆▅▅▅▄▄▃▃▂▂▂▂▁▁▂▁▁▁▂▁▁▁▁▁▁▁▁▂▁▁▁▁▁▁▂▁▂▁▂▁▁▁▁▂▂▂ ▃
-  1.01 μs        Histogram: frequency by time        1.07 μs <
+  ▇                                                        ▁
+  █▇▁▁▁▁▁▃▄▇▄▃▁▁▁▁▁▁▁▁▁▁▁▃▃▄▃▅▄▁▄▃▄▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▇ █
+  1.02 μs      Histogram: log(frequency) by time     1.46 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

Next, we compare the results to sparse matrix representations. It will not come as a surprise that these are again much (around an order of magnitude) slower.

doit(Di_sparse, "Di_sparse:", du, u)
 doit(Di_banded, "Di_banded:", du, u)
Di_sparse:
 BenchmarkTools.Trial: 10000 samples with 6 evaluations.
- Range (minmax):  5.148 μs 10.847 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     5.178 μs                GC (median):    0.00%
- Time  (mean ± σ):   5.205 μs ± 249.007 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  5.317 μs 12.291 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     5.375 μs                GC (median):    0.00%
+ Time  (mean ± σ):   5.414 μs ± 327.372 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  ▆                                                         ▁
-  █▄▄█▇▅▁▁▁▁▃▅▄▆▄▅▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▁▃▁▁▁▁▁▁▁▅▅▆ █
-  5.15 μs      Histogram: log(frequency) by time      6.49 μs <
+  ▂▇                                                       ▂
+  ██▁▇█▆▄▁▁▄▁▄▆▅▅▅▄▄▆▆▁▁▃▄▁▃▃▁▁▁▁▃▁▁▁▁▃▁▁▃▃▁▁▁▁▄▃▁▁▄▅▅▆▆▆▆ █
+  5.32 μs      Histogram: log(frequency) by time      6.78 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 Di_banded:
 BenchmarkTools.Trial: 10000 samples with 5 evaluations.
- Range (minmax):  6.174 μs 15.992 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     6.823 μs                GC (median):    0.00%
- Time  (mean ± σ):   6.594 μs ± 402.332 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  6.186 μs 13.405 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     6.216 μs                GC (median):    0.00%
+ Time  (mean ± σ):   6.416 μs ± 407.010 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  ▇     ▁                       ▁                            ▁
-  ██▁▁▃▁█▄▁▃▁▃▄▁▁▃▅▅▄▃▁▁▁█▇▁▄▃▄█▃▁▁▁▁▁▁▄▃▄▆▆▃▁▁▁▁▁▃▁▃▁▁▃▁▄▄ █
-  6.17 μs      Histogram: log(frequency) by time       7.7 μs <
+  █                                                          
+  █▂▂▂▁▂▂▁▂▂▂▂▂▂▂▂▂▂▂▂▂█▅▂▁▂▂▂▂▁▁▁▁▁▂▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▂▂▂▂▂▂▂ ▂
+  6.19 μs         Histogram: frequency by time        7.83 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

Finally, let's benchmark the same computation if a full (dense) matrix is used to represent the derivative operator. This is obviously a bad idea but 🤷

doit(Di_full, "Di_full:", du, u)
Di_full:
 BenchmarkTools.Trial: 10000 samples with 1 evaluation.
- Range (minmax):  138.568 μs344.865 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     141.044 μs                GC (median):    0.00%
- Time  (mean ± σ):   142.198 μs ±   5.084 μs   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  138.278 μs387.955 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     140.593 μs                GC (median):    0.00%
+ Time  (mean ± σ):   142.203 μs ±   7.599 μs   GC (mean ± σ):  0.00% ± 0.00%
 
-   ▁▄▆▇█▇▅▃▃▃▂▂▁                 ▁ ▁                          ▂
-  ▆████████████████▇▆▆▆▅▅▆▆▆▇▇▇██████████▇▇█▆▆▆▇▆▅▅▅▄▅▅▁▄▅▃▄▅ █
-  139 μs        Histogram: log(frequency) by time        164 μs <
+   ▂▅▇█▆▅▄▂▂▁▁            ▁  ▁▁                               ▂
+  ▆████████████▇▇▇▆▆▆▆▆▆▆▇████████▆▇▆▆▆▅▅▄▅▆▄▅▄▅▄▅▄▅▅▄▄▄▄▅▂▃▅ █
+  138 μs        Histogram: log(frequency) by time        166 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

These results were obtained using the following versions.

using InteractiveUtils
 versioninfo()
@@ -301,35 +301,35 @@
 show(stdout, MIME"text/plain"(), @benchmark mul!($du, $D_full, $u))
Scalar case
 D_SBP
 BenchmarkTools.Trial: 10000 samples with 989 evaluations.
- Range (minmax):  45.454 ns77.689 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     46.304 ns               GC (median):    0.00%
- Time  (mean ± σ):   46.908 ns ±  2.693 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  44.685 ns90.746 ns   GC (min … max): 0.00% … 0.00%
+ Time  (median):     46.467 ns               GC (median):    0.00%
+ Time  (mean ± σ):   46.735 ns ±  2.336 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  ▅██▅▃▂                                                   ▂
-  ███████▇▆▄▅▃▅▃▄▁▃▃▄▃▃▁▄▃▁▃██▇▇▇▆▆▆▅▅▅▇▇▇▇▇▇█▇█▇▆▇▇▆▅▆▇▇▆ █
-  45.5 ns      Histogram: log(frequency) by time      61.1 ns <
+        ▁▃▂██▂                                              
+  ▂▂▁▁▂▅██████▇▅▄▃▃▂▂▂▂▂▂▂▂▁▂▂▂▂▂▂▁▂▁▂▁▂▁▁▁▁▁▂▁▂▁▁▂▂▂▂▂▂▂▂▂ ▃
+  44.7 ns         Histogram: frequency by time        54.6 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 D_sparse
-BenchmarkTools.Trial: 10000 samples with 217 evaluations.
- Range (minmax):  341.747 ns853.212 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     347.378 ns                GC (median):    0.00%
- Time  (mean ± σ):   353.804 ns ±  42.602 ns   GC (mean ± σ):  0.00% ± 0.00%
+BenchmarkTools.Trial: 10000 samples with 231 evaluations.
+ Range (minmax):  319.472 ns509.654 ns   GC (min … max): 0.00% … 0.00%
+ Time  (median):     329.229 ns                GC (median):    0.00%
+ Time  (mean ± σ):   331.516 ns ±  10.141 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  █    ▁                                                      ▂
-  ██▅▄▅██▆▆▅▄▃▃▁▃▅▄▄▅▆▄▁▃▁▆▄▁▁▁▁▃▁▁▁▁▃▁▃▁▁▁▃▃▃▃▁▃▁▃▁▃▁▁▁▄▇▅▅▆ █
-  342 ns        Histogram: log(frequency) by time        664 ns <
+         ▄▇█▆▃▁                                                
+  ▂▂▂▂▃▄███████▆▆▅▄▄▃▃▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
+  319 ns           Histogram: frequency by time          374 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 D_full
 BenchmarkTools.Trial: 10000 samples with 10 evaluations.
- Range (minmax):  1.712 μs  7.417 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     1.722 μs                GC (median):    0.00%
- Time  (mean ± σ):   1.738 μs ± 129.336 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  1.710 μs 4.440 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     1.723 μs               GC (median):    0.00%
+ Time  (mean ± σ):   1.734 μs ± 96.922 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  █                                                         ▂
-  █▄▄▃▄▄█▆▃▁▄▁▃▃▄▁▄▁▁▁▅▃▄▃▃▄▄▁▃▄▁▄▁▁▃▄▁▄▃▃▄▁▁▄▁▁▄█▇▅▃▃▄▄▁▅ █
-  1.71 μs      Histogram: log(frequency) by time      2.26 μs <
+  █                                                        ▂
+  █▅▅▁▁▇▇▃▁▁▁▁▃▁▃▃▄▄▄▃▄▃▄▁▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▁▁▁▁▃▁▃▁▁▁▃▁▁▆ █
+  1.71 μs      Histogram: log(frequency) by time     2.38 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

Next, we use a plain array of structures (AoS) in the form of a two-dimensional array and our custom mul_aos! implementation that loops over each component, using mul! on views. Here, the differences between the timings are less pronounced.

println("Plain Array of Structures")
 u_aos_plain = randn(T, 5, size(D_SBP, 1)); du_aos_plain = similar(u_aos_plain)
@@ -341,35 +341,35 @@
 show(stdout, MIME"text/plain"(), @benchmark mul_aos!($du_aos_plain, $D_full, $u_aos_plain))
Plain Array of Structures
 D_SBP
 BenchmarkTools.Trial: 10000 samples with 10 evaluations.
- Range (minmax):  1.296 μs 4.011 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     1.305 μs               GC (median):    0.00%
- Time  (mean ± σ):   1.311 μs ± 66.000 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  1.302 μs 3.781 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     1.313 μs               GC (median):    0.00%
+ Time  (mean ± σ):   1.318 μs ± 67.032 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-     ▁▅█                                                    
-  ▂▃▄███▇▅▆▄▃▂▂▂▂▁▁▂▂▁▁▁▁▁▁▁▁▁▁▁▂▁▁▂▂▁▁▂▂▂▁▁▂▁▂▁▁▁▂▁▁▂▂▂▂▂ ▃
-  1.3 μs         Histogram: frequency by time        1.38 μs <
+                   ▁    ▇ █ ▇ ▄  ▃                           
+  ▂▁▂▁▂▁▂▁▂▁▃▂▁▄▁▆▁█▁█▇▁█▁█▁██▁▁█▁█▁▇▁▁▄▅▁▆▁▅▁▄▁▂▃▁▃▁▃▁▂▁▂ ▃
+  1.3 μs         Histogram: frequency by time        1.33 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 D_sparse
 BenchmarkTools.Trial: 10000 samples with 9 evaluations.
- Range (minmax):  2.437 μs  5.010 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     2.500 μs                GC (median):    0.00%
- Time  (mean ± σ):   2.524 μs ± 162.166 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  2.347 μs  7.195 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     2.408 μs                GC (median):    0.00%
+ Time  (mean ± σ):   2.421 μs ± 133.190 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-    ▇                                                        
-  ▂▆█▃▂▂▂▂▂▁▂▂▂▂▂▂▂▂▂▁▂▂▂▁▁▂▂▂▁▂▁▁▁▂▁▂▁▁▁▂▂▂▂▂▂▂▂▂▂▁▂▂▂▂▂▂▂ ▂
-  2.44 μs         Histogram: frequency by time        3.63 μs <
+    ▁█                                                      
+  ▂▄██▄▃▂▂▂▂▂▁▁▁▂▂▂▂▂▂▂▂▂▁▁▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁▁▁▁▁▂▁▂ ▂
+  2.35 μs         Histogram: frequency by time        3.24 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 D_full
 BenchmarkTools.Trial: 10000 samples with 3 evaluations.
- Range (minmax):  8.930 μs 18.030 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     8.973 μs                GC (median):    0.00%
- Time  (mean ± σ):   9.012 μs ± 355.360 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  8.960 μs 23.865 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     9.027 μs                GC (median):    0.00%
+ Time  (mean ± σ):   9.088 μs ± 576.999 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  ▅█       ▁                                                ▂
-  ██▇▄▁▄▁▁▄██▅▄▁▁▁▁▁▁▁▃▁▁▁▄▅▅▅▄▅▄▁▃▁▃▁▁▁▁▁▁▁▁▃▁▃▁▁▁▁▁▁▁▁▁▁▆ █
-  8.93 μs      Histogram: log(frequency) by time      10.4 μs <
+  ▅                                                         ▁
+  █▅▅██▁▃▁▄▁▄▄▇▆▄▅▄▁▃▁▁▁▃▁▃▁▁▁▁▁▁▁▁▁▃▁▁▃▁▁▁▁▄▁▁▁▁▃▃▄▃▁▁▃▁▄ █
+  8.96 μs      Histogram: log(frequency) by time      11.7 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

Now, we use an array of structures (AoS) based on reinterpret and standard mul!. This is much more efficient for the implementation in SummationByPartsOperators.jl. In Julia v1.6, this is also more efficient for sparse matrices but less efficient for dense matrices (compared to the plain AoS approach with mul_aos! above).

println("Array of Structures (reinterpreted array)")
 u_aos_r = reinterpret(reshape, Vec5{T}, u_aos_plain); du_aos_r = similar(u_aos_r)
@@ -385,36 +385,36 @@
 D_SBP * u_aos_r ≈ D_sparse * u_aos_r ≈ D_full * u_aos_r = true
 reinterpret(reshape, T, du_aos_r) ≈ du_aos_plain = true
 D_SBP
-BenchmarkTools.Trial: 10000 samples with 425 evaluations.
- Range (minmax):  235.452 ns323.379 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     238.186 ns                GC (median):    0.00%
- Time  (mean ± σ):   239.563 ns ±   6.685 ns   GC (mean ± σ):  0.00% ± 0.00%
+BenchmarkTools.Trial: 10000 samples with 550 evaluations.
+ Range (minmax):  215.875 ns297.284 ns   GC (min … max): 0.00% … 0.00%
+ Time  (median):     219.920 ns                GC (median):    0.00%
+ Time  (mean ± σ):   221.268 ns ±   5.970 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-    ▅█▁                    ▁                                 ▂
-  ▅▇███▇██▇▆▄▁▄▁▃▄▁▃▃▁▁▄▃▆███▇▇▅▆▅▅▅▅▁▄▃▄▁▄▁▄▅▄▅▃▃▄▄▆▆▅▆▅▆▆▆ █
-  235 ns        Histogram: log(frequency) by time        279 ns <
+     ▃▇█                                                      
+  ▂▃▆███▇▆▅▄▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
+  216 ns           Histogram: frequency by time          256 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 D_sparse
-BenchmarkTools.Trial: 10000 samples with 169 evaluations.
- Range (minmax):  625.669 ns973.473 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     638.769 ns                GC (median):    0.00%
- Time  (mean ± σ):   643.378 ns ±  27.051 ns   GC (mean ± σ):  0.00% ± 0.00%
+BenchmarkTools.Trial: 10000 samples with 181 evaluations.
+ Range (minmax):  576.934 ns 1.108 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     592.878 ns               GC (median):    0.00%
+ Time  (mean ± σ):   595.460 ns ± 14.708 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-   ▂▆█▃▁         ▁▁                                           ▂
-  ▆██████▆▅▁▃▃▃▄█████▇▆▄▄▄▅▄▄▅▄▆▅▆▄▄▁▅▃▃▁▁▄▃▃▁▁▄▃▁▁▁▃▄▄▅▄▅▄▅▅ █
-  626 ns        Histogram: log(frequency) by time        825 ns <
+            ▃▇█                                             
+  ▂▁▁▁▂▂▂▃▄▇███▇▅▄▃▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
+  577 ns          Histogram: frequency by time          650 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 D_full
 BenchmarkTools.Trial: 10000 samples with 4 evaluations.
- Range (minmax):  7.239 μs 16.288 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     7.289 μs                GC (median):    0.00%
- Time  (mean ± σ):   7.332 μs ± 429.413 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  7.194 μs 15.827 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     7.266 μs                GC (median):    0.00%
+ Time  (mean ± σ):   7.315 μs ± 459.315 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-                                                             
-  ▄▁▁▂▂▁▁▁▁▁▁▂▂▂▂▂▂▂▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▂▂ ▂
-  7.24 μs         Histogram: frequency by time        9.26 μs <
+   ▇                                                         
+  ▃█▂▂▂▂▂▁▁▁▁▁▂▂▂▂▂▂▂▂▂▁▁▁▁▁▁▁▁▁▂▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▂▂▂ ▂
+  7.19 μs         Histogram: frequency by time        9.31 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

Next, we still use an array of structures (AoS), but copy the data into a plain Array instead of using the reinterpreted versions. There is no significant difference to the previous version in this case.

println("Array of Structures")
 u_aos = Array(u_aos_r); du_aos = similar(u_aos)
@@ -431,35 +431,35 @@
 du_aos ≈ du_aos_r = true
 D_SBP
 BenchmarkTools.Trial: 10000 samples with 555 evaluations.
- Range (minmax):  206.602 ns262.220 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     211.405 ns                GC (median):    0.00%
- Time  (mean ± σ):   212.023 ns ±   3.655 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  219.058 ns337.027 ns   GC (min … max): 0.00% … 0.00%
+ Time  (median):     222.036 ns                GC (median):    0.00%
+ Time  (mean ± σ):   223.246 ns ±   5.911 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-           ▁▄▇                                               
-  ▂▂▂▂▂▃▃▄▆███▇▅▄▃▃▂▂▂▂▂▂▂▂▂▂▂▁▂▂▁▂▂▂▁▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
-  207 ns           Histogram: frequency by time          230 ns <
+    ▃▇█▃▁▁▁              ▁▁                                   ▂
+  ▅████████▇▆▅▄▃▃▁▃▃▃▄▄▆███▇▆▆▆▆▅▆▇▆▆▅▅▅▄▃▃▄▁▄▁▃▃▄▃▃▃▄▅▆▆▅▅▆▄ █
+  219 ns        Histogram: log(frequency) by time        259 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 D_sparse
-BenchmarkTools.Trial: 10000 samples with 175 evaluations.
- Range (minmax):  606.046 ns 2.098 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     615.497 ns               GC (median):    0.00%
- Time  (mean ± σ):   626.848 ns ± 55.957 ns   GC (mean ± σ):  0.00% ± 0.00%
+BenchmarkTools.Trial: 10000 samples with 179 evaluations.
+ Range (minmax):  585.670 ns 1.026 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     602.302 ns               GC (median):    0.00%
+ Time  (mean ± σ):   605.180 ns ± 17.116 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-  ▂█▅▂       ▁                                                ▁
-  ████▆▅▃▄▃▇██▇▇▇▆▆▅▅▅▄▄▅▅▄▄▅▅▆▆▆▆▇▇▇▆▅▅▅▃▄▄▄▃▆▅▅▄▄▄▅▅▅▅▃▅▄▅ █
-  606 ns        Histogram: log(frequency) by time       859 ns <
+           ▁▅█▇                                             
+  ▁▁▁▁▁▁▂▃▅████▆▄▃▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▂
+  586 ns          Histogram: frequency by time          664 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 D_full
 BenchmarkTools.Trial: 10000 samples with 4 evaluations.
- Range (minmax):  7.399 μs 17.838 μs   GC (min … max): 0.00% … 0.00%
- Time  (median):     7.449 μs                GC (median):    0.00%
- Time  (mean ± σ):   7.480 μs ± 271.982 ns   GC (mean ± σ):  0.00% ± 0.00%
+ Range (minmax):  7.261 μs 23.323 μs   GC (min … max): 0.00% … 0.00%
+ Time  (median):     7.359 μs                GC (median):    0.00%
+ Time  (mean ± σ):   7.462 μs ± 910.966 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-                                                             
-  ▅▂▂▂▂▂▂▁▁▂▁▁▂▂▂▂▂▂▂▂▂▂▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁▂▁▂▁▁▂▁▁▁▂▁▁▂▂ ▂
-  7.4 μs          Histogram: frequency by time        9.39 μs <
+  ▅█                                                        ▂
+  ████▅▁▁▃▄▆▆▅▁▄▁▁▁▇▄▁▁▃▃▁▁▁▁▁▁▁▁▃▃▃▁▁▃▅█▆▅▆▅▄▄▃▁▃▁▄▁▁▃▃▃▃ █
+  7.26 μs      Histogram: log(frequency) by time      10.3 μs <
 
  Memory estimate: 0 bytes, allocs estimate: 0.

Finally, let's look at a structure of arrays (SoA). Interestingly, this is slower than the array of structures we used above. On Julia v1.6, the sparse matrix representation performs particularly bad in this case.

println("Structure of Arrays")
 u_soa = StructArray(u_aos); du_soa = similar(u_soa)
@@ -475,36 +475,36 @@
 D_SBP * u_soa ≈ D_sparse * u_soa ≈ D_full * u_soa = true
 du_soa ≈ du_aos = true
 D_SBP
-BenchmarkTools.Trial: 10000 samples with 487 evaluations.
- Range (minmax):  221.400 ns303.339 ns   GC (min … max): 0.00% … 0.00%
- Time  (median):     223.579 ns                GC (median):    0.00%
- Time  (mean ± σ):   224.314 ns ±   4.200 ns   GC (mean ± σ):  0.00% ± 0.00%
+BenchmarkTools.Trial: 10000 samples with 496 evaluations.
+ Range (minmax):  220.454 ns321.550 ns   GC (min … max): 0.00% … 0.00%
+ Time  (median):     222.756 ns                GC (median):    0.00%
+ Time  (mean ± σ):   223.452 ns ±   3.952 ns   GC (mean ± σ):  0.00% ± 0.00%
 
-     ▂▆█                                                      
-  ▂▃▆███▆▄▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▁▂▁▁▂▁▂▁▁▁▁▁▂▂▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
-  221 ns           Histogram: frequency by time          244 ns <
+      ▄▇█                                                     
+  ▂▃▄▇███▅▄▃▂▂▂▂▂▂▂▂▂▂▂▁▂▂▁▂▁▁▁▁▁▁▁▁▂▂▂▂▁▁▂▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
+  220 ns           Histogram: frequency by time          242 ns <
 
  Memory estimate: 0 bytes, allocs estimate: 0.
 D_sparse
 BenchmarkTools.Trial: 10000 samples with 1 evaluation.
- Range (minmax):  209.722 μs  7.615 ms   GC (min … max):  0.00% … 94.70%
- Time  (median):     219.139 μs                GC (median):     0.00%
- Time  (mean ± σ):   272.139 μs ± 464.138 μs   GC (mean ± σ):  10.85% ±  6.17%
+ Range (minmax):  214.611 μs  8.062 ms   GC (min … max):  0.00% … 94.53%
+ Time  (median):     221.744 μs                GC (median):     0.00%
+ Time  (mean ± σ):   276.692 μs ± 468.255 μs   GC (mean ± σ):  10.79% ±  6.18%
 
-  ▁▃▄▅▃▃▃▂▁▁                                       ▄▄▃▁▁       ▁
-  ███████████▇▇▇▇▇▇▆▇▆▅▆▅▃▄▄▅▃▃▄▃▄▄▃▁▁▁▁▄▃▁▃▁▄▃▃▃▇██████▇▇▆▅▆ █
-  210 μs        Histogram: log(frequency) by time        376 μs <
+  ▃█▅▃▄▃▂▁                                   ▃▅▄▂▁▂▁   ▁▁    ▁ ▂
+  ███████████▇▇▆▆▇▇▆▅▆▅▆▅▄▄▁▅▄▄▄▃▄▁▃▃▃▁▃▁▃▃▄████████▆▇██▇▅▆▇█ █
+  215 μs        Histogram: log(frequency) by time        394 μs <
 
  Memory estimate: 328.25 KiB, allocs estimate: 10504.
 D_full
 BenchmarkTools.Trial: 10000 samples with 1 evaluation.
- Range (minmax):  173.244 μs  7.617 ms   GC (min … max):  0.00% … 94.91%
- Time  (median):     181.720 μs                GC (median):     0.00%
- Time  (mean ± σ):   232.624 μs ± 461.592 μs   GC (mean ± σ):  12.68% ±  6.22%
+ Range (minmax):  171.952 μs  8.305 ms   GC (min … max):  0.00% … 90.62%
+ Time  (median):     179.825 μs                GC (median):     0.00%
+ Time  (mean ± σ):   233.001 μs ± 470.412 μs   GC (mean ± σ):  12.86% ±  6.21%
 
-  ▃▅█▄▃▃▃▂▁                                          ▁▄▅▄▂▁▁▁  ▂
-  ███████████▇▇▇▆▅▆▃▄▅▄▄▄▄▁▄▄▄▃▃▃▁▁▃▁▄▁▁▄▄▄▃▁▁▃▃▄▆▄▆█████████ █
-  173 μs        Histogram: log(frequency) by time        325 μs <
+  ▄▆█▄▃▃▃▂▁                                     ▄▅▄▁▂▁   ▁▁    ▂
+  ███████████▇▆▆▅▆▆▆▅▅▄▄▄▁▅▃▄▁▃▄▄▁▄▃▁▁▁▄▁▄▄▄▃▄▇████████▇███▇▆ █
+  172 μs        Histogram: log(frequency) by time        338 μs <
 
  Memory estimate: 328.25 KiB, allocs estimate: 10504.

These results were obtained using the following versions.

using InteractiveUtils
 versioninfo()
@@ -524,4 +524,4 @@
       Status `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl/docs/Manifest.toml`
   [90137ffa] StaticArrays v1.9.5
   [09ab397b] StructArrays v0.6.18
-  [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl`
+ [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` diff --git a/dev/code_of_conduct/index.html b/dev/code_of_conduct/index.html index 6ff4d646..cbbbd1be 100644 --- a/dev/code_of_conduct/index.html +++ b/dev/code_of_conduct/index.html @@ -1,2 +1,2 @@ -Code of conduct · SummationByPartsOperators.jl

Code of Conduct

Contributor Covenant Code of Conduct

Our Pledge

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

Our Standards

Examples of behavior that contributes to a positive environment for our community include:

  • Demonstrating empathy and kindness toward other people
  • Being respectful of differing opinions, viewpoints, and experiences
  • Giving and gracefully accepting constructive feedback
  • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
  • Focusing on what is best not just for us as individuals, but for the overall community

Examples of unacceptable behavior include:

  • The use of sexualized language or imagery, and sexual attention or advances of any kind
  • Trolling, insulting or derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others' private information, such as a physical or email address, without their explicit permission
  • Other conduct which could reasonably be considered inappropriate in a professional setting

Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

Scope

This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to Hendrik Ranocha. All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the reporter of any incident.

Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

1. Correction

Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

2. Warning

Community Impact: A violation through a single incident or series of actions.

Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

3. Temporary Ban

Community Impact: A serious violation of community standards, including sustained inappropriate behavior.

Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

4. Permanent Ban

Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

Consequence: A permanent ban from any sort of public interaction within the community.

Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/codeofconduct.html.

Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

+Code of conduct · SummationByPartsOperators.jl

Code of Conduct

Contributor Covenant Code of Conduct

Our Pledge

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.

Our Standards

Examples of behavior that contributes to a positive environment for our community include:

  • Demonstrating empathy and kindness toward other people
  • Being respectful of differing opinions, viewpoints, and experiences
  • Giving and gracefully accepting constructive feedback
  • Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
  • Focusing on what is best not just for us as individuals, but for the overall community

Examples of unacceptable behavior include:

  • The use of sexualized language or imagery, and sexual attention or advances of any kind
  • Trolling, insulting or derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others' private information, such as a physical or email address, without their explicit permission
  • Other conduct which could reasonably be considered inappropriate in a professional setting

Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.

Scope

This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.

Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to Hendrik Ranocha. All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the reporter of any incident.

Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:

1. Correction

Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.

Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.

2. Warning

Community Impact: A violation through a single incident or series of actions.

Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.

3. Temporary Ban

Community Impact: A serious violation of community standards, including sustained inappropriate behavior.

Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.

4. Permanent Ban

Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.

Consequence: A permanent ban from any sort of public interaction within the community.

Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/codeofconduct.html.

Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.

diff --git a/dev/contributing/index.html b/dev/contributing/index.html index eb2fb303..ee922776 100644 --- a/dev/contributing/index.html +++ b/dev/contributing/index.html @@ -35,4 +35,4 @@ are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. + this project or the open source license(s) involved. diff --git a/dev/index.html b/dev/index.html index 77b5dc52..d01fe69f 100644 --- a/dev/index.html +++ b/dev/index.html @@ -46,4 +46,4 @@ pages={3454}, publisher={The Open Journal}, url={https://github.com/ranocha/SummationByPartsOperators.jl} -}

Please also cite the appropriate references for specific SBP operators you use, which can be obtained via source_of_coefficients.

License and contributing

This project is licensed under the MIT license (see License). Since it is an open-source project, we are very happy to accept contributions from the community. Please refer to the section Contributing for more details.

+}

Please also cite the appropriate references for specific SBP operators you use, which can be obtained via source_of_coefficients.

License and contributing

This project is licensed under the MIT license (see License). Since it is an open-source project, we are very happy to accept contributions from the community. Please refer to the section Contributing for more details.

diff --git a/dev/introduction/index.html b/dev/introduction/index.html index 6f40cd2d..335870ff 100644 --- a/dev/introduction/index.html +++ b/dev/introduction/index.html @@ -44,18 +44,18 @@ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 1//8 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 1//8 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ 1//16
julia> M * Matrix(D) + Matrix(D)' * M == tR * tR' - tL * tL'true
julia> u = randn(size(grid(D))); derivative_left(D, u, Val(0)) == u[begin]true
julia> u = randn(size(grid(D))); derivative_right(D, u, Val(0)) == u[end]true

Here, we have introduced some additional features. Firstly, exact rational coefficients are provided, based on the type of xmin and xmax (if available). Secondly, a source_of_coefficients has to be provided when constructing the SBP operator. You can list them using

using InteractiveUtils, SummationByPartsOperators
-subtypes(SourceOfCoefficients)
20-element Vector{Any}:
+subtypes(SourceOfCoefficients)
21-element Vector{Any}:
  BeljaddLeFlochMishraParés2017
  DienerDorbandSchnetterTiglio2007
  Fornberg1998
+ GlaubitzNordströmÖffner2023
  Holoborodko2008
  MadayTadmor1989
  Mattsson2012
  Mattsson2014
  Mattsson2017
  MattssonAlmquistCarpenter2014Extended
- MattssonAlmquistCarpenter2014Optimal
- MattssonAlmquistVanDerWeide2018Accurate
+ ⋮
  MattssonAlmquistVanDerWeide2018Minimal
  MattssonNordström2004
  MattssonSvärdNordström2004
@@ -254,4 +254,4 @@
   0.0    0.0    0.0   3.0  -12.0    9.0   0.0    0.0    0.0
   0.0    0.0    0.0   0.0    0.0  -18.0   9.0   12.0   -3.0
   0.0    0.0    0.0   0.0    0.0    0.0  -3.0    0.0    3.0
-  0.0    0.0    0.0   0.0    0.0    0.0   3.0  -12.0    9.0

Basic interfaces and additional features

To actually compute and plot the discrete grid functions, a few additional ingredients are necessary.

Next steps

If you are familiar with SBP operators in general, this introduction might already be enough for you to apply SummationByPartsOperators.jl to your problems. Otherwise, you might want to have a look at the references, the tutorials coming next, or some ready-to-use semidiscretizations of the following partial differential equations (PDEs). These are shipped with this package and you are encouraged to look at their source code to learn more about it.

Some additional examples are included as Jupyter notebooks in the directory notebooks. Even more examples and research articles making use of SummationByPartsOperators.jl are listed in the section Applications. If you want to know even more, you can have a look at the test.

References

+ 0.0 0.0 0.0 0.0 0.0 0.0 3.0 -12.0 9.0

Basic interfaces and additional features

To actually compute and plot the discrete grid functions, a few additional ingredients are necessary.

Next steps

If you are familiar with SBP operators in general, this introduction might already be enough for you to apply SummationByPartsOperators.jl to your problems. Otherwise, you might want to have a look at the references, the tutorials coming next, or some ready-to-use semidiscretizations of the following partial differential equations (PDEs). These are shipped with this package and you are encouraged to look at their source code to learn more about it.

Some additional examples are included as Jupyter notebooks in the directory notebooks. Even more examples and research articles making use of SummationByPartsOperators.jl are listed in the section Applications. If you want to know even more, you can have a look at the test.

References

diff --git a/dev/license/index.html b/dev/license/index.html index 3093f12d..14eb8e57 100644 --- a/dev/license/index.html +++ b/dev/license/index.html @@ -1,2 +1,2 @@ -License · SummationByPartsOperators.jl

License

MIT License

Copyright (c) 2017-present Hendrik Ranocha <mail@ranocha.de>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+License · SummationByPartsOperators.jl

License

MIT License

Copyright (c) 2017-present Hendrik Ranocha <mail@ranocha.de>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

diff --git a/dev/objects.inv b/dev/objects.inv index 47e778c5..e1519614 100644 Binary files a/dev/objects.inv and b/dev/objects.inv differ diff --git a/dev/search_index.js b/dev/search_index.js index f2c89083..0e596429 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"tutorials/variable_linear_advection/#Linear-advection-equation-with-variable-coefficients","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"","category":"section"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"This tutorial is concerned with the linear advection equation","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"beginaligned\n partial_t u(tx) + partial_x (a(x) u(tx)) = 0 t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \n textboundary conditions x in partial (x_min x_max)\nendaligned","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"with variable coefficient a.","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"The boundary conditions depend on the sign of the transport velocity a at the boundary. In particular, specifying a Dirichlet type boundary condition is only allowed for inflow boundaries, e.g. a(x_min) 0 at x = x_min.","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"SummationByPartsOperators.jl includes a pre-built semidiscretization of this equation: VariableLinearAdvectionNonperiodicSemidiscretization. Have a look at the source code if you want to dig deeper. Below is an example demonstrating how to use this semidiscretization.","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig\n\n# general parameters\nxmin = -1.\nxmax = +1.\ntspan = (0., 8.0)\nafunc(x) = one(x)\nu0func(x) = sinpi(x)\n# Dirichlet type boundary conditions; they are used only at inflow boundaries\nleft_bc(t) = t >= 3 ? sinpi(t) : zero(t)\nright_bc(t) = zero(t)\n\n# discretization parameters\ninterior_order = 4\nN = 101\n# whether a split form should be applied or not\nsplit_form = Val(false)\n\n# setup spatial semidiscretization\nD = derivative_operator(MattssonSvärdShoeybi2008(), 1, interior_order, xmin, xmax, N)\n# whether or not artificial dissipation should be applied: nothing, dissipation_operator(D)\nDi = nothing\nsemi = VariableLinearAdvectionNonperiodicSemidiscretization(D, Di, afunc, split_form, left_bc, right_bc)\node = semidiscretize(u0func, semi, tspan)\n\n# solve ODE\nsol = solve(ode, SSPRK104(), dt=D.Δx, adaptive=false,\n save_everystep=false)\n\n# visualise the result\nplot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], semi), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], semi), label=L\"u_\\mathrm{numerical}\")\nsavefig(\"example_linear_advection.png\");","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"(Image: )","category":"page"},{"location":"tutorials/variable_linear_advection/#Package-versions","page":"Linear advection equation with variable coefficients","title":"Package versions","text":"","category":"section"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"applications/#Applications","page":"Applications & references","title":"Applications","text":"","category":"section"},{"location":"applications/","page":"Applications & references","title":"Applications & references","text":"Here is a (non-exhaustive) list of research using SummationByPartsOperators.jl.","category":"page"},{"location":"applications/","page":"Applications & references","title":"Applications & references","text":"Jesse Chan, Hendrik Ranocha, Andrés M. Rueda-Ramírez, Gregor Gassner, Tim Warburton (2022). On the Entropy Projection and the Robustness of High Order Entropy Stable Discontinuous Galerkin Schemes for Under-Resolved Flows. arXiv: 2203.10238 [math.NA] DOI: 10.3389/fphy.2022.898028 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.6364108\nHendrik Ranocha, Manuel Quezada de Luna, and David I Ketcheson (2021). On the Rate of Error Growth in Time for Numerical Solutions of Nonlinear Dispersive Wave Equations. arXiv: 2102.07376 [math.NA] DOI: 10.1007/s42985-021-00126-3 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.4540467\nHendrik Ranocha, Dimitrios Mitsotakis, and David I Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3908803\nPhilippe G LeFloch and Hendrik Ranocha (2021). Kinetic functions for nonclassical shocks, entropy stability, and discrete summation by parts. DOI: 10.1007/s10915-021-01463-6\nJan Nordström and Hendrik Ranocha (2021). A New Class of A Stable Summation by Parts Time Integration Schemes with Strong Initial Conditions. DOI: 10.1007/s10915-021-01454-7 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3699173\nHendrik Ranocha (2021). On Strong Stability of Explicit Runge-Kutta Methods for Nonlinear Semibounded Operators. DOI: 10.1093/imanum/drz070\nHendrik Ranocha and David I Ketcheson (2020). Energy Stability of Explicit Runge-Kutta Methods for Nonautonomous or Nonlinear Problems. DOI: 10.1137/19M1290346 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3464243\nHendrik Ranocha, Katharina Ostaszewski, and Philip Heinisch (2020). Discrete Vector Calculus and Helmholtz Hodge Decomposition for Classical Finite Difference Summation by Parts Operators. DOI: 10.1007/s42967-019-00057-2 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3375170\nHendrik Ranocha and Gregor J Gassner (2020). Preventing pressure oscillations does not fix local linear stability issues of entropy-based split-form high-order schemes. arXiv: 2009.13139 [math.NA] A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.4054366\nPhilipp Öffner and Hendrik Ranocha (2019). Error Boundedness of Discontinuous Galerkin Methods with Variable Coefficients. DOI: 10.1007/s10915-018-00902-1","category":"page"},{"location":"applications/","page":"Applications & references","title":"Applications & references","text":"If you use this package for your own research, please cite it as described in the documentation and make a PR to add your work to the list above.","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"EditURL = \"https://github.com/ranocha/SummationByPartsOperators.jl/blob/main/CONTRIBUTING.md\"","category":"page"},{"location":"contributing/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"ContributingSummationByPartsOperators.jl is an open-source project and we are very happy to accept contributions from the community. Please feel free to open issues or submit patches (preferably as pull requests) any time. For planned larger contributions, it is often beneficial to get in contact first, for example via issues.SummationByPartsOperators.jl and its contributions are licensed under the MIT license (see License). As a contributor, you certify that all your contributions are in conformance with the Developer Certificate of Origin (Version 1.1), which is reproduced below.Developer Certificate of Origin (Version 1.1)The following text was taken from https://developercertificate.org:Developer Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n1 Letterman Drive\nSuite D4700\nSan Francisco, CA, 94129\n\nEveryone is permitted to copy and distribute verbatim copies of this\nlicense document, but changing it is not allowed.\n\n\nDeveloper's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n have the right to submit it under the open source license\n indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n of my knowledge, is covered under an appropriate open source\n license and I have the right under that license to submit that\n work with modifications, whether created in whole or in part\n by me, under the same open source license (unless I am\n permitted to submit under a different license), as indicated\n in the file; or\n\n(c) The contribution was provided directly to me by some other\n person who certified (a), (b) or (c) and I have not modified\n it.\n\n(d) I understand and agree that this project and the contribution\n are public and that a record of the contribution (including all\n personal information I submit with it, including my sign-off) is\n maintained indefinitely and may be redistributed consistent with\n this project or the open source license(s) involved.","category":"page"},{"location":"tutorials/kdv/#Korteweg-de-Vries-equation","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"","category":"section"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Let's consider the Korteweg-de Vries (KdV) equation","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"beginaligned\n partial_t u(tx) + partial_x fracu(tx)^22 + partial_x^3 u(tx) = 0 t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \nendaligned","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"with periodic boundary conditions. The KdV equation has the quadratic invariant","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":" J = frac12 int u(tx)^2 mathrmdx","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"A classical trick to conserve this invariant is to use following split form","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":" u_t + frac13 (u^2)_x + frac13 u u_x + partial_x^3 u = 0","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Indeed, integration by parts with periodic boundary conditions yields","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"beginaligned\n partial_t J\n =\n int u u_t\n =\n -frac13 int u (u^2)_x - frac13 int u^2 u_x - int u partial_x^3 u\n \n =\n 0 + frac13 int u_x u^2 - frac13 int u^2 u_x + 0\n =\n 0\nendaligned","category":"page"},{"location":"tutorials/kdv/#Basic-example-using-finite-difference-SBP-operators","page":"Korteweg-de Vries equation","title":"Basic example using finite difference SBP operators","text":"","category":"section"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Let's create an appropriate discretization of this equation step by step. At first, we load packages that we will use in this example.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Next, we specify the initial data as Julia function as well as the spatial domain and the time span. Here, we use an analytic soliton solution of the KdV equation for the initial data.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"# traveling wave solution (soliton)\nget_xmin() = 0.0 # left boundary of the domain\nget_xmax() = 80.0 # right boundary of the domain\nget_c() = 2 / 3 # wave speed\nfunction usol(t, x)\n xmin = get_xmin()\n xmax = get_xmax()\n μ = (xmax - xmin) / 2\n c = get_c()\n A = 3 * c\n K = sqrt(1/c - 1)\n x_t = mod(x - c*t - xmin, xmax - xmin) + xmin - μ\n\n A / cosh(sqrt(3*A) / 6 * x_t)^2\nend\n\ntspan = (0.0, (get_xmax() - get_xmin()) / (3 * get_c()) + 10 * (get_xmax() - get_xmin()) / get_c())","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Next, we implement the semidiscretization using the interface of OrdinaryDiffEq.jl which is part of DifferentialEquations.jl. For simplicity, we just use the out-of-place version here since we do not have to worry about appropriate temporary buffers when using automatic differentiation in implicit time integration methods.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"function kdv(u, parameters, t)\n D1 = parameters.D1\n D3 = parameters.D3\n\n # conservative semidiscretization using a split form\n return (-1 / 3) * (u .* (D1 * u) + D1 * (u.^2)) - D3 * u\nend","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Next, we choose first- and third-derivative SBP operators D1, D3, evaluate the initial data on the grid, and set up the semidiscretization as an ODE problem.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"N = 128 # number of grid points\nD1 = periodic_derivative_operator(derivative_order=1, accuracy_order=8,\n xmin=get_xmin(), xmax=get_xmax(), N=N)\nD3 = periodic_derivative_operator(derivative_order=3, accuracy_order=8,\n xmin=get_xmin(), xmax=get_xmax(), N=N)\nu0 = usol.(first(tspan), grid(D1))\nparameters = (; D1, D3)\n\node = ODEProblem(kdv, u0, tspan, parameters);","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Finally, we can solve the ODE using a Rosenbrock method with adaptive time stepping. We use such a linearly implicit time integration method since the third-order derivative makes the system stiff.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"sol = solve(ode, Rodas5(), saveat=range(first(tspan), stop=last(tspan), length=200))\n\nplot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], D1), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], D1), label=L\"u_\\mathrm{numerical}\")\nsavefig(\"example_kdv.png\");","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"(Image: )","category":"page"},{"location":"tutorials/kdv/#Advanced-visualization","page":"Korteweg-de Vries equation","title":"Advanced visualization","text":"","category":"section"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Let's create an animation of the numerical solution.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"using Printf; using Plots: Animation, frame, gif\n\nlet anim = Animation()\n idx = 1\n x, u = evaluate_coefficients(sol[idx], D1)\n fig = plot(x, u, xguide=L\"x\", yguide=L\"u\", xlim=extrema(x), ylim=(-0.05, 2.05),\n label=\"\", title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n for idx in 1:length(sol.t)\n fig[1] = x, sol.u[idx]\n plot!(title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n frame(anim)\n end\n gif(anim, \"example_kdv.gif\")\nend","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"(Image: example_kdv_animation)","category":"page"},{"location":"tutorials/kdv/#Package-versions","page":"Korteweg-de Vries equation","title":"Package versions","text":"","category":"section"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"tutorials/constant_linear_advection/#Linear-advection-equation-with-constant-coefficients","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"This tutorial is concerned with the basic linear advection equation","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"beginaligned\n partial_t u(tx) + partial_x u(tx) = 0 t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \n u(tx_min) = u_L(t)\nendaligned","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Note that the advection velocity is positive (unity). Thus, a boundary condition needs to be specified exactly at the left boundary. Otherwise, the problem will not be well-posed (under-specified or over-specified).","category":"page"},{"location":"tutorials/constant_linear_advection/#Basic-example-using-finite-difference-SBP-operators","page":"Linear advection equation with constant coefficients","title":"Basic example using finite difference SBP operators","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Let's create an appropriate discretization of this equation step by step. At first, we load packages that we will use in this example.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Next, we specify the initial and boundary data as Julia functions as well as the spatial domain and the time span.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"xmin, xmax = -1.0, 1.0\nu0_func(x) = sinpi(x)\nuL_func(t) = t >= 3 ? sinpi(t) : zero(t)\ntspan = (0., 8.0)","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"This choice of the domain and boundary condition ensures that the initial profile is transported out of the domain before non-homogeneous boundary data influences the solution.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Next, we implement the semidiscretization using the interface of OrdinaryDiffEq.jl which is part of DifferentialEquations.jl.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"function rhs!(du, u, params, t)\n D = params.D\n\n # Set `du = - D * u` using in-place multiplication avoiding allocations\n # for efficiency\n mul!(du, D, u, -one(eltype(D)))\n\n # Next, we impose the boundary conditions weakly using an SAT at the left\n # boundary. Since we use the strong form of the equation, we do not need to\n # do anything at the right boundary.\n # Assuming that boundary nodes are included in the grid, adding this SAT\n # can be achieved by\n du[begin] += (uL_func(t) - u[begin]) / left_boundary_weight(D)\n\n return nothing\nend","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Here, we have used a simultaneous approximation term (SAT) to impose the boundary condition weakly. In general, this approach is related to the weak imposition of boundary conditions using numerical fluxes in finite volume and discontinuous Galerkin methods; they are even equivalent for the linear advection equation considered here.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Next, we choose an SBP operator D, evaluate the initial data on the grid, and set up the semidiscretization as an ODE problem.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"D = derivative_operator(MattssonNordström2004(), derivative_order=1, accuracy_order=4,\n xmin=xmin, xmax=xmax, N=101)\nu0 = compute_coefficients(u0_func, D)\nparams = (D=D, )\node = ODEProblem(rhs!, u0, tspan, params);","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Finally, we can solve the ODE using an explicit Runge-Kutta method with adaptive time stepping.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"sol = solve(ode, Tsit5(), saveat=range(first(tspan), stop=last(tspan), length=200));\n\nplot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], D), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], D), label=L\"u_\\mathrm{numerical}\")\nsavefig(\"example_linear_advection.png\");","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"(Image: )","category":"page"},{"location":"tutorials/constant_linear_advection/#Advanced-visualization","page":"Linear advection equation with constant coefficients","title":"Advanced visualization","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Let's create an animation of the numerical solution.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"using Printf; using Plots: Animation, frame, gif\n\nlet anim = Animation()\n idx = 1\n x, u = evaluate_coefficients(sol[idx], D)\n fig = plot(x, u, xguide=L\"x\", yguide=L\"u\", xlim=extrema(x), ylim=(-1.05, 1.05),\n label=\"\", title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n for idx in 1:length(sol.t)\n fig[1] = x, sol.u[idx]\n plot!(title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n frame(anim)\n end\n gif(anim, \"example_linear_advection.gif\")\nend","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"(Image: example_linear_advection_animation)","category":"page"},{"location":"tutorials/constant_linear_advection/#Continuous-and-discontinuous-Galerkin-methods","page":"Linear advection equation with constant coefficients","title":"Continuous and discontinuous Galerkin methods","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"You can use a CG or DG method by swapping out the derivative operator D.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"plot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], D), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], D), label=L\"u_\\mathrm{FD}\")\n\n# CGSEM using polynomials of degree 3, i.e. 4 nodes per element, and 30 elements\nD_CGSEM = couple_continuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=4),\n UniformMesh1D(xmin=xmin, xmax=xmax, Nx=30))\node_CGSEM = ODEProblem(rhs!, compute_coefficients(u0_func, D_CGSEM), tspan, (D=D_CGSEM,))\nsol_CGSEM = solve(ode_CGSEM, Tsit5(), save_everystep=false)\nplot!(evaluate_coefficients(sol_CGSEM[end], D_CGSEM), label=L\"u_\\mathrm{CG}\")\n\n# DGSEM using polynomials of degree 3, i.e. 4 nodes per element, and 30 elements\n# which are coupled using upwind fluxes\nD_DGSEM = couple_discontinuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=4),\n UniformMesh1D(xmin=xmin, xmax=xmax, Nx=30),\n Val(:minus))\node_DGSEM = ODEProblem(rhs!, compute_coefficients(u0_func, D_DGSEM), tspan, (D=D_DGSEM,))\nsol_DGSEM = solve(ode_DGSEM, Tsit5(), save_everystep=false)\nplot!(evaluate_coefficients(sol_DGSEM[end], D_DGSEM), label=L\"u_\\mathrm{DG}\")\n\nsavefig(\"example_linear_advection_Galerkin.png\");","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"(Image: )","category":"page"},{"location":"tutorials/constant_linear_advection/#Package-versions","page":"Linear advection equation with constant coefficients","title":"Package versions","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"tutorials/advection_diffusion/#Linear-advection-diffusion-equation-with-periodic-boundary-conditions","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"","category":"section"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Let's consider the linear advection diffusion equation","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"beginaligned\n partial_t u(tx) + a partial_x u(tx) = varepsilon partial_x^2 u(tx) t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \nendaligned","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"with periodic boundary conditions. Here, a is the constant advection velocity and ε > 0 is the constant diffusion coefficient.","category":"page"},{"location":"tutorials/advection_diffusion/#Basic-example-using-finite-difference-SBP-operators","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Basic example using finite difference SBP operators","text":"","category":"section"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Let's create an appropriate discretization of this equation step by step. At first, we load packages that we will use in this example.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Next, we specify the initial data as Julia function as well as the spatial domain and the time span.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"xmin, xmax = -1.0, 1.0\nu0_func(x) = sinpi(x)\ntspan = (0., 10.0)","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Next, we implement the semidiscretization using the interface of OrdinaryDiffEq.jl which is part of DifferentialEquations.jl.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"function advection_diffusion!(du, u, params, t)\n # In-place version of du = -a * D1 * u\n mul!(du, params.D1, u, -params.a)\n # In-place version of du = du + ε * D2 * u\n mul!(du, params.D2, u, params.ε, true)\nend","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Next, we choose first- and second-derivative SBP operators D1, D2, evaluate the initial data on the grid, and set up the semidiscretization as an ODE problem.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"N = 100 # number of grid points\nD1 = periodic_derivative_operator(derivative_order=1, accuracy_order=4,\n xmin=xmin, xmax=xmax, N=N)\nD2 = periodic_derivative_operator(derivative_order=2, accuracy_order=4,\n xmin=xmin, xmax=xmax, N=N)\nu0 = u0_func.(grid(D1))\nparams = (D1=D1, D2=D2, a=1.0, ε=0.03)\node = ODEProblem(advection_diffusion!, u0, tspan, params);","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Finally, we can solve the ODE using an explicit Runge-Kutta method with adaptive time stepping.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"sol = solve(ode, Tsit5(), saveat=range(first(tspan), stop=last(tspan), length=200));\n\nplot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], D1), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], D1), label=L\"u_\\mathrm{numerical}\")\nsavefig(\"example_advection_diffusion.png\");","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"(Image: )","category":"page"},{"location":"tutorials/advection_diffusion/#Advanced-visualization","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Advanced visualization","text":"","category":"section"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Let's create an animation of the numerical solution.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"using Printf; using Plots: Animation, frame, gif\n\nlet anim = Animation()\n idx = 1\n x, u = evaluate_coefficients(sol[idx], D1)\n fig = plot(x, u, xguide=L\"x\", yguide=L\"u\", xlim=extrema(x), ylim=(-1.05, 1.05),\n label=\"\", title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n for idx in 1:length(sol.t)\n fig[1] = x, sol.u[idx]\n plot!(title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n frame(anim)\n end\n gif(anim, \"example_advection_diffusion.gif\")\nend","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"(Image: example_advection_diffusion_animation)","category":"page"},{"location":"tutorials/advection_diffusion/#Package-versions","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Package versions","text":"","category":"section"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"benchmarks/#Benchmarks","page":"Benchmarks","title":"Benchmarks","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Here are some simple benchmarks. Take them with a grain of salt since they run on virtual machines in the cloud to generate the documentation automatically.","category":"page"},{"location":"benchmarks/#First-derivative-operators","page":"Benchmarks","title":"First-derivative operators","text":"","category":"section"},{"location":"benchmarks/#Periodic-domains","page":"Benchmarks","title":"Periodic domains","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Let's set up some benchmark code.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using BenchmarkTools\nusing LinearAlgebra, SparseArrays\nusing SummationByPartsOperators, DiffEqOperators\n\nBLAS.set_num_threads(1) # make sure that BLAS is serial to be fair\n\nT = Float64\nxmin, xmax = T(0), T(1)\n\nD_SBP = periodic_derivative_operator(derivative_order=1, accuracy_order=2,\n xmin=xmin, xmax=xmax, N=100)\nx = grid(D_SBP)\nD_DEO = CenteredDifference(derivative_order(D_SBP), accuracy_order(D_SBP),\n step(x), length(x)) * PeriodicBC(eltype(D_SBP))\n\nD_sparse = sparse(D_SBP)\n\nu = randn(eltype(D_SBP), length(x)); du = similar(u);\n@show D_SBP * u ≈ D_DEO * u ≈ D_sparse * u\n\nfunction doit(D, text, du, u)\n println(text)\n sleep(0.1)\n show(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D, $u))\n println()\nend","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"First, we benchmark the implementation from SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_SBP, \"D_SBP:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Next, we compare this to the runtime obtained using a sparse matrix representation of the derivative operator. Depending on the hardware etc., this can be an order of magnitude slower than the optimized implementation from SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_sparse, \"D_sparse:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Finally, we benchmark the implementation of the same derivative operator in DiffEqOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_DEO, \"D_DEO:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"These results were obtained using the following versions.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"DiffEqOperators\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"benchmarks/#Bounded-domains","page":"Benchmarks","title":"Bounded domains","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"We start again by setting up some benchmark code.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using BenchmarkTools\nusing LinearAlgebra, SparseArrays\nusing SummationByPartsOperators, BandedMatrices\n\nBLAS.set_num_threads(1) # make sure that BLAS is serial to be fair\n\nT = Float64\nxmin, xmax = T(0), T(1)\n\nD_SBP = derivative_operator(MattssonNordström2004(), derivative_order=1,\n accuracy_order=6, xmin=xmin, xmax=xmax, N=10^3)\nD_sparse = sparse(D_SBP)\nD_banded = BandedMatrix(D_SBP)\n\nu = randn(eltype(D_SBP), size(D_SBP, 1)); du = similar(u);\n@show D_SBP * u ≈ D_sparse * u ≈ D_banded * u\n\nfunction doit(D, text, du, u)\n println(text)\n sleep(0.1)\n show(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D, $u))\n println()\nend","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"First, we benchmark the implementation from SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_SBP, \"D_SBP:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Again, we compare this to a representation of the derivative operator as a sparse matrix. No surprise - it is again much slower, as in periodic domains.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_sparse, \"D_sparse:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"FInally, we compare it to a representation as banded matrix. Disappointingly, this is still much slower than the optimized implementation from SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_banded, \"D_banded:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"These results were obtained using the following versions.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"BandedMatrices\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"benchmarks/#Dissipation-operators","page":"Benchmarks","title":"Dissipation operators","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"We follow the same structure as before. At first, we set up some benchmark code.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using BenchmarkTools\nusing LinearAlgebra, SparseArrays\nusing SummationByPartsOperators, BandedMatrices\n\nBLAS.set_num_threads(1) # make sure that BLAS is serial to be fair\n\nT = Float64\nxmin, xmax = T(0), T(1)\n\nD_SBP = derivative_operator(MattssonNordström2004(), derivative_order=1,\n accuracy_order=6, xmin=xmin, xmax=xmax, N=10^3)\nDi_SBP = dissipation_operator(MattssonSvärdNordström2004(), D_SBP)\nDi_sparse = sparse(Di_SBP)\nDi_banded = BandedMatrix(Di_SBP)\nDi_full = Matrix(Di_SBP)\n\nu = randn(eltype(D_SBP), size(D_SBP, 1)); du = similar(u);\n@show Di_SBP * u ≈ Di_sparse * u ≈ Di_banded * u ≈ Di_full * u\n\nfunction doit(D, text, du, u)\n println(text)\n sleep(0.1)\n show(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D, $u))\n println()\nend","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"At first, let us benchmark the derivative and dissipation operators implemented in SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_SBP, \"D_SBP:\", du, u)\ndoit(Di_SBP, \"Di_SBP:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Next, we compare the results to sparse matrix representations. It will not come as a surprise that these are again much (around an order of magnitude) slower.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(Di_sparse, \"Di_sparse:\", du, u)\ndoit(Di_banded, \"Di_banded:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Finally, let's benchmark the same computation if a full (dense) matrix is used to represent the derivative operator. This is obviously a bad idea but 🤷","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(Di_full, \"Di_full:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"These results were obtained using the following versions.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"BandedMatrices\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"benchmarks/#Structure-of-Arrays-(SoA)-and-Array-of-Structures-(AoS)","page":"Benchmarks","title":"Structure-of-Arrays (SoA) and Array-of-Structures (AoS)","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"SummationByPartsOperators.jl tries to provide efficient support of","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"StaticVectors from StaticArrays.jl\nStructArrays.jl","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"To demonstrate this, let us set up some benchmark code.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using BenchmarkTools\nusing StaticArrays, StructArrays\nusing LinearAlgebra, SparseArrays\nusing SummationByPartsOperators\n\nBLAS.set_num_threads(1) # make sure that BLAS is serial to be fair\n\nstruct Vec5{T} <: FieldVector{5,T}\n x1::T\n x2::T\n x3::T\n x4::T\n x5::T\nend\n\n# Apply `mul!` to each component of a plain array of structures one after another\nfunction mul_aos!(du, D, u, args...)\n for i in 1:size(du, 1)\n mul!(view(du, i, :), D, view(u, i, :), args...)\n end\nend\n\nT = Float64\nxmin, xmax = T(0), T(1)\n\nD_SBP = derivative_operator(MattssonNordström2004(), derivative_order=1,\n accuracy_order=4, xmin=xmin, xmax=xmax, N=101)\nD_sparse = sparse(D_SBP)\nD_full = Matrix(D_SBP)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"At first, we benchmark the application of the operators implemented in SummationByPartsOperators.jl and their representations as sparse and dense matrices in the scalar case. As before, the sparse matrix representation is around an order of magnitude slower and the dense matrix representation is far off.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Scalar case\")\nu = randn(T, size(D_SBP, 1)); du = similar(u)\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D_SBP, $u))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D_sparse, $u))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D_full, $u))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Next, we use a plain array of structures (AoS) in the form of a two-dimensional array and our custom mul_aos! implementation that loops over each component, using mul! on views. Here, the differences between the timings are less pronounced.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Plain Array of Structures\")\nu_aos_plain = randn(T, 5, size(D_SBP, 1)); du_aos_plain = similar(u_aos_plain)\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul_aos!($du_aos_plain, $D_SBP, $u_aos_plain))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul_aos!($du_aos_plain, $D_sparse, $u_aos_plain))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul_aos!($du_aos_plain, $D_full, $u_aos_plain))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Now, we use an array of structures (AoS) based on reinterpret and standard mul!. This is much more efficient for the implementation in SummationByPartsOperators.jl. In Julia v1.6, this is also more efficient for sparse matrices but less efficient for dense matrices (compared to the plain AoS approach with mul_aos! above).","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Array of Structures (reinterpreted array)\")\nu_aos_r = reinterpret(reshape, Vec5{T}, u_aos_plain); du_aos_r = similar(u_aos_r)\n@show D_SBP * u_aos_r ≈ D_sparse * u_aos_r ≈ D_full * u_aos_r\nmul!(du_aos_r, D_SBP, u_aos_r)\n@show reinterpret(reshape, T, du_aos_r) ≈ du_aos_plain\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos_r, $D_SBP, $u_aos_r))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos_r, $D_sparse, $u_aos_r))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos_r, $D_full, $u_aos_r))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Next, we still use an array of structures (AoS), but copy the data into a plain Array instead of using the reinterpreted versions. There is no significant difference to the previous version in this case.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Array of Structures\")\nu_aos = Array(u_aos_r); du_aos = similar(u_aos)\n@show D_SBP * u_aos ≈ D_sparse * u_aos ≈ D_full * u_aos\nmul!(du_aos, D_SBP, u_aos)\n@show du_aos ≈ du_aos_r\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos, $D_SBP, $u_aos))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos, $D_sparse, $u_aos))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos, $D_full, $u_aos))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Finally, let's look at a structure of arrays (SoA). Interestingly, this is slower than the array of structures we used above. On Julia v1.6, the sparse matrix representation performs particularly bad in this case.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Structure of Arrays\")\nu_soa = StructArray(u_aos); du_soa = similar(u_soa)\n@show D_SBP * u_soa ≈ D_sparse * u_soa ≈ D_full * u_soa\nmul!(du_soa, D_SBP, u_soa)\n@show du_soa ≈ du_aos\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_soa, $D_SBP, $u_soa))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_soa, $D_sparse, $u_soa))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_soa, $D_full, $u_soa))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"These results were obtained using the following versions.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"StaticArrays\", \"StructArrays\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"code_of_conduct/","page":"Code of conduct","title":"Code of conduct","text":"EditURL = \"https://github.com/ranocha/SummationByPartsOperators.jl/blob/main/CODE_OF_CONDUCT.md\"","category":"page"},{"location":"code_of_conduct/#code-of-conduct","page":"Code of conduct","title":"Code of Conduct","text":"","category":"section"},{"location":"code_of_conduct/","page":"Code of conduct","title":"Code of conduct","text":"Contributor Covenant Code of ConductOur PledgeWe as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.Our StandardsExamples of behavior that contributes to a positive environment for our community include:Demonstrating empathy and kindness toward other people\nBeing respectful of differing opinions, viewpoints, and experiences\nGiving and gracefully accepting constructive feedback\nAccepting responsibility and apologizing to those affected by our mistakes, and learning from the experience\nFocusing on what is best not just for us as individuals, but for the overall communityExamples of unacceptable behavior include:The use of sexualized language or imagery, and sexual attention or advances of any kind\nTrolling, insulting or derogatory comments, and personal or political attacks\nPublic or private harassment\nPublishing others' private information, such as a physical or email address, without their explicit permission\nOther conduct which could reasonably be considered inappropriate in a professional settingEnforcement ResponsibilitiesCommunity leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.ScopeThis Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.EnforcementInstances of abusive, harassing, or otherwise unacceptable behavior may be reported to Hendrik Ranocha. All complaints will be reviewed and investigated promptly and fairly.All community leaders are obligated to respect the privacy and security of the reporter of any incident.Enforcement GuidelinesCommunity leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:1. CorrectionCommunity Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.2. WarningCommunity Impact: A violation through a single incident or series of actions.Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.3. Temporary BanCommunity Impact: A serious violation of community standards, including sustained inappropriate behavior.Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.4. Permanent BanCommunity Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.Consequence: A permanent ban from any sort of public interaction within the community.AttributionThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/codeofconduct.html.Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.[homepage]: https://www.contributor-covenant.orgFor answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.","category":"page"},{"location":"api_reference/#SummationByPartsOperators.jl-API","page":"API reference","title":"SummationByPartsOperators.jl API","text":"","category":"section"},{"location":"api_reference/","page":"API reference","title":"API reference","text":"CurrentModule = SummationByPartsOperators","category":"page"},{"location":"api_reference/","page":"API reference","title":"API reference","text":"Modules = [SummationByPartsOperators]","category":"page"},{"location":"api_reference/#SummationByPartsOperators.SummationByPartsOperators","page":"API reference","title":"SummationByPartsOperators.SummationByPartsOperators","text":"SummationByPartsOperators\n\nSummationByPartsOperators.jl is a Julia library of summation-by-parts (SBP) operators, which are discrete derivative operators developed to get provably stable semidiscretizations, paying special attention to boundary conditions. Discretizations included in this framework are finite difference, Fourier pseudospectral, continuous Galerkin, and discontinuous Galerkin methods. The main aim of SummationByPartsOperators.jl is to be useful for researchers and students to learn the basic concepts by providing a unified framework of all of these seemingly different discretizations. At the same time, the implementation is optimized to achieve good performance without sacrificing flexibility.\n\nCheck out the documentation for further information. Some noticeable functions to start with are derivative_operator, legendre_derivative_operator, periodic_derivative_operator, fourier_derivative_operator, dissipation_operator, and grid.\n\nIf you use this package for your research, please cite it using\n\n@article{ranocha2021sbp,\n title={{SummationByPartsOperators.jl}: {A} {J}ulia library of provably stable\n semidiscretization techniques with mimetic properties},\n author={Ranocha, Hendrik},\n journal={Journal of Open Source Software},\n year={2021},\n month={08},\n doi={10.21105/joss.03454},\n volume={6},\n number={64},\n pages={3454},\n publisher={The Open Journal},\n url={https://github.com/ranocha/SummationByPartsOperators.jl}\n}\n\n\n\n\n\n","category":"module"},{"location":"api_reference/#SummationByPartsOperators.BeljaddLeFlochMishraParés2017","page":"API reference","title":"SummationByPartsOperators.BeljaddLeFlochMishraParés2017","text":"BeljaddLeFlochMishraParés2017()\n\nCoefficients of the periodic operators given in\n\nBeljadid, LeFloch, Mishra, Parés (2017) Schemes with Well-Controlled Dissipation. Hyperbolic Systems in Nonconservative Form. Communications in Computational Physics 21.4, pp. 913-946.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.BurgersNonperiodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.BurgersNonperiodicSemidiscretization","text":"BurgersNonperiodicSemidiscretization(D, Di, split_form, left_bc, right_bc)\n\nA semidiscretization of Burgers' equation partial_t u(tx) + partial_x fracu(tx)^22 = 0 with boundary conditions left_bc(t), right_bc(t).\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.BurgersPeriodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.BurgersPeriodicSemidiscretization","text":"BurgersPeriodicSemidiscretization(D, Di, split_form)\n\nA semidiscretization of Burgers' equation partial_t u(tx) + partial_x fracu(tx)^22 = 0 with periodic boundary conditions.\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.ConstantFilter","page":"API reference","title":"SummationByPartsOperators.ConstantFilter","text":"ConstantFilter\n\nRepresents the action of a modal filter on values in a nodal basis with fixed strength.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.ConstantFilter-Union{Tuple{T}, Tuple{FourierDerivativeOperator{T, Grid, RFFT, BRFFT} where {Grid, RFFT, BRFFT}, Any}} where T","page":"API reference","title":"SummationByPartsOperators.ConstantFilter","text":"ConstantFilter(D::FourierDerivativeOperator, filter)\n\nCreate a modal filter with constant parameters adapted to the Fourier derivative operator D with parameters given by the filter function filter.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.ConstantFilter-Union{Tuple{T}, Tuple{LegendreDerivativeOperator{T}, Any}, Tuple{LegendreDerivativeOperator{T}, Any, Any}} where T","page":"API reference","title":"SummationByPartsOperators.ConstantFilter","text":"ConstantFilter(D::LegendreDerivativeOperator, filter, TmpEltype=T)\n\nCreate a modal filter with constant parameters adapted to the Legendre derivative operator D with parameters given by the filter function filter.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.CubicNonperiodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.CubicNonperiodicSemidiscretization","text":"CubicNonperiodicSemidiscretization(D, Di, split_form, left_bc, right_bc)\n\nA semidiscretization of the cubic conservation law partial_t u(tx) + partial_x u(tx)^3 = 0 with nonperiodic boundary conditions left_bc(t), right_bc(t).\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.CubicPeriodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.CubicPeriodicSemidiscretization","text":"CubicPeriodicSemidiscretization(D, Di, split_form)\n\nA semidiscretization of the cubic conservation law partial_t u(tx) + partial_x u(tx)^3 = 0 with periodic boundary conditions.\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DerivativeCoefficientRow","page":"API reference","title":"SummationByPartsOperators.DerivativeCoefficientRow","text":"DerivativeCoefficientRow{T,Start,Length}\n\nA struct representing a row in the boundary block of an SBP derivative operator with scalar type T.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DerivativeCoefficients","page":"API reference","title":"SummationByPartsOperators.DerivativeCoefficients","text":"DerivativeCoefficients\n\nThe coefficients of a derivative operator on a nonperiodic grid.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DerivativeOperator","page":"API reference","title":"SummationByPartsOperators.DerivativeOperator","text":"DerivativeOperator\n\nA derivative operator on a nonperiodic finite difference grid. See derivative_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DienerDorbandSchnetterTiglio2007","page":"API reference","title":"SummationByPartsOperators.DienerDorbandSchnetterTiglio2007","text":"DienerDorbandSchnetterTiglio2007()\n\nCoefficients of the SBP operators given in\n\nDiener, Dorband, Schnetter, Tiglio (2007) Optimized high-order derivative and dissipation operators satisfying summation by parts, and applications in three-dimensional multi-block evolutions. Journal of Scientific Computing 32.1, pp. 109-145.\n\nSee also (second- and fourth-order operators)\n\nMattsson, Nordström (2004) Summation by parts operators for finite difference approximations of second derivatives. Journal of Computational Physics 199, pp. 503-540.\n\nThe dissipation operators proposed by Diener, Dorband, Schnetter, Tiglio (2007) for the diagonal-norm operators are the same as the ones of\n\nMattsson, Svärd, Nordström (2004) Stable and Accurate Artificial Dissipation. Journal of Scientific Computing 21.1, pp. 57-79.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DissipationOperator","page":"API reference","title":"SummationByPartsOperators.DissipationOperator","text":"DissipationOperator\n\nA dissipation operator on a nonperiodic finite difference grid. See dissipation_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.ExponentialFilter","page":"API reference","title":"SummationByPartsOperators.ExponentialFilter","text":"ExponentialFilter\n\nRepresents the exponential filter function σ(η) = exp(-α*η^p).\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FactorisationWrapper","page":"API reference","title":"SummationByPartsOperators.FactorisationWrapper","text":"FactorisationWrapper\n\nA small wrapper around a a factorisation fact, allowing to represent multiplication by the inverse of fact.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FastMode","page":"API reference","title":"SummationByPartsOperators.FastMode","text":"FastMode()\n\nA (probably) faster execution mode that might depend on packages such as LoopVectorization.jl.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Fornberg1998","page":"API reference","title":"SummationByPartsOperators.Fornberg1998","text":"Fornberg1998()\n\nCoefficients of the periodic operators given in\n\nFornberg (1998) Calculation of Weights in Finite Difference Formulas. SIAM Rev. 40.3, pp. 685-691.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FourierConstantViscosity","page":"API reference","title":"SummationByPartsOperators.FourierConstantViscosity","text":"FourierConstantViscosity\n\nFourier viscosity operator with constant coefficients for the periodic 1st derivative Fourier operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FourierDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.FourierDerivativeOperator","text":"FourierDerivativeOperator{T}\n\nA derivative operator on a periodic grid with real scalar type T computing the first derivative using a spectral Fourier expansion via real discrete Fourier transforms.\n\nSee also fourier_derivative_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FourierDerivativeOperator-Union{Tuple{T}, Tuple{T, T, Integer}} where T<:Real","page":"API reference","title":"SummationByPartsOperators.FourierDerivativeOperator","text":"FourierDerivativeOperator(xmin::T, xmax::T, N::Integer) where {T<:Real}\n\nConstruct the FourierDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N÷2+1 complex Fourier modes.\n\nSee also fourier_derivative_operator.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.FourierDerivativeOperator2D","page":"API reference","title":"SummationByPartsOperators.FourierDerivativeOperator2D","text":"FourierDerivativeOperator2D{T<:Real}\n\nA derivative operator on a two-dimensional periodic grid with scalar type T computing the first derivatives using a spectral Fourier expansion via real discrete Fourier transforms.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FourierDerivativeOperator2D-Union{Tuple{T}, Tuple{T, T, Int64, T, T, Int64}} where T<:Real","page":"API reference","title":"SummationByPartsOperators.FourierDerivativeOperator2D","text":"FourierDerivativeOperator2D(xmin, xmax, Nx, ymin, ymax, Ny)\n\nConstruct the FourierDerivativeOperator on a uniform grid between xmin and xmax using Nx nodes and ymin and ymax using Ny nodes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.Holoborodko2008","page":"API reference","title":"SummationByPartsOperators.Holoborodko2008","text":"Holoborodko2008()\n\nCoefficients of the periodic operators given in\n\nHoloborodko (2008) Smooth Noise Robust Differentiators. http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.LegendreDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.LegendreDerivativeOperator","text":"LegendreDerivativeOperator{T<:Real}\n\nA derivative operator on a nonperiodic Lobatto-Legendre grid with scalar type T computing the first derivative using a Legendre expansion.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.LegendreDerivativeOperator-Union{Tuple{T}, Tuple{T, T, Int64}} where T<:Real","page":"API reference","title":"SummationByPartsOperators.LegendreDerivativeOperator","text":"LegendreDerivativeOperator(xmin::T, xmax::T, N::Int) where {T<:Real}\n\nConstruct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.LegendreSecondDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.LegendreSecondDerivativeOperator","text":"LegendreSecondDerivativeOperator{T<:Real}\n\nA derivative operator on a nonperiodic Lobatto-Legendre grid with scalar type T computing the second derivative using a Legendre expansion.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.LinearlyCombinedDerivativeOperators","page":"API reference","title":"SummationByPartsOperators.LinearlyCombinedDerivativeOperators","text":"LinearlyCombinedDerivativeOperators\n\nForm linear combinations of several derivative operators lazily.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MadayTadmor1989","page":"API reference","title":"SummationByPartsOperators.MadayTadmor1989","text":"MadayTadmor1989()\n\nCoefficients of the Fourier spectral viscosity given in\n\nMaday, Tadmor (1989) Analysis of the Spectral Vanishing Viscosity Method for Periodic Conservation Laws. SIAM Journal on Numerical Analysis 26.4, pp. 854-870.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MatrixDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.MatrixDerivativeOperator","text":"MatrixDerivativeOperator{T <: Real}\nMatrixDerivativeOperator(xmin, xmax, nodes, weights, D, accuracy_order, source)\n\nA derivative operator on a nonperiodic grid with scalar type T computing a derivative as matrix vector product. This type is designed to make it easy to experiment with new operators given in matrix form.\n\nAn instance of this type can be constructed by passing the endpoints xmin, xmax of the desired grid as well as the nodes, weights, and the derivative operator D::Matrix on a reference interval, assuming that the nodes contain the boundary points of the reference interval. source is the source of coefficients and can be nothing for experimentation.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Mattsson2012","page":"API reference","title":"SummationByPartsOperators.Mattsson2012","text":"Mattsson2012()\n\nCoefficients of the SBP operators given in\n\nMattsson (2012) Summation by Parts Operators for Finite Difference Approximations of Second-Derivatives with Variable Coefficients. Journal of Scientific Computing 51, pp. 650-682.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Mattsson2014","page":"API reference","title":"SummationByPartsOperators.Mattsson2014","text":"Mattsson2014()\n\nCoefficients of the SBP operators given in\n\nMattsson (2014) Diagonal-norm summation by parts operators for finite difference approximations of third and fourth derivatives. Journal of Computational Physics 274, pp. 432-454.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Mattsson2017","page":"API reference","title":"SummationByPartsOperators.Mattsson2017","text":"Mattsson2017(version::Symbol)\n\nCoefficients of the upwind SBP operators given in\n\nMattsson (2017) Diagonal-norm upwind SBP operators. Journal of Computational Physics 335, pp. 283-310.\n\nYou can choose between the different versions :central, :plus, and :minus.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonAlmquistCarpenter2014Extended","page":"API reference","title":"SummationByPartsOperators.MattssonAlmquistCarpenter2014Extended","text":"MattssonAlmquistCarpenter2014Extended()\n\nCoefficients of the extended SBP operators given in\n\nMattsson, Almquist, Carpenter (2014) Optimal diagonal-norm SBP operators. Journal of Computational Physics 264, pp. 91-111.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonAlmquistCarpenter2014Optimal","page":"API reference","title":"SummationByPartsOperators.MattssonAlmquistCarpenter2014Optimal","text":"MattssonAlmquistCarpenter2014Optimal()\n\nCoefficients of the optimal SBP operators with nonuniform grid given in\n\nMattsson, Almquist, Carpenter (2014) Optimal diagonal-norm SBP operators. Journal of Computational Physics 264, pp. 91-111.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonAlmquistVanDerWeide2018Accurate","page":"API reference","title":"SummationByPartsOperators.MattssonAlmquistVanDerWeide2018Accurate","text":"MattssonAlmquistVanDerWeide2018Accurate()\n\nCoefficients of the optimized SBP operators with nonuniform grid given in\n\nMattsson, Almquist, van der Weide (2018) Boundary optimized diagonal-norm SBP operators. Journal of Computational Physics 374, pp. 1261-1266.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonAlmquistVanDerWeide2018Minimal","page":"API reference","title":"SummationByPartsOperators.MattssonAlmquistVanDerWeide2018Minimal","text":"MattssonAlmquistVanDerWeide2018Minimal()\n\nCoefficients of the optimized SBP operators with nonuniform grid given in\n\nMattsson, Almquist, van der Weide (2018) Boundary optimized diagonal-norm SBP operators. Journal of Computational Physics 374, pp. 1261-1266.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonNordström2004","page":"API reference","title":"SummationByPartsOperators.MattssonNordström2004","text":"MattssonNordström2004()\n\nCoefficients of the SBP operators given in\n\nMattsson, Nordström (2004) Summation by parts operators for finite difference approximations of second derivatives. Journal of Computational Physics 199, pp. 503-540.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonSvärdNordström2004","page":"API reference","title":"SummationByPartsOperators.MattssonSvärdNordström2004","text":"MattssonSvärdNordström2004()\n\nCoefficients of the SBP operators given in\n\nMattsson, Svärd, Nordström (2004) Stable and Accurate Artificial Dissipation. Journal of Scientific Computing 21.1, pp. 57-79.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonSvärdShoeybi2008","page":"API reference","title":"SummationByPartsOperators.MattssonSvärdShoeybi2008","text":"MattssonSvärdShoeybi2008()\n\nCoefficients of the SBP operators given in\n\nMattsson, Svärd, Shoeybi (2008) Stable and accurate schemes for the compressible Navier-Stokes equations. Journal of Computational Physics 227, pp. 2293-2316.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.PeriodicDerivativeCoefficients","page":"API reference","title":"SummationByPartsOperators.PeriodicDerivativeCoefficients","text":"PeriodicDerivativeCoefficients\n\nThe coefficients of a derivative operator on a periodic grid.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.PeriodicDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.PeriodicDerivativeOperator","text":"PeriodicDerivativeOperator\n\nA derivative operator on a uniform periodic grid. See periodic_derivative_operator and periodic_central_derivative_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.PeriodicDissipationOperator","page":"API reference","title":"SummationByPartsOperators.PeriodicDissipationOperator","text":"PeriodicDissipationOperator\n\nA dissipation operator on a periodic finite difference grid. See dissipation_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.PeriodicUpwindOperators","page":"API reference","title":"SummationByPartsOperators.PeriodicUpwindOperators","text":"PeriodicUpwindOperators\nPeriodicUpwindOperators(D_minus, D_central, D_plus)\n\nA struct bundling the individual operators available for periodic upwind SBP operators. The individual operators are available as D.minus, D.plus (and optionally D.central, if provided), where D::PeriodicUpwindOperators.\n\nThe combined struct behaves as much as possible as an operator itself as long as no ambiguities arise. For example, upwind operators need to use the same grid and mass matrix, so mass_matrix, grid, xmin, xmax etc. are available but mul! is not.\n\nIt is recommended to construct an instance of PeriodicUpwindOperators using upwind_operators. An instance can also be constructed manually by passing the operators in the order D_minus, D_central, D_plus.\n\nSee also upwind_operators, UpwindOperators\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.QuarticNonconvexPeriodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.QuarticNonconvexPeriodicSemidiscretization","text":"QuarticNonconvexPeriodicSemidiscretization(D, Di, split_form)\n\nA semidiscretization of the quartic nonconvex conservation law partial_t u(tx) + partial_x ( u(tx)^4 - 10 u(tx)^2 + 3 u(tx) ) = 0 with periodic boundary conditions.\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.SafeMode","page":"API reference","title":"SummationByPartsOperators.SafeMode","text":"SafeMode()\n\nA safe execution mode relying only on basic functionality of Julia.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.SharanBradyLivescu2022","page":"API reference","title":"SummationByPartsOperators.SharanBradyLivescu2022","text":"SharanBradyLivescu2022(alpha_left, alpha_right)\n\nCoefficients of the cut-cell SBP operators given in\n\nSharan, Brady, Livescu (2022) High-order dimensionally-split Cartesian embedded boundary method for non-dissipative schemes. Journal of Computational Physics 464, 111341.\n\nHere, alpha_left * Δx is the spacing between the left endpoint and the second node, while alpha_right * Δx is the spacing between the right endpoint and the last node.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.SourceOfCoefficients","page":"API reference","title":"SummationByPartsOperators.SourceOfCoefficients","text":"SourceOfCoefficients\n\nAll sources of coefficients (articles) are subtypes of this abstract type.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Tadmor1989","page":"API reference","title":"SummationByPartsOperators.Tadmor1989","text":"Tadmor1989()\n\nCoefficients of the Fourier spectral viscosity given in\n\nTadmor (1989) Convergence of Spectral Methods for Nonlinear Conservation Laws. SIAM Journal on Numerical Analysis 26.1, pp. 30-44.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Tadmor1993","page":"API reference","title":"SummationByPartsOperators.Tadmor1993","text":"Tadmor1993()\n\nCoefficients of the Fourier super spectral viscosity given in\n\nTadmor (1993) Super Viscosity and Spectral Approximations of Nonlinear Conservation Laws. Numerical Methods for Fluid Dynamics IV, pp. 69-82.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.TadmorWaagan2012Convergent","page":"API reference","title":"SummationByPartsOperators.TadmorWaagan2012Convergent","text":"TadmorWaagan2012Convergent()\n\nCoefficients of the Fourier spectral viscosity given in\n\nTadmor, Waagan (2012) Adaptive Spectral Viscosity for Hyperbolic Conservation Laws. SIAM Journal on Scientific Computing 34.2, pp. A993-A1009.\n\nSee also\n\nSchochet (1990) The Rate of Convergence of Spectral-Viscosity Methods for Periodic Scalar Conservation Laws. SIAM Journal on Numerical Analysis 27.5, pp. 1142-1159.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.TadmorWaagan2012Standard","page":"API reference","title":"SummationByPartsOperators.TadmorWaagan2012Standard","text":"TadmorWaagan2012Standard()\n\nCoefficients of the Fourier spectral viscosity given in\n\nTadmor, Waagan (2012) Adaptive Spectral Viscosity for Hyperbolic Conservation Laws. SIAM Journal on Scientific Computing 34.2, pp. A993-A1009.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.ThreadedMode","page":"API reference","title":"SummationByPartsOperators.ThreadedMode","text":"ThreadedMode()\n\nAn execution mode using multiple threads and possibly further optimizations, cf. FastMode.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.UniformMesh1D","page":"API reference","title":"SummationByPartsOperators.UniformMesh1D","text":"UniformMesh1D(xmin::Real, xmax::Real, Nx::Integer)\nUniformMesh1D(; xmin::Real, xmax::Real, Nx::Integer)\n\nA uniform mesh in one space dimension of Nx cells between xmin and xmax.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.UniformPeriodicMesh1D","page":"API reference","title":"SummationByPartsOperators.UniformPeriodicMesh1D","text":"UniformPeriodicMesh1D(xmin::Real, xmax::Real, Nx::Integer)\nUniformPeriodicMesh1D(; xmin::Real, xmax::Real, Nx::Integer)\n\nA uniform periodic mesh in one space dimension of Nx cells between xmin and xmax.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.UpwindOperators","page":"API reference","title":"SummationByPartsOperators.UpwindOperators","text":"UpwindOperators\nUpwindOperators(D_minus, D_central, D_plus)\n\nA struct bundling the individual operators available for non-periodic upwind SBP operators. The individual operators are available as D.minus, D.plus (and optionally D.central, if provided), where D::UpwindOperators.\n\nThe combined struct behaves as much as possible as an operator itself as long as no ambiguities arise. For example, upwind operators need to use the same grid and mass matrix, so mass_matrix, grid, xmin, xmax etc. are available but mul! is not.\n\nIt is recommended to construct an instance of UpwindOperators using upwind_operators. An instance can also be constructed manually by passing the operators in the order D_minus, D_central, D_plus.\n\nSee also upwind_operators, PeriodicUpwindOperators\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.VarCoefDerivativeCoefficients","page":"API reference","title":"SummationByPartsOperators.VarCoefDerivativeCoefficients","text":"VarCoefDerivativeCoefficients\n\nThe coefficients of a variable coefficient derivative operator on a nonperiodic grid.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.VarCoefDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.VarCoefDerivativeOperator","text":"VarCoefDerivativeOperator\n\nA dissipation operator on a nonperiodic finite difference grid.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.VariableLinearAdvectionNonperiodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.VariableLinearAdvectionNonperiodicSemidiscretization","text":"VariableLinearAdvectionNonperiodicSemidiscretization(D, Di, a, split_form,\n left_bc, right_bc)\n\nA semidiscretization of the linear advection equation partial_t u(tx) + partial_x ( a(x) u(tx) ) = 0 with boundary conditions left_bc(t), right_bc(t).\n\nD is an SBP derivative operator, Di an associated dissipation operator or nothing, a(x) the variable coefficient, and split_form::Union{Val(false), Val(true)} determines whether the canonical split form or the conservative form should be used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.VariableLinearAdvectionPeriodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.VariableLinearAdvectionPeriodicSemidiscretization","text":"VariableLinearAdvectionPeriodicSemidiscretization(D, Di, a, split_form)\n\nA semidiscretization of the linear advection equation partial_t u(tx) + partial_x ( a(x) u(tx) ) = 0 with periodic boundary conditions.\n\nD is a periodic SBP derivative operator, Di an associated dissipation operator or nothing, a(x) the variable coefficient, and split_form::Union{Val(false), Val(true)} determines whether the canonical split form or the conservative form should be used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.WaveEquationNonperiodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.WaveEquationNonperiodicSemidiscretization","text":"WaveEquationNonperiodicSemidiscretization(D, left_bc, right_bc)\n\nA semidiscretization of the linear wave equation partial_t^2 u(tx) = partial_x^2 u(tx).\n\nD is assumed to be a second-derivative SBP operator and the boundary conditions can be Val(:HomogeneousNeumann), Val(:HomogeneousDirichlet), or Val(:NonReflecting).\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#LinearAlgebra.mul!","page":"API reference","title":"LinearAlgebra.mul!","text":"mul!(du, D::DerivativeOperator, u, α=true, β=false)\n\nEfficient in-place version of du = α * D * u + β * du. Note that du must not be aliased with u.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#PolynomialBases.compute_coefficients!-Tuple{Any, Any, SummationByPartsOperators.AbstractDerivativeOperator}","page":"API reference","title":"PolynomialBases.compute_coefficients!","text":"compute_coefficients!(uval, u, D::AbstractDerivativeOperator)\n\nCompute the nodal values of the function u at the grid associated to the derivative operator D and stores the result in uval.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.compute_coefficients-Tuple{Any, SummationByPartsOperators.AbstractDerivativeOperator}","page":"API reference","title":"PolynomialBases.compute_coefficients","text":"compute_coefficients(u, D::AbstractDerivativeOperator)\n\nCompute the nodal values of the function u at the grid associated to the derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.evaluate_coefficients!-Tuple{Any, Any, Any, SummationByPartsOperators.AbstractDerivativeOperator}","page":"API reference","title":"PolynomialBases.evaluate_coefficients!","text":"evaluate_coefficients!(xplot, uplot, u, D::AbstractDerivativeOperator)\n\nEvaluates the nodal coefficients u at a grid associated to the derivative operator D and stores the result in xplot, uplot. Returns xplot, uplot, where xplot contains the nodes and uplot the corresponding values of u.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.evaluate_coefficients-Tuple{Any, SummationByPartsOperators.AbstractDerivativeOperator}","page":"API reference","title":"PolynomialBases.evaluate_coefficients","text":"evaluate_coefficients(u, D::AbstractDerivativeOperator)\n\nEvaluates the nodal coefficients u at a grid associated to the derivative operator D. Returns xplot, uplot, where xplot contains the nodes and uplot the corresponding values of u.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.integrate-Tuple{Any, AbstractVector{T} where T, DerivativeOperator}","page":"API reference","title":"PolynomialBases.integrate","text":"integrate(func, u, D::DerivativeOperator)\n\nMap the function func to the coefficients u and integrate with respect to the quadrature rule associated with the SBP derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.integrate-Tuple{Any, AbstractVector{T} where T, PeriodicDerivativeOperator}","page":"API reference","title":"PolynomialBases.integrate","text":"integrate(func, u, D::PeriodicDerivativeOperator)\n\nMap the function func to the coefficients u and integrate with respect to the quadrature rule associated with the periodic derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.integrate-Tuple{Any, AbstractVector{T} where T, SummationByPartsOperators.AbstractPeriodicDerivativeOperator}","page":"API reference","title":"PolynomialBases.integrate","text":"integrate(func, u, D::AbstractPeriodicDerivativeOperator)\n\nMap the function func to the coefficients u and integrate with respect to the quadrature rule associated with the derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.accuracy_order","page":"API reference","title":"SummationByPartsOperators.accuracy_order","text":"accuracy_order(D)\n\nReturn the order of accuracy of a derivative operator D. For SBP finite difference operators, this refers to the interior order of accuracy.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.couple_continuously","page":"API reference","title":"SummationByPartsOperators.couple_continuously","text":"couple_continuously(D, mesh)\n\nReturn a derivative operator corresponding to a continuous coupling of D on the cells of the given mesh as in (nodal) continuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are CG spectral element methods (CGSEM). However, a continuous coupling of arbitrary SBP operators is supported.\n\nThe mesh can be a UniformMesh1D or a UniformPeriodicMesh1D.\n\nReferences\n\nRanocha, Mitsotakis, Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.couple_discontinuously","page":"API reference","title":"SummationByPartsOperators.couple_discontinuously","text":"couple_discontinuously(D, mesh, [coupling=Val(:central)])\n\nReturn a derivative operator corresponding to a discontinuous coupling of D on the cells of the given mesh as in (nodal) discontinuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are DG spectral element methods (DGSEM). However, a discontinuous coupling of arbitrary SBP operators is supported.\n\nThe mesh can be a UniformMesh1D or a UniformPeriodicMesh1D. The coupling can be\n\nVal(:central) (default), resulting in classical SBP properties\nVal(:minus) or Val(:plus), resulting in upwind SBP operators\n\nReferences\n\nRanocha, Mitsotakis, Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.derivative_left-Tuple{SummationByPartsOperators.AbstractNonperiodicDerivativeOperator, Any}","page":"API reference","title":"SummationByPartsOperators.derivative_left","text":"derivative_left(D::AbstractNonperiodicDerivativeOperator, der_order)\n\nGet a representation of the linear functional evaluation the Nth derivative at the left boundary node as (dense) vector.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.derivative_left-Union{Tuple{N}, Tuple{DerivativeOperator, Any, Val{N}}} where N","page":"API reference","title":"SummationByPartsOperators.derivative_left","text":"derivative_left(D::DerivativeOperator, u, der_order::Val{N})\n\nCompute the N-th derivative of the function given by the coefficients u at the left boundary of the grid.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.derivative_operator","page":"API reference","title":"SummationByPartsOperators.derivative_operator","text":"derivative_operator(source_of_coefficients,\n derivative_order, accuracy_order,\n xmin, xmax, N, mode=FastMode())\nderivative_operator(source_of_coefficients;\n derivative_order, accuracy_order,\n xmin, xmax, N, mode=FastMode())\n\nCreate a DerivativeOperator approximating the derivative_order-th derivative on a grid between xmin and xmax with N grid points up to order of accuracy accuracy_order. with coefficients given by source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.derivative_order","page":"API reference","title":"SummationByPartsOperators.derivative_order","text":"derivative_order(D)\n\nReturn the order of the derivative associated to the derivative operator D. For example, it will return 1 for a first-derivative SBP operator.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.derivative_right-Tuple{SummationByPartsOperators.AbstractNonperiodicDerivativeOperator, Any}","page":"API reference","title":"SummationByPartsOperators.derivative_right","text":"derivative_right(D::AbstractNonperiodicDerivativeOperator, der_order)\n\nGet a representation of the linear functional evaluation the Nth derivative at the right boundary node as (dense) vector.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.derivative_right-Union{Tuple{N}, Tuple{DerivativeOperator, Any, Val{N}}} where N","page":"API reference","title":"SummationByPartsOperators.derivative_right","text":"derivative_right(D::DerivativeOperator, u, der_order::Val{N})\n\nCompute the N-th derivative of the function given by the coefficients u at the right boundary of the grid.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.dissipation_operator","page":"API reference","title":"SummationByPartsOperators.dissipation_operator","text":"dissipation_operator(source_of_coefficients, order, xmin, xmax, N,\n left_weights, right_weights, mode=FastMode())\n\nCreate a negative semidefinite DissipationOperator using undivided differences approximating a weighted order-th derivative on a grid between xmin and xmax with N grid points up to order of accuracy 2 with coefficients given by source_of_coefficients. The norm matrix is given by left_weights and right_weights. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.dissipation_operator-Tuple{PeriodicDerivativeOperator}","page":"API reference","title":"SummationByPartsOperators.dissipation_operator","text":"dissipation_operator(D::PeriodicDerivativeOperator;\n strength=one(eltype(D)),\n order=accuracy_order(D),\n mode=D.coefficients.mode)\n\nCreate a negative semidefinite DissipationOperator using undivided differences approximating a order-th derivative with strength strength adapted to the derivative operator D. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.dissipation_operator-Union{Tuple{T}, Tuple{Any, DerivativeOperator{T, LeftBoundary, RightBoundary, LeftBoundaryDerivatives, RightBoundaryDerivatives, LowerOffset, UpperOffset, LeftWidth, RightWidth, ExecutionMode, SourceOfCoefficients, Grid} where {LeftBoundary, RightBoundary, LeftBoundaryDerivatives, RightBoundaryDerivatives, LowerOffset, UpperOffset, LeftWidth, RightWidth, ExecutionMode, SourceOfCoefficients, Grid}}} where T","page":"API reference","title":"SummationByPartsOperators.dissipation_operator","text":"dissipation_operator([source_of_coefficients=MattssonSvärdNordström2004()],\n D::DerivativeOperator{T};\n strength=one(T),\n order::Int=accuracy_order(D),\n mode=D.coefficients.mode)\n\nCreate a negative semidefinite DissipationOperator using undivided differences approximating a weighted order-th derivative adapted to the derivative operator D with coefficients given in source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.fornberg-Union{Tuple{T}, Tuple{Vector{T}, Int64}} where T","page":"API reference","title":"SummationByPartsOperators.fornberg","text":"fornberg(x::Vector{T}, m::Int) where {T}\n\nCalculate the weights of a finite difference approximation of the mth derivative with maximal order of accuracy at 0 using the nodes x, see Fornberg (1998) Calculation of Weights in Finite Difference Formulas SIAM Rev. 40.3, pp. 685-691.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.fourier_derivative_matrix","page":"API reference","title":"SummationByPartsOperators.fourier_derivative_matrix","text":"fourier_derivative_matrix(N, xmin::Real=0.0, xmax::Real=2π)\n\nCompute the Fourier derivative matrix with respect to the corresponding nodal basis using N nodes, see Kopriva (2009) Implementing Spectral Methods for PDEs, Algorithm 18.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.fourier_derivative_operator-Tuple{Real, Real, Integer}","page":"API reference","title":"SummationByPartsOperators.fourier_derivative_operator","text":"fourier_derivative_operator(xmin::Real, xmax::Real, N::Integer)\nfourier_derivative_operator(; xmin::Real, xmax::Real, N::Integer)\n\nConstruct the FourierDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N÷2+1 complex Fourier modes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.grid","page":"API reference","title":"SummationByPartsOperators.grid","text":"grid(D)\n\nReturn the grid associated to a derivative operator D.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.left_boundary_weight","page":"API reference","title":"SummationByPartsOperators.left_boundary_weight","text":"left_boundary_weight(D)\n\nReturn the left-boundary weight of the (diagonal) mass matrix M associated to the derivative operator D.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.legendre_derivative_operator-Tuple{Real, Real, Integer}","page":"API reference","title":"SummationByPartsOperators.legendre_derivative_operator","text":"legendre_derivative_operator(xmin::Real, xmax::Real, N::Integer)\nlegendre_derivative_operator(; xmin::Real, xmax::Real, N::Integer)\n\nConstruct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.legendre_second_derivative_operator-Tuple{Real, Real, Integer}","page":"API reference","title":"SummationByPartsOperators.legendre_second_derivative_operator","text":"legendre_second_derivative_operator(xmin::Real, xmax::Real, N::Integer)\nlegendre_second_derivative_operator(; xmin::Real, xmax::Real, N::Integer)\n\nConstruct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.mass_matrix-Tuple{Union{DerivativeOperator, VarCoefDerivativeOperator}}","page":"API reference","title":"SummationByPartsOperators.mass_matrix","text":"mass_matrix(D::Union{DerivativeOperator,VarCoefDerivativeOperator})\n\nCreate the diagonal mass matrix for the SBP derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.mul_transpose_derivative_left!-Union{Tuple{N}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}, Any}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}, Any, Any}} where N","page":"API reference","title":"SummationByPartsOperators.mul_transpose_derivative_left!","text":"mul_transpose_derivative_left!(u, D::DerivativeOperator, der_order::Val{N}, α=true, β=false)\n\nSet the grid function u to α times the transposed N-th derivative functional applied to u plus β times u in the domain of the N-th derivative functional at the left boundary of the grid. Thus, the coefficients α, β have the same meaning as in mul!.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.mul_transpose_derivative_right!-Union{Tuple{N}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}, Any}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}, Any, Any}} where N","page":"API reference","title":"SummationByPartsOperators.mul_transpose_derivative_right!","text":"mul_transpose_derivative_right!(u, D::DerivativeOperator, der_order::Val{N}, α=true, β=false)\n\nSet the grid function u to α times the transposed N-th derivative functional applied to u plus β times u in the domain of the N-th derivative functional at the right boundary of the grid. Thus, the coefficients α, β have the same meaning as in mul!.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.periodic_central_derivative_coefficients","page":"API reference","title":"SummationByPartsOperators.periodic_central_derivative_coefficients","text":"periodic_central_derivative_coefficients(derivative_order, accuracy_order, T=Float64, mode=FastMode())\n\nCreate the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_central_derivative_operator","page":"API reference","title":"SummationByPartsOperators.periodic_central_derivative_operator","text":"periodic_central_derivative_operator(derivative_order, accuracy_order,\n xmin, xmax, N, mode=FastMode())\n\nCreate a PeriodicDerivativeOperator approximating the derivative_order-th derivative on a uniform grid between xmin and xmax with N grid points up to order of accuracy accuracy_order. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_coefficients","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_coefficients","text":"periodic_derivative_coefficients(derivative_order, accuracy_order,\n left_offset=-(accuracy_order+1)÷2,\n T=Float64, mode=FastMode())\n\nCreate the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()`.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_coefficients-Tuple{Holoborodko2008, Any, Any}","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_coefficients","text":"periodic_derivative_coefficients(source::Holoborodko2008, derivative_order, accuracy_order;\n T=Float64, mode=FastMode(),\n stencil_width=accuracy_order+3)\n\nCreate the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T given by Holoborodko2008. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()`.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_operator","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_operator","text":"periodic_derivative_operator(derivative_order, accuracy_order, grid,\n left_offset=-(accuracy_order+1)÷2, mode=FastMode())\n\nCreate a PeriodicDerivativeOperator approximating the derivative_order-th derivative on the uniform grid up to order of accuracy accuracy_order where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_operator-2","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_operator","text":"periodic_derivative_operator(derivative_order, accuracy_order,\n xmin, xmax, N,\n left_offset=-(accuracy_order+1)÷2,\n mode=FastMode())\nperiodic_derivative_operator(; derivative_order, accuracy_order,\n xmin, xmax, N,\n left_offset=-(accuracy_order+1)÷2,\n mode=FastMode())\n\nCreate a PeriodicDerivativeOperator approximating the derivative_order-th derivative on a uniform grid between xmin and xmax with N grid points up to order of accuracy accuracy_order where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).\n\nExamples\n\njulia> periodic_derivative_operator(derivative_order=1, accuracy_order=2,\n xmin=0.0, xmax=1.0, N=11)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 1.0] using 11 nodes,\nstencils with 1 nodes to the left, 1 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_operator-Tuple{Holoborodko2008, Any, Any, Any, Any, Any}","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_operator","text":"periodic_derivative_operator(source::Holoborodko2008,\n derivative_order, accuracy_order,\n xmin, xmax, N; mode=FastMode(), kwargs...)\nperiodic_derivative_operator(source::Holoborodko2008;\n derivative_order, accuracy_order,\n xmin, xmax, N, mode=FastMode(), kwargs...)\n\nCreate a PeriodicDerivativeOperator approximating the derivative_order-th derivative on a uniform grid between xmin and xmax with N grid points up to order of accuracy accuracy_order where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\nExamples\n\njulia> periodic_derivative_operator(Holoborodko2008(), derivative_order=1, accuracy_order=2,\n xmin=0.0, xmax=1.0, N=11)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 1.0] using 11 nodes,\nstencils with 2 nodes to the left, 2 nodes to the right, and coefficients of Holoborodko (2008)\n Smooth Noise Robust Differentiators.\n http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.right_boundary_weight","page":"API reference","title":"SummationByPartsOperators.right_boundary_weight","text":"right_boundary_weight(D)\n\nReturn the left-boundary weight of the (diagonal) mass matrix M associated to the derivative operator D.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.semidiscretize-Tuple{Any, SummationByPartsOperators.AbstractSemidiscretization, Any}","page":"API reference","title":"SummationByPartsOperators.semidiscretize","text":"semidiscretize(u0func, semi::AbstractSemidiscretization, tspan)\n\nApply the semidiscretization semi to the initial data given by u0func and return an ODEProblem with time span tspan.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.source_of_coefficients-Tuple{Any}","page":"API reference","title":"SummationByPartsOperators.source_of_coefficients","text":"source_of_coefficients(D)\n\nReturn the source of coefficients of the derivative operator D. If you use the operator D for your research, please cite this source in addition to SummationByPartsOperators.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.upwind_operators-Tuple{Any, Vararg{Any, N} where N}","page":"API reference","title":"SummationByPartsOperators.upwind_operators","text":"upwind_operators(source_type, args...; derivative_order = 1, kwargs...)\n\nCreate UpwindOperators from the given source type. The positional arguments args... and keyword arguments kwargs... are passed directly to derivative_operator.\n\nExamples\n\njulia> D = upwind_operators(Mattsson2017, accuracy_order = 2,\n xmin = 0//1, xmax = 9//1, N = 10)\nUpwind SBP first-derivative operators of order 2 on a grid in [0//1, 9//1] using 10 nodes\nand coefficients of Mattsson2017\n\njulia> D.minus\nSBP first-derivative operator of order 2 on a grid in [0//1, 9//1] using 10 nodes\nand coefficients of Mattsson (2017)\n Diagonal-norm upwind SBP operators.\n Journal of Computational Physics 335, pp. 283-310.\n (upwind coefficients minus)\n\njulia> D.plus\nSBP first-derivative operator of order 2 on a grid in [0//1, 9//1] using 10 nodes\nand coefficients of Mattsson (2017)\n Diagonal-norm upwind SBP operators.\n Journal of Computational Physics 335, pp. 283-310.\n (upwind coefficients plus)\n\njulia> Matrix(D.central)\n10×10 Matrix{Rational{Int64}}:\n -2//1 3//1 -1//1 0//1 0//1 0//1 0//1 0//1 0//1 0//1\n -3//5 0//1 4//5 -1//5 0//1 0//1 0//1 0//1 0//1 0//1\n 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1 0//1 0//1 0//1\n 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1 0//1 0//1\n 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1 0//1\n 0//1 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1\n 0//1 0//1 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1\n 0//1 0//1 0//1 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4\n 0//1 0//1 0//1 0//1 0//1 0//1 1//5 -4//5 0//1 3//5\n 0//1 0//1 0//1 0//1 0//1 0//1 0//1 1//1 -3//1 2//1\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.upwind_operators-Tuple{typeof(periodic_derivative_operator)}","page":"API reference","title":"SummationByPartsOperators.upwind_operators","text":"upwind_operators(periodic_derivative_operator;\n derivative_order = 1, accuracy_order,\n xmin, xmax, N,\n mode = FastMode()))\n\nCreate PeriodicUpwindOperators from operators constructed by periodic_derivative_operator. The keyword arguments are passed directly to periodic_derivative_operator.\n\nExamples\n\njulia> D = upwind_operators(periodic_derivative_operator, accuracy_order = 2,\n xmin = 0//1, xmax = 8//1, N = 8)\nUpwind SBP first-derivative operators of order 2 on a grid in [0//1, 7//1] using 8 nodes\nand coefficients of Fornberg1998\n\njulia> D.minus\nPeriodic first-derivative operator of order 2 on a grid in [0//1, 8//1] using 8 nodes,\nstencils with 2 nodes to the left, 0 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> D.plus\nPeriodic first-derivative operator of order 2 on a grid in [0//1, 8//1] using 8 nodes,\nstencils with 0 nodes to the left, 2 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> Matrix(D.central)\n8×8 Matrix{Rational{Int64}}:\n 0//1 1//1 -1//4 0//1 0//1 0//1 1//4 -1//1\n -1//1 0//1 1//1 -1//4 0//1 0//1 0//1 1//4\n 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1 0//1\n 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1\n 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1\n 0//1 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4\n -1//4 0//1 0//1 0//1 1//4 -1//1 0//1 1//1\n 1//1 -1//4 0//1 0//1 0//1 1//4 -1//1 0//1\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.var_coef_derivative_operator","page":"API reference","title":"SummationByPartsOperators.var_coef_derivative_operator","text":"var_coef_derivative_operator(source_of_coefficients, derivative_order, accuracy_order,\n xmin, xmax, N, left_weights, right_weights, bfunc,\n mode=FastMode())\n\nCreate a VarCoefDerivativeOperator approximating a derivative_order-th derivative with variable coefficients bfunc on a grid between xmin and xmax with N grid points up to order of accuracy accuracy_order with coefficients given by source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.xmax","page":"API reference","title":"SummationByPartsOperators.xmax","text":"xmax(D)\n\nReturn the right boundary xmax of the domain specified when constructing the derivative operator D. Note that this might be different from the rightmost node of the grid of D when not all boundary nodes are included, e.g., for periodic derivative operators.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.xmin","page":"API reference","title":"SummationByPartsOperators.xmin","text":"xmin(D)\n\nReturn the left boundary xmin of the domain specified when constructing the derivative operator D. Note that this might be different from the leftmost node of the grid of D when not all boundary nodes are included, e.g., for periodic derivative operators.\n\n\n\n\n\n","category":"function"},{"location":"license/","page":"License","title":"License","text":"EditURL = \"https://github.com/ranocha/SummationByPartsOperators.jl/blob/main/LICENSE.md\"","category":"page"},{"location":"license/#License","page":"License","title":"License","text":"","category":"section"},{"location":"license/","page":"License","title":"License","text":"MIT LicenseCopyright (c) 2017-present Hendrik Ranocha Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","category":"page"},{"location":"tutorials/wave_equation/#Wave-equation","page":"Wave equation","title":"Wave equation","text":"","category":"section"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"Consider the linear wave equation","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"beginaligned\n partial_t^2 u(tx) = partial_x^2 u(tx) t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \n partial_t u(0x) = v_0(x) x in (x_min x_max) \n textboundary conditions x in partial (x_min x_max)\nendaligned","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"SummationByPartsOperators.jl includes a pre-built semidiscretization of this equation: WaveEquationNonperiodicSemidiscretization. Have a look at the source code if you want to dig deeper. In particular, you can find applications of derivative_left, derivative_right mul_transpose_derivative_left!, and mul_transpose_derivative_right!. Below is an example demonstrating how to use this semidiscretization.","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig\n\n# general parameters\nxmin = -1.\nxmax = +1.\ntspan = (0., 8.0)\nu0_func(x) = exp(-20x^2)\nv0_func(x) = zero(x)\n# HomogeneousNeumann, HomogeneousDirichlet, and NonReflecting BCs are available\nleft_bc = Val(:HomogeneousNeumann)\nright_bc = Val(:HomogeneousDirichlet)\n\n# setup spatial semidiscretization\nD2 = derivative_operator(MattssonSvärdShoeybi2008(), derivative_order=2,\n accuracy_order=4, xmin=xmin, xmax=xmax, N=101)\nsemi = WaveEquationNonperiodicSemidiscretization(D2, left_bc, right_bc)\node = semidiscretize(v0_func, u0_func, semi, tspan)\n\n# solve second-order ODE using a Runge-Kutta-Nyström method\nsol = solve(ode, DPRKN6(), saveat=range(first(tspan), stop=last(tspan), length=200))\n\n# visualize the result\nplot(xguide=L\"x\")\nplot!(evaluate_coefficients(sol[end].x[2], semi), label=L\"u\")\nplot!(evaluate_coefficients(sol[end].x[1], semi), label=L\"\\partial_t u\")\nsavefig(\"example_wave_equation.png\");","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"(Image: )","category":"page"},{"location":"tutorials/wave_equation/#Advanced-visualization-of-different-boundary-conditions","page":"Wave equation","title":"Advanced visualization of different boundary conditions","text":"","category":"section"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"Let's create animations of the numerical solutions for different boundary conditions.","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"using Printf; using Plots: Animation, frame, gif\n\nfunction create_gif(left_bc::Val{LEFT_BC}, right_bc::Val{RIGHT_BC}) where {LEFT_BC, RIGHT_BC}\n xmin = -1.\n xmax = +1.\n tspan = (0., 8.0)\n u0_func(x) = exp(-20x^2)\n v0_func(x) = zero(x)\n\n D2 = derivative_operator(MattssonSvärdShoeybi2008(), derivative_order=2,\n accuracy_order=4, xmin=xmin, xmax=xmax, N=101)\n semi = WaveEquationNonperiodicSemidiscretization(D2, left_bc, right_bc)\n ode = semidiscretize(v0_func, u0_func, semi, tspan)\n\n sol = solve(ode, DPRKN6(), saveat=range(first(tspan), stop=last(tspan), length=200))\n\n anim = Animation()\n idx = 1\n x, u = evaluate_coefficients(sol[idx].x[2], D2)\n fig = plot(x, u, xguide=L\"x\", yguide=L\"u\", xlim=extrema(x), ylim=(-1.05, 1.05),\n label=\"\", title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n for idx in 1:length(sol.t)\n fig[1] = x, sol.u[idx].x[2]\n plot!(title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n frame(anim)\n end\n gif(anim, \"wave_equation_$(LEFT_BC)_$(RIGHT_BC).gif\")\nend\n\ncreate_gif(Val(:HomogeneousNeumann), Val(:HomogeneousNeumann))","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"(Image: wave_equation_HomogeneousNeumann_HomogeneousNeumann)","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"create_gif(Val(:HomogeneousNeumann), Val(:HomogeneousDirichlet))","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"(Image: wave_equation_HomogeneousNeumann_HomogeneousDirichlet)","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"create_gif(Val(:HomogeneousNeumann), Val(:NonReflecting))","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"(Image: wave_equation_HomogeneousNeumann_NonReflecting)","category":"page"},{"location":"tutorials/wave_equation/#Package-versions","page":"Wave equation","title":"Package versions","text":"","category":"section"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"ad/#Automatic/algorithmic-differentiation-(AD)","page":"Automatic differentiation (AD)","title":"Automatic/algorithmic differentiation (AD)","text":"","category":"section"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"SummationByPartsOperators.jl is written using generic Julia code whenever possible. This means that standard AD tools just work. For example, computing the Jacobian using ForwardDiff.jl is possible using the following code.","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"julia> using SummationByPartsOperators, ForwardDiff\n\njulia> D = periodic_derivative_operator(derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 8)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 1.0] using 8 nodes,\nstencils with 1 nodes to the left, 1 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> u = rand(size(D, 2));\n\njulia> J = ForwardDiff.jacobian(u -> D * u, u)\n8×8 Matrix{Float64}:\n 0.0 4.0 0.0 0.0 0.0 0.0 0.0 -4.0\n -4.0 0.0 4.0 0.0 0.0 0.0 0.0 0.0\n 0.0 -4.0 0.0 4.0 0.0 0.0 0.0 0.0\n 0.0 0.0 -4.0 0.0 4.0 0.0 0.0 0.0\n 0.0 0.0 0.0 -4.0 0.0 4.0 0.0 0.0\n 0.0 0.0 0.0 0.0 -4.0 0.0 4.0 0.0\n 0.0 0.0 0.0 0.0 0.0 -4.0 0.0 4.0\n 4.0 0.0 0.0 0.0 0.0 0.0 -4.0 0.0\n\njulia> J ≈ Matrix(D)\ntrue","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"This works of course also for non-periodic SBP operators, e.g.,","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"julia> using SummationByPartsOperators, ForwardDiff\n\njulia> D = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 8)\nSBP first-derivative operator of order 2 on a grid in [0.0, 1.0] using 8 nodes\nand coefficients of Mattsson, Nordström (2004)\n Summation by parts operators for finite difference approximations of second\n derivatives.\n Journal of Computational Physics 199, pp. 503-540.\n\njulia> u = rand(size(D, 2));\n\njulia> J = ForwardDiff.jacobian(u -> D * u, u)\n8×8 Matrix{Float64}:\n -7.0 7.0 0.0 0.0 0.0 0.0 0.0 0.0\n -3.5 0.0 3.5 0.0 0.0 0.0 0.0 0.0\n 0.0 -3.5 0.0 3.5 0.0 0.0 0.0 0.0\n 0.0 0.0 -3.5 0.0 3.5 0.0 0.0 0.0\n 0.0 0.0 0.0 -3.5 0.0 3.5 0.0 0.0\n 0.0 0.0 0.0 0.0 -3.5 0.0 3.5 0.0\n 0.0 0.0 0.0 0.0 0.0 -3.5 0.0 3.5\n 0.0 0.0 0.0 0.0 0.0 0.0 -7.0 7.0\n\njulia> J ≈ Matrix(D)\ntrue","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"However, this does not work for Fourier derivative operators - and all other operators involving an FFT - since FFTW.jl cannot handle dual numbers and a simple reinterpret trick does also not help since FFTW.jl requires unit strides.","category":"page"},{"location":"ad/#Jacobian-vector-products","page":"Automatic differentiation (AD)","title":"Jacobian-vector products","text":"","category":"section"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"There is a nat trick that you can use if you are only interested in Jacobian-vector products. ForwardDiff.jl does not offer such a functionality at the time of writing, but Simon Byrne suggested the following implementation.","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"using SummationByPartsOperators, ForwardDiff, StructArrays\n\nfunction StructDual(x::AbstractVector{T}, w::AbstractVector{T}) where {T}\n @assert length(x) == length(w)\n # This was the original suggestion. However, it is currently not stable\n # under broadcasting. Thus, we use a slightly different version.\n # partials = StructArray{ForwardDiff.Partials{1, T}}(\n # (StructArray{Tuple{T}}(\n # (w,)\n # ),)\n # )\n partials = reinterpret(reshape, ForwardDiff.Partials{1, T}, w)\n duals = StructArray{ForwardDiff.Dual{Nothing, T, 1}}((x, partials))\n return duals\nend\n\nfunction ForwardDiff.value(dx::StructArray{D}) where {D <: ForwardDiff.Dual}\n return dx.value\nend\n\nfunction ForwardDiff.partials(dx::StructArray{<: ForwardDiff.Dual{Tag, T, 1}}, i) where {Tag, T}\n # This was the original suggestion. We need to update it (see above).\n # return getproperty(dx.partials.values, i)\n @assert i == 1\n return reinterpret(reshape, T, dx.partials)\nend","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"You can use it as follows to compute the Jacobian-vector product","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"J_f(u) cdot v","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"for the function f given by","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"f(u) = D u","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"D = fourier_derivative_operator(xmin = 0.0, xmax = 1.0, N = 8)\n\nu = randn(size(D, 2)); # the point `u` where we want to compute the derivative\nv = randn(size(D, 2)); # the direction `v` in which we want to compute the derivative\nu_v = StructDual(u, v); # combined StructArray containing the value and direction\n\nf_df = D * u_v # compute the function value and its derivative\n\n@assert ForwardDiff.value(f_df) ≈ D * u\n\n@assert ForwardDiff.partials(f_df, 1) ≈ D * v # the Jacobian of `f(u) = D * u` is `D`","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"You can of course also use this with nonlinear functions, e.g.,","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"f(u, D) = u .* (D * (u.^2))\n\nf_df = f(u_v, D)","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"The Jacobian of this function is","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"using LinearAlgebra\n\nJ = Diagonal(D * u.^2) + 2 .* u .* Matrix(D) * Diagonal(u)\n\n@assert ForwardDiff.value(f_df) ≈ f(u, D)\n\n@assert ForwardDiff.partials(f_df, 1) ≈ J * v","category":"page"},{"location":"ad/#Reproducibility","page":"Automatic differentiation (AD)","title":"Reproducibility","text":"","category":"section"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"These results were obtained using the following versions.","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"ForwardDiff\", \"StructArrays\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"introduction/#intro-introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Summation-by-parts (SBP) operators are discrete derivative operators designed to enable (semi-) discrete stability proofs mimicking the energy method from the continuous level. To do so, SBP operators mimic integration-by-parts discretely. Here, we will briefly explain the basic concepts. If you want to learn more about this subject, the classical review articles of [SvärdNordström2014] and [FernándezHickenZingg2014] are good starting points. More recent references and applications of SBP operators from many classes implemented in SummationByPartsOperators.jl are given by [RanochaMitsotakisKetcheson2021].","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Since SBP operators are designed to mimic integration-by-parts, they need a notion of derivatives and integrals. Here, derivatives are interpreted as linear operators D (derivative matrices) and integrals are interpreted as discrete inner products, represented by the associated mass/norm matrices M. Thus, the discrete derivative of a grid function u is D * u and the discrete inner product of two grid functions u and v is dot(u, M, v), where M = mass_matrix(D). Here, we have already introduced some basic interfaces provided by SummationByPartsOperators.jl:","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Derivative operators act as linear operators implementing * (and mul! for more efficient in-place updates avoiding allocations).\nThe mass matrix associated to an SBP derivative operator can be retrieved via mass_matrix.","category":"page"},{"location":"introduction/#Periodic-domains","page":"Introduction","title":"Periodic domains","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Periodic (central) SBP operators mimic the properties of differential operators on periodic domains. Hence, they are","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"skew-symmetric if they approximate odd derivatives\nsymmetric and semi-definite if they approximate even derivatives; second-derivative operators are negative semi-definite, fourth-derivative operators are positive semi-definite etc.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Classical central finite difference operators on periodic domains are periodic SBP operators. They can be constructed via periodic_derivative_operator. Similarly, Fourier collocation methods can be interpreted as periodic SBP operators, which can be constructed via fourier_derivative_operator.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"julia> using SummationByPartsOperators, LinearAlgebra\n\njulia> D = periodic_derivative_operator(derivative_order=1, accuracy_order=2,\n xmin=0.0, xmax=2.0, N=20)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 2.0] using 20 nodes,\nstencils with 1 nodes to the left, 1 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> M = mass_matrix(D)\nUniformScaling{Float64}\n0.1*I\n\njulia> M * Matrix(D) + Matrix(D)' * M |> norm\n0.0\n\njulia> D = fourier_derivative_operator(xmin=0.0, xmax=2.0, N=20)\nPeriodic 1st derivative Fourier operator {T=Float64}\non a grid in [0.0, 2.0] using 20 nodes and 11 modes\n\njulia> M = mass_matrix(D)\nUniformScaling{Float64}\n0.1*I\n\njulia> norm(M * Matrix(D) + Matrix(D)' * M) < 10 * eps(eltype(D))\ntrue","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"As you have seen above, conversion methods to other common types such as Matrix, sparse from the standard library SparseArrays, and BandedMatrix from BandedMatrices.jl are available.","category":"page"},{"location":"introduction/#Non-periodic-domains","page":"Introduction","title":"Non-periodic domains","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"On non-periodic domains, additional boundary terms appear. Thus, the basic symmetry properties of SBP operators are the same as the ones of periodic SBP operators modulo boundary terms. Note that the correct handling of boundary terms is the basic reason of the success of SBP operators. In particular for hyperbolic problems, other boundary treatments that might appear senseful can result in catastrophic failure.","category":"page"},{"location":"introduction/#First-derivative-operators","page":"Introduction","title":"First-derivative operators","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"First-derivative SBP operators need to mimic","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":" int_x_mathrmmin^x_mathrmmax u(x) bigl( partial_x v(x) bigr) mathrmdx\n+ int_x_mathrmmin^x_mathrmmax bigl( partial_x u(x) bigr) v(x) mathrmdx\n= u(x_mathrmmax) v(x_mathrmmax) - u(x_mathrmmin) v(x_mathrmmin)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Thus, a discrete evaluation at the boundary of the domain is necessary. For SBP operators with a grid including the boundary nodes, this can be achieved by simply picking the first/last nodal coefficient of a grid function u. If boundary nodes are not included, some interpolation is necessary in general. Nevertheless, getting a boundary value is a linear functional that is often represented in the literature using (transposed) vectors tL, tR. Then, an SBP operator has to satisfy M * D + D' * M == tR * tR' - tL * tL'. The boundary operators are represented matrix-free via derivative_left and derivative_right for zeroth-order derivatives.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0//1, xmax = 1//1, N = 9)\ntL = zeros(eltype(D), size(D, 1)); tL[1] = 1; tL'\ntR = zeros(eltype(D), size(D, 1)); tR[end] = 1; tR'\nM = mass_matrix(D)\n\nM * Matrix(D) + Matrix(D)' * M == tR * tR' - tL * tL'\nu = randn(size(grid(D))); derivative_left(D, u, Val(0)) == u[begin]\nu = randn(size(grid(D))); derivative_right(D, u, Val(0)) == u[end]","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Here, we have introduced some additional features. Firstly, exact rational coefficients are provided, based on the type of xmin and xmax (if available). Secondly, a source_of_coefficients has to be provided when constructing the SBP operator. You can list them using","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using InteractiveUtils, SummationByPartsOperators\nsubtypes(SourceOfCoefficients)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Here and in the following, the order of accuracy of (finite difference) SBP operators refers to the local order of accuracy in the interior, cf. accuracy_order.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"A special case of first-derivative SBP operators are polynomial derivative operators on Lobatto-Legendre nodes, implemented in legendre_derivative_operator.","category":"page"},{"location":"introduction/#Second-derivative-operators","page":"Introduction","title":"Second-derivative operators","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"To mimic integration-by-parts of second derivatives,","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":" int_x_mathrmmin^x_mathrmmax u(x) bigl( partial_x^2 v(x) bigr) mathrmdx\n= - int_x_mathrmmin^x_mathrmmax bigl( partial_x u(x) bigr) bigl( partial_x v(x) bigr) mathrmdx\n + u(x_mathrmmax) bigl( partial_x v(x_mathrmmax) bigr)\n - bigl( partial_x u(x_mathrmmin)) v(x_mathrmmin)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"the evaluation of the first derivative at the boundaries is necessary. These linear functionals are available as derivative_left and derivative_right. In the literature, they are often called dL and dR. Then, a second-derivative SBP operator has to be of the form M * D == -A + tR * dR' - tL * dL', where A is symmetric and positive semidefinite.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nD = derivative_operator(MattssonNordström2004(), derivative_order=2, accuracy_order=2,\n xmin=0//1, xmax=1//1, N=9)\n\nM = mass_matrix(D)\ntL = derivative_left(D, Val(0)); tL'\ntR = derivative_right(D, Val(0)); tR'\ndL = derivative_left(D, Val(1)); dL'\ndR = derivative_right(D, Val(1)); dR'\n\nA = -M * Matrix(D) + tR * dR' - tL * dL'\nisposdef(A)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Usually, there is no need to form dL, dR explicitly. Instead, you can use the matrix-free variants derivative_left and derivative_right. Some procedures imposing boundary conditions weakly require adding the transposed boundary derivatives to a grid function, which can be achieved by mul_transpose_derivative_left! and mul_transpose_derivative_right!. You can find applications of these operators in the source code of WaveEquationNonperiodicSemidiscretization.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"A special case of second-derivative SBP operators are polynomial derivative operators on Lobatto-Legendre nodes, implemented in legendre_second_derivative_operator.","category":"page"},{"location":"introduction/#intro-upwind-operators","page":"Introduction","title":"Upwind operators","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Upwind SBP operators were introduced by Mattsson2017. They combine two derivative operators Dp (:plus) and Dm (:minus) such that M * Dp + Dm' * M == tR * tR' - tL * tL' and M * (Dp - Dm) is negative semidefinite.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nDp = derivative_operator(Mattsson2017(:plus), derivative_order=1, accuracy_order=2,\n xmin=0//1, xmax=1//1, N=9)\nMatrix(Dp)\nDm = derivative_operator(Mattsson2017(:minus), derivative_order=1, accuracy_order=2,\n xmin=0//1, xmax=1//1, N=9)\nMatrix(Dm)\n\nM = mass_matrix(Dp)\nM * Matrix(Dp) + Matrix(Dm)' * M\nminimum(eigvals(-M * (Matrix(Dp) - Matrix(Dm)))) # > 0 up to floating point tolerances","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"You can also set up fully periodic upwind operators by setting the argument left_offset of periodic_derivative_operator appropriately. For example,","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nDp = periodic_derivative_operator(derivative_order=1, accuracy_order=2, left_offset=0,\n xmin=0//1, xmax=1//1, N=8)\nMatrix(Dp)\nDm = periodic_derivative_operator(derivative_order=1, accuracy_order=2, left_offset=-2,\n xmin=0//1, xmax=1//1, N=8)\nMatrix(Dm)\n\nM = mass_matrix(Dp)\nM * Matrix(Dp) + Matrix(Dm)' * M |> iszero\nminimum(eigvals(-M * (Matrix(Dp) - Matrix(Dm)))) # > 0 up to floating point tolerances","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Note that we used N=8 here, i.e., one node less than for the non-periodic example. This is necessary since the additional node at the right boundary is identified with the left boundary node for periodic operators.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"To create all upwind operators for a single setup, you can use upwind_operators.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators\n\nD = upwind_operators(Mattsson2017, derivative_order=1, accuracy_order=2,\n xmin=0, xmax=1//1, N=9)\nMatrix(D.plus)\nMatrix(D.minus)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"This also works with periodic upwind operators.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators\n\nD = upwind_operators(periodic_derivative_operator, accuracy_order = 2,\n xmin = 0, xmax = 1//1, N = 10)\nMatrix(D.plus)\nMatrix(D.minus)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"You can also couple upwind operators continuously across elements using couple_continuously to obtain global upwind operators, see below and Theorem 2.4 of [RanochaMitsotakisKetcheson2021].","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Similarly, you can couple classical and upwind operators discontinuously across elements using couple_discontinuously to obtain global upwind operators, see below and Theorem 2.2 of [RanochaMitsotakisKetcheson2021].","category":"page"},{"location":"introduction/#intro-CGSEM","page":"Introduction","title":"Continuous Galerkin methods","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"SBP operators can be coupled to obtain (nodal) continuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are CG spectral element methods (CGSEM). However, a continuous coupling of arbitrary SBP operators is supported.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nD = couple_continuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=3),\n UniformMesh1D(xmin=0.0, xmax=1.0, Nx=3))\nMatrix(D)\nmass_matrix(D)","category":"page"},{"location":"introduction/#intro-DGSEM","page":"Introduction","title":"Discontinuous Galerkin methods","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"SBP operators can also be coupled as in discontinuous Galerkin (DG) methods. Using a central numerical flux results in central SBP operators; upwind fluxes yield upwind SBP operators. If LegendreDerivativeOperators are used, the discontinuous coupling yields DG spectral element methods (DGSEM).","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nD = couple_discontinuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=3),\n UniformPeriodicMesh1D(xmin=0.0, xmax=1.0, Nx=3),\n Val(:central))\n\nM = mass_matrix(D);\nM * Matrix(D) + Matrix(D)' * M |> iszero","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Right now, only uniform meshes UniformMesh1D and UniformPeriodicMesh1D are implemented.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"You can also specify a different coupling than Val(:central) to obtain upwind operators.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nDp = couple_discontinuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=3),\n UniformPeriodicMesh1D(xmin=0.0, xmax=1.0, Nx=3),\n Val(:plus))\n\nMatrix(Dp)\n\nDm = couple_discontinuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=3),\n UniformPeriodicMesh1D(xmin=0.0, xmax=1.0, Nx=3),\n Val(:minus))\n\nMatrix(Dm)","category":"page"},{"location":"introduction/#Basic-interfaces-and-additional-features","page":"Introduction","title":"Basic interfaces and additional features","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"To actually compute and plot the discrete grid functions, a few additional ingredients are necessary.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"The discrete coefficients of a function on the grid of an SBP operator can usually be computed as x = grid(D); u = u_function.(x), at least for nodal bases. In general, compute_coefficients (or the in-place version compute_coefficients!) can also be used for this task.\nTo get a grid and discrete values suitable for plotting, you can use evaluate_coefficients (or the in-place version evaluate_coefficients!). The plot nodes returned from evaluate_coefficients can be different from the nodes of the grid associated to an SBP operator.\nTo implement boundary procedures, the weights of the mass matrix at the boundary are often needed. These can be obtained without forming M = mass_matrix(D) explicitly via left_boundary_weight and right_boundary_weight.\nInstead of forming a mass matrix explicitly, discrete integrals can be evaluated efficiently using integrate.\nDissipation operators based on the same discrete inner product as SBP derivative operators can be obtained via dissipation_operator.","category":"page"},{"location":"introduction/#Next-steps","page":"Introduction","title":"Next steps","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"If you are familiar with SBP operators in general, this introduction might already be enough for you to apply SummationByPartsOperators.jl to your problems. Otherwise, you might want to have a look at the references, the tutorials coming next, or some ready-to-use semidiscretizations of the following partial differential equations (PDEs). These are shipped with this package and you are encouraged to look at their source code to learn more about it.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Linear scalar advection with variable coefficient: VariableLinearAdvectionPeriodicSemidiscretization, VariableLinearAdvectionNonperiodicSemidiscretization\nBurgers' equation (inviscid): BurgersPeriodicSemidiscretization, BurgersNonperiodicSemidiscretization\nScalar conservation law with cubic flux: CubicPeriodicSemidiscretization, CubicNonperiodicSemidiscretization\nA scalar conservation law with quartic, non-convex flux: QuarticNonconvexPeriodicSemidiscretization\nThe second-order wave equation: WaveEquationNonperiodicSemidiscretization","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Some additional examples are included as Jupyter notebooks in the directory notebooks. Even more examples and research articles making use of SummationByPartsOperators.jl are listed in the section Applications. If you want to know even more, you can have a look at the test.","category":"page"},{"location":"introduction/#References","page":"Introduction","title":"References","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"[SvärdNordström2014]: Svärd, Nordström (2014). Review of summation-by-parts schemes for initial–boundary-value problems. DOI: 10.1016/j.jcp.2014.02.031","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"[FernándezHickenZingg2014]: Fernández, Hicken, Zingg (2014). Review of summation-by-parts operators with simultaneous approximation terms for the numerical solution of partial differential equations. DOI: 10.1016/j.compfluid.2014.02.016","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"[RanochaMitsotakisKetcheson2021]: Ranocha, Mitsotakis, Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119","category":"page"},{"location":"tutorials/basic_interface/#Basic-interface","page":"Basic interface","title":"Basic interface","text":"","category":"section"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"Here, we discuss the basic interface of SummationByPartsOperators.jl. We assume you are already familiar with the concept of SBP operators in general and the introduction describing how to construct specific operators.","category":"page"},{"location":"tutorials/basic_interface/#Applying-SBP-operators","page":"Basic interface","title":"Applying SBP operators","text":"","category":"section"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"All SBP operators implement the general interface of matrix vector multiplication in Julia. The most simple version is to just use *, e.g.,","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nx = grid(D)\n\nu = @. sin(pi * x)\n\nD * u\n\n@allocated D * u","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"As you can see above, calling D * u allocates a new vector for the result. If you want to apply an SBP operator multiple times and need good performance, you should consider using pre-allocating the output and using in-place update instead. This strategy is also described in the performance tips in the Julia manual. Julia provides the function mul! for this purpose.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using LinearAlgebra, InteractiveUtils\n\n@doc mul!","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"To improve the performance, you can pre-allocate an output vector and call the non-allocating function mul!.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nx = grid(D)\n\nu = @. sin(pi * x)\n\ndu = similar(u); mul!(du, D, u)\n\ndu ≈ D * u\n\n@allocated mul!(du, D, u)","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"All operators provided by SummationByPartsOperators.jl implement this 3-argument version of mul!. Most operators also implement the 5-argument version of mul! that can be used to scale the output and add it to some multiple of the result vector.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nx = grid(D); u = @. sin(pi * x); du = similar(u); mul!(du, D, u);\n\nmul!(du, D, u, 2) # equivalent to du .= 2 * D * u\n\ndu ≈ 2 * D * u\n\n@allocated mul!(du, D, u, 2)\n\ndu_background = rand(length(du)); du .= du_background\n\nmul!(du, D, u, 2, 3) # equivalent to du .= 2 * D * u + 3 * du\n\ndu ≈ 2 * D * u + 3 * du_background\n\n@allocated mul!(du, D, u, 2, 3)","category":"page"},{"location":"tutorials/basic_interface/#Integration-and-the-mass/norm-matrix","page":"Basic interface","title":"Integration and the mass/norm matrix","text":"","category":"section"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"SBP operators come with a mass matrix yielding a quadrature rule. In SummationByPartsOperators.jl, all operators typically have diagonal mass/norm matrices. You can access them via mass_matrix, e.g.,","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nmass_matrix(D)\n\nD = periodic_derivative_operator(derivative_order = 1,\n accuracy_order = 2,\n xmin = 0.0, xmax = 1.0,\n N = 8)\n\nmass_matrix(D)","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"If you want to use the quadrature associated with a mass matrix, you do not need to form it explicitly. Instead, it is recommended to use the function integrate, e.g.,","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nM = mass_matrix(D)\n\nx = grid(D)\n\nu = x.^2\n\nintegrate(u, D)\n\nintegrate(u, D) ≈ sum(M * u)\n\nintegrate(u, D) ≈ integrate(x -> x^2, x, D)","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"For example, you can proceed as follows to compute the error of the SBP operator when computing a derivative as follows.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nM = mass_matrix(D)\n\nx = grid(D)\n\ndifference = D * x.^3 - 3 * x.^2\n\nerror_l2 = sqrt(integrate(abs2, difference, D))","category":"page"},{"location":"tutorials/basic_interface/#Multi-dimensional-cases-or-multiple-variables","page":"Basic interface","title":"Multi-dimensional cases or multiple variables","text":"","category":"section"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"If you want to work with multiple space dimensions, you can still use the 1D operators provided by SummationByPartsOperators.jl if you apply them in a tensor product fashion along each space dimension.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 4,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nx = y = grid(D)\n\nu = x .* y'.^2 # u(x, y) = x y^2\n\nlet du_dx = zero(u)\n for j in axes(u, 2)\n mul!(view(du_dx, :, j), D, view(u, :, j))\n end\n # The derivative of x*y^2 with respect to x is just y^2.\n # Thus, the result is constant in each column and varies\n # in the rows.\n du_dx\nend\n\nlet du_dy = zero(u)\n for i in axes(u, 1)\n mul!(view(du_dy, i, :), D, view(u, i, :))\n end\n # The derivative of x*y^2 with respect to y is 2*x*y.\n du_dy\nend\n\n2 .* x .* y'","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"Here, we have used views to interpret parts of the memory of the multi-dimensional arrays as one-diemnsional vectors that can be used together with the operators of SummationByPartsOperators.jl. You can use the same trick if you collect values of multiple variables in a multi-dimensional array.","category":"page"},{"location":"#SummationByPartsOperators.jl","page":"Home","title":"SummationByPartsOperators.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The Julia library SummationByPartsOperators.jl provides a unified interface of different discretization approaches including finite difference, Fourier pseudospectral, continuous Galerkin, and discontinuous Galerkin methods. This unified interface is based on the notion of summation-by-parts (SBP) operators. Originally developed for finite difference methods, SBP operators are discrete derivative operators designed specifically to get provably stable (semi-) discretizations, mimicking energy/entropy estimates from the continuous level discretely and paying special attention to boundary conditions.","category":"page"},{"location":"","page":"Home","title":"Home","text":"SummationByPartsOperators.jl is mainly written to be useful for both students learning the basic concepts and researchers developing new numerical algorithms based on SBP operators. Thus, this package uses Julia's multiple dispatch and strong type system to provide a unified framework of all of these seemingly different discretizations while being reasonably optimized at the same time, achieving good performance without sacrificing flexibility.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"SummationByPartsOperators.jl is a registered Julia package. Thus, you can install it from the Julia REPL via","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.add(\"SummationByPartsOperators\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you want to update SummationByPartsOperators.jl, you can use","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.update(\"SummationByPartsOperators\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"As usual, if you want to update SummationByPartsOperators.jl and all other packages in your current project, you can execute","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.update()","category":"page"},{"location":"#Basic-examples","page":"Home","title":"Basic examples","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Compute the derivative on a periodic domain using a central finite difference operator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using SummationByPartsOperators\n\njulia> using Plots: plot, plot!\n\njulia> D = periodic_derivative_operator(derivative_order = 1,\n accuracy_order = 2,\n xmin = 0.0, xmax = 2.0,\n N = 20)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 2.0] using 20 nodes,\nstencils with 1 nodes to the left, 1 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> x = grid(D); u = sinpi.(x);\n\njulia> plot(x, D * u, label = \"numerical\")\n\njulia> plot!(x, π .* cospi.(x), label = \"analytical\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"You should see a plot like the following.","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"","page":"Home","title":"Home","text":"Compute the derivative on a bounded domain using an SBP finite difference operator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using SummationByPartsOperators\n\njulia> using Plots: plot, plot!\n\njulia> D = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 21)\nSBP first-derivative operator of order 2 on a grid in [0.0, 1.0] using 21 nodes\nand coefficients of Mattsson, Nordström (2004)\n Summation by parts operators for finite difference approximations of second\n derivatives.\n Journal of Computational Physics 199, pp. 503-540.\n\njulia> x = grid(D); u = exp.(x);\n\njulia> plot(x, D * u, label = \"numerical\")\n\njulia> plot!(x, exp.(x), label = \"analytical\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"You should see a plot like the following.","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"#Referencing","page":"Home","title":"Referencing","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you use SummationByPartsOperators.jl for your research, please cite it using the bibtex entry","category":"page"},{"location":"","page":"Home","title":"Home","text":"@article{ranocha2021sbp,\n title={{SummationByPartsOperators.jl}: {A} {J}ulia library of provably stable\n semidiscretization techniques with mimetic properties},\n author={Ranocha, Hendrik},\n journal={Journal of Open Source Software},\n year={2021},\n month={08},\n doi={10.21105/joss.03454},\n volume={6},\n number={64},\n pages={3454},\n publisher={The Open Journal},\n url={https://github.com/ranocha/SummationByPartsOperators.jl}\n}","category":"page"},{"location":"","page":"Home","title":"Home","text":"Please also cite the appropriate references for specific SBP operators you use, which can be obtained via source_of_coefficients.","category":"page"},{"location":"#License-and-contributing","page":"Home","title":"License and contributing","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This project is licensed under the MIT license (see License). Since it is an open-source project, we are very happy to accept contributions from the community. Please refer to the section Contributing for more details.","category":"page"}] +[{"location":"tutorials/variable_linear_advection/#Linear-advection-equation-with-variable-coefficients","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"","category":"section"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"This tutorial is concerned with the linear advection equation","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"beginaligned\n partial_t u(tx) + partial_x (a(x) u(tx)) = 0 t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \n textboundary conditions x in partial (x_min x_max)\nendaligned","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"with variable coefficient a.","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"The boundary conditions depend on the sign of the transport velocity a at the boundary. In particular, specifying a Dirichlet type boundary condition is only allowed for inflow boundaries, e.g. a(x_min) 0 at x = x_min.","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"SummationByPartsOperators.jl includes a pre-built semidiscretization of this equation: VariableLinearAdvectionNonperiodicSemidiscretization. Have a look at the source code if you want to dig deeper. Below is an example demonstrating how to use this semidiscretization.","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig\n\n# general parameters\nxmin = -1.\nxmax = +1.\ntspan = (0., 8.0)\nafunc(x) = one(x)\nu0func(x) = sinpi(x)\n# Dirichlet type boundary conditions; they are used only at inflow boundaries\nleft_bc(t) = t >= 3 ? sinpi(t) : zero(t)\nright_bc(t) = zero(t)\n\n# discretization parameters\ninterior_order = 4\nN = 101\n# whether a split form should be applied or not\nsplit_form = Val(false)\n\n# setup spatial semidiscretization\nD = derivative_operator(MattssonSvärdShoeybi2008(), 1, interior_order, xmin, xmax, N)\n# whether or not artificial dissipation should be applied: nothing, dissipation_operator(D)\nDi = nothing\nsemi = VariableLinearAdvectionNonperiodicSemidiscretization(D, Di, afunc, split_form, left_bc, right_bc)\node = semidiscretize(u0func, semi, tspan)\n\n# solve ODE\nsol = solve(ode, SSPRK104(), dt=D.Δx, adaptive=false,\n save_everystep=false)\n\n# visualise the result\nplot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], semi), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], semi), label=L\"u_\\mathrm{numerical}\")\nsavefig(\"example_linear_advection.png\");","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"(Image: )","category":"page"},{"location":"tutorials/variable_linear_advection/#Package-versions","page":"Linear advection equation with variable coefficients","title":"Package versions","text":"","category":"section"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/variable_linear_advection/","page":"Linear advection equation with variable coefficients","title":"Linear advection equation with variable coefficients","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"applications/#Applications","page":"Applications & references","title":"Applications","text":"","category":"section"},{"location":"applications/","page":"Applications & references","title":"Applications & references","text":"Here is a (non-exhaustive) list of research using SummationByPartsOperators.jl.","category":"page"},{"location":"applications/","page":"Applications & references","title":"Applications & references","text":"Jesse Chan, Hendrik Ranocha, Andrés M. Rueda-Ramírez, Gregor Gassner, Tim Warburton (2022). On the Entropy Projection and the Robustness of High Order Entropy Stable Discontinuous Galerkin Schemes for Under-Resolved Flows. arXiv: 2203.10238 [math.NA] DOI: 10.3389/fphy.2022.898028 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.6364108\nHendrik Ranocha, Manuel Quezada de Luna, and David I Ketcheson (2021). On the Rate of Error Growth in Time for Numerical Solutions of Nonlinear Dispersive Wave Equations. arXiv: 2102.07376 [math.NA] DOI: 10.1007/s42985-021-00126-3 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.4540467\nHendrik Ranocha, Dimitrios Mitsotakis, and David I Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3908803\nPhilippe G LeFloch and Hendrik Ranocha (2021). Kinetic functions for nonclassical shocks, entropy stability, and discrete summation by parts. DOI: 10.1007/s10915-021-01463-6\nJan Nordström and Hendrik Ranocha (2021). A New Class of A Stable Summation by Parts Time Integration Schemes with Strong Initial Conditions. DOI: 10.1007/s10915-021-01454-7 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3699173\nHendrik Ranocha (2021). On Strong Stability of Explicit Runge-Kutta Methods for Nonlinear Semibounded Operators. DOI: 10.1093/imanum/drz070\nHendrik Ranocha and David I Ketcheson (2020). Energy Stability of Explicit Runge-Kutta Methods for Nonautonomous or Nonlinear Problems. DOI: 10.1137/19M1290346 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3464243\nHendrik Ranocha, Katharina Ostaszewski, and Philip Heinisch (2020). Discrete Vector Calculus and Helmholtz Hodge Decomposition for Classical Finite Difference Summation by Parts Operators. DOI: 10.1007/s42967-019-00057-2 A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.3375170\nHendrik Ranocha and Gregor J Gassner (2020). Preventing pressure oscillations does not fix local linear stability issues of entropy-based split-form high-order schemes. arXiv: 2009.13139 [math.NA] A reproducibility repository containing source code for all numerical experiments is available at DOI: 10.5281/zenodo.4054366\nPhilipp Öffner and Hendrik Ranocha (2019). Error Boundedness of Discontinuous Galerkin Methods with Variable Coefficients. DOI: 10.1007/s10915-018-00902-1","category":"page"},{"location":"applications/","page":"Applications & references","title":"Applications & references","text":"If you use this package for your own research, please cite it as described in the documentation and make a PR to add your work to the list above.","category":"page"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"EditURL = \"https://github.com/ranocha/SummationByPartsOperators.jl/blob/main/CONTRIBUTING.md\"","category":"page"},{"location":"contributing/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"contributing/","page":"Contributing","title":"Contributing","text":"ContributingSummationByPartsOperators.jl is an open-source project and we are very happy to accept contributions from the community. Please feel free to open issues or submit patches (preferably as pull requests) any time. For planned larger contributions, it is often beneficial to get in contact first, for example via issues.SummationByPartsOperators.jl and its contributions are licensed under the MIT license (see License). As a contributor, you certify that all your contributions are in conformance with the Developer Certificate of Origin (Version 1.1), which is reproduced below.Developer Certificate of Origin (Version 1.1)The following text was taken from https://developercertificate.org:Developer Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n1 Letterman Drive\nSuite D4700\nSan Francisco, CA, 94129\n\nEveryone is permitted to copy and distribute verbatim copies of this\nlicense document, but changing it is not allowed.\n\n\nDeveloper's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n have the right to submit it under the open source license\n indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n of my knowledge, is covered under an appropriate open source\n license and I have the right under that license to submit that\n work with modifications, whether created in whole or in part\n by me, under the same open source license (unless I am\n permitted to submit under a different license), as indicated\n in the file; or\n\n(c) The contribution was provided directly to me by some other\n person who certified (a), (b) or (c) and I have not modified\n it.\n\n(d) I understand and agree that this project and the contribution\n are public and that a record of the contribution (including all\n personal information I submit with it, including my sign-off) is\n maintained indefinitely and may be redistributed consistent with\n this project or the open source license(s) involved.","category":"page"},{"location":"tutorials/kdv/#Korteweg-de-Vries-equation","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"","category":"section"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Let's consider the Korteweg-de Vries (KdV) equation","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"beginaligned\n partial_t u(tx) + partial_x fracu(tx)^22 + partial_x^3 u(tx) = 0 t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \nendaligned","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"with periodic boundary conditions. The KdV equation has the quadratic invariant","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":" J = frac12 int u(tx)^2 mathrmdx","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"A classical trick to conserve this invariant is to use following split form","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":" u_t + frac13 (u^2)_x + frac13 u u_x + partial_x^3 u = 0","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Indeed, integration by parts with periodic boundary conditions yields","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"beginaligned\n partial_t J\n =\n int u u_t\n =\n -frac13 int u (u^2)_x - frac13 int u^2 u_x - int u partial_x^3 u\n \n =\n 0 + frac13 int u_x u^2 - frac13 int u^2 u_x + 0\n =\n 0\nendaligned","category":"page"},{"location":"tutorials/kdv/#Basic-example-using-finite-difference-SBP-operators","page":"Korteweg-de Vries equation","title":"Basic example using finite difference SBP operators","text":"","category":"section"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Let's create an appropriate discretization of this equation step by step. At first, we load packages that we will use in this example.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Next, we specify the initial data as Julia function as well as the spatial domain and the time span. Here, we use an analytic soliton solution of the KdV equation for the initial data.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"# traveling wave solution (soliton)\nget_xmin() = 0.0 # left boundary of the domain\nget_xmax() = 80.0 # right boundary of the domain\nget_c() = 2 / 3 # wave speed\nfunction usol(t, x)\n xmin = get_xmin()\n xmax = get_xmax()\n μ = (xmax - xmin) / 2\n c = get_c()\n A = 3 * c\n K = sqrt(1/c - 1)\n x_t = mod(x - c*t - xmin, xmax - xmin) + xmin - μ\n\n A / cosh(sqrt(3*A) / 6 * x_t)^2\nend\n\ntspan = (0.0, (get_xmax() - get_xmin()) / (3 * get_c()) + 10 * (get_xmax() - get_xmin()) / get_c())","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Next, we implement the semidiscretization using the interface of OrdinaryDiffEq.jl which is part of DifferentialEquations.jl. For simplicity, we just use the out-of-place version here since we do not have to worry about appropriate temporary buffers when using automatic differentiation in implicit time integration methods.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"function kdv(u, parameters, t)\n D1 = parameters.D1\n D3 = parameters.D3\n\n # conservative semidiscretization using a split form\n return (-1 / 3) * (u .* (D1 * u) + D1 * (u.^2)) - D3 * u\nend","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Next, we choose first- and third-derivative SBP operators D1, D3, evaluate the initial data on the grid, and set up the semidiscretization as an ODE problem.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"N = 128 # number of grid points\nD1 = periodic_derivative_operator(derivative_order=1, accuracy_order=8,\n xmin=get_xmin(), xmax=get_xmax(), N=N)\nD3 = periodic_derivative_operator(derivative_order=3, accuracy_order=8,\n xmin=get_xmin(), xmax=get_xmax(), N=N)\nu0 = usol.(first(tspan), grid(D1))\nparameters = (; D1, D3)\n\node = ODEProblem(kdv, u0, tspan, parameters);","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Finally, we can solve the ODE using a Rosenbrock method with adaptive time stepping. We use such a linearly implicit time integration method since the third-order derivative makes the system stiff.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"sol = solve(ode, Rodas5(), saveat=range(first(tspan), stop=last(tspan), length=200))\n\nplot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], D1), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], D1), label=L\"u_\\mathrm{numerical}\")\nsavefig(\"example_kdv.png\");","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"(Image: )","category":"page"},{"location":"tutorials/kdv/#Advanced-visualization","page":"Korteweg-de Vries equation","title":"Advanced visualization","text":"","category":"section"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"Let's create an animation of the numerical solution.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"using Printf; using Plots: Animation, frame, gif\n\nlet anim = Animation()\n idx = 1\n x, u = evaluate_coefficients(sol[idx], D1)\n fig = plot(x, u, xguide=L\"x\", yguide=L\"u\", xlim=extrema(x), ylim=(-0.05, 2.05),\n label=\"\", title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n for idx in 1:length(sol.t)\n fig[1] = x, sol.u[idx]\n plot!(title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n frame(anim)\n end\n gif(anim, \"example_kdv.gif\")\nend","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"(Image: example_kdv_animation)","category":"page"},{"location":"tutorials/kdv/#Package-versions","page":"Korteweg-de Vries equation","title":"Package versions","text":"","category":"section"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/kdv/","page":"Korteweg-de Vries equation","title":"Korteweg-de Vries equation","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"tutorials/constant_linear_advection/#Linear-advection-equation-with-constant-coefficients","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"This tutorial is concerned with the basic linear advection equation","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"beginaligned\n partial_t u(tx) + partial_x u(tx) = 0 t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \n u(tx_min) = u_L(t)\nendaligned","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Note that the advection velocity is positive (unity). Thus, a boundary condition needs to be specified exactly at the left boundary. Otherwise, the problem will not be well-posed (under-specified or over-specified).","category":"page"},{"location":"tutorials/constant_linear_advection/#Basic-example-using-finite-difference-SBP-operators","page":"Linear advection equation with constant coefficients","title":"Basic example using finite difference SBP operators","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Let's create an appropriate discretization of this equation step by step. At first, we load packages that we will use in this example.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Next, we specify the initial and boundary data as Julia functions as well as the spatial domain and the time span.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"xmin, xmax = -1.0, 1.0\nu0_func(x) = sinpi(x)\nuL_func(t) = t >= 3 ? sinpi(t) : zero(t)\ntspan = (0., 8.0)","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"This choice of the domain and boundary condition ensures that the initial profile is transported out of the domain before non-homogeneous boundary data influences the solution.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Next, we implement the semidiscretization using the interface of OrdinaryDiffEq.jl which is part of DifferentialEquations.jl.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"function rhs!(du, u, params, t)\n D = params.D\n\n # Set `du = - D * u` using in-place multiplication avoiding allocations\n # for efficiency\n mul!(du, D, u, -one(eltype(D)))\n\n # Next, we impose the boundary conditions weakly using an SAT at the left\n # boundary. Since we use the strong form of the equation, we do not need to\n # do anything at the right boundary.\n # Assuming that boundary nodes are included in the grid, adding this SAT\n # can be achieved by\n du[begin] += (uL_func(t) - u[begin]) / left_boundary_weight(D)\n\n return nothing\nend","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Here, we have used a simultaneous approximation term (SAT) to impose the boundary condition weakly. In general, this approach is related to the weak imposition of boundary conditions using numerical fluxes in finite volume and discontinuous Galerkin methods; they are even equivalent for the linear advection equation considered here.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Next, we choose an SBP operator D, evaluate the initial data on the grid, and set up the semidiscretization as an ODE problem.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"D = derivative_operator(MattssonNordström2004(), derivative_order=1, accuracy_order=4,\n xmin=xmin, xmax=xmax, N=101)\nu0 = compute_coefficients(u0_func, D)\nparams = (D=D, )\node = ODEProblem(rhs!, u0, tspan, params);","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Finally, we can solve the ODE using an explicit Runge-Kutta method with adaptive time stepping.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"sol = solve(ode, Tsit5(), saveat=range(first(tspan), stop=last(tspan), length=200));\n\nplot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], D), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], D), label=L\"u_\\mathrm{numerical}\")\nsavefig(\"example_linear_advection.png\");","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"(Image: )","category":"page"},{"location":"tutorials/constant_linear_advection/#Advanced-visualization","page":"Linear advection equation with constant coefficients","title":"Advanced visualization","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"Let's create an animation of the numerical solution.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"using Printf; using Plots: Animation, frame, gif\n\nlet anim = Animation()\n idx = 1\n x, u = evaluate_coefficients(sol[idx], D)\n fig = plot(x, u, xguide=L\"x\", yguide=L\"u\", xlim=extrema(x), ylim=(-1.05, 1.05),\n label=\"\", title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n for idx in 1:length(sol.t)\n fig[1] = x, sol.u[idx]\n plot!(title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n frame(anim)\n end\n gif(anim, \"example_linear_advection.gif\")\nend","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"(Image: example_linear_advection_animation)","category":"page"},{"location":"tutorials/constant_linear_advection/#Continuous-and-discontinuous-Galerkin-methods","page":"Linear advection equation with constant coefficients","title":"Continuous and discontinuous Galerkin methods","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"You can use a CG or DG method by swapping out the derivative operator D.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"plot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], D), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], D), label=L\"u_\\mathrm{FD}\")\n\n# CGSEM using polynomials of degree 3, i.e. 4 nodes per element, and 30 elements\nD_CGSEM = couple_continuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=4),\n UniformMesh1D(xmin=xmin, xmax=xmax, Nx=30))\node_CGSEM = ODEProblem(rhs!, compute_coefficients(u0_func, D_CGSEM), tspan, (D=D_CGSEM,))\nsol_CGSEM = solve(ode_CGSEM, Tsit5(), save_everystep=false)\nplot!(evaluate_coefficients(sol_CGSEM[end], D_CGSEM), label=L\"u_\\mathrm{CG}\")\n\n# DGSEM using polynomials of degree 3, i.e. 4 nodes per element, and 30 elements\n# which are coupled using upwind fluxes\nD_DGSEM = couple_discontinuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=4),\n UniformMesh1D(xmin=xmin, xmax=xmax, Nx=30),\n Val(:minus))\node_DGSEM = ODEProblem(rhs!, compute_coefficients(u0_func, D_DGSEM), tspan, (D=D_DGSEM,))\nsol_DGSEM = solve(ode_DGSEM, Tsit5(), save_everystep=false)\nplot!(evaluate_coefficients(sol_DGSEM[end], D_DGSEM), label=L\"u_\\mathrm{DG}\")\n\nsavefig(\"example_linear_advection_Galerkin.png\");","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"(Image: )","category":"page"},{"location":"tutorials/constant_linear_advection/#Package-versions","page":"Linear advection equation with constant coefficients","title":"Package versions","text":"","category":"section"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/constant_linear_advection/","page":"Linear advection equation with constant coefficients","title":"Linear advection equation with constant coefficients","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"tutorials/advection_diffusion/#Linear-advection-diffusion-equation-with-periodic-boundary-conditions","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"","category":"section"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Let's consider the linear advection diffusion equation","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"beginaligned\n partial_t u(tx) + a partial_x u(tx) = varepsilon partial_x^2 u(tx) t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \nendaligned","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"with periodic boundary conditions. Here, a is the constant advection velocity and ε > 0 is the constant diffusion coefficient.","category":"page"},{"location":"tutorials/advection_diffusion/#Basic-example-using-finite-difference-SBP-operators","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Basic example using finite difference SBP operators","text":"","category":"section"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Let's create an appropriate discretization of this equation step by step. At first, we load packages that we will use in this example.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Next, we specify the initial data as Julia function as well as the spatial domain and the time span.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"xmin, xmax = -1.0, 1.0\nu0_func(x) = sinpi(x)\ntspan = (0., 10.0)","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Next, we implement the semidiscretization using the interface of OrdinaryDiffEq.jl which is part of DifferentialEquations.jl.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"function advection_diffusion!(du, u, params, t)\n # In-place version of du = -a * D1 * u\n mul!(du, params.D1, u, -params.a)\n # In-place version of du = du + ε * D2 * u\n mul!(du, params.D2, u, params.ε, true)\nend","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Next, we choose first- and second-derivative SBP operators D1, D2, evaluate the initial data on the grid, and set up the semidiscretization as an ODE problem.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"N = 100 # number of grid points\nD1 = periodic_derivative_operator(derivative_order=1, accuracy_order=4,\n xmin=xmin, xmax=xmax, N=N)\nD2 = periodic_derivative_operator(derivative_order=2, accuracy_order=4,\n xmin=xmin, xmax=xmax, N=N)\nu0 = u0_func.(grid(D1))\nparams = (D1=D1, D2=D2, a=1.0, ε=0.03)\node = ODEProblem(advection_diffusion!, u0, tspan, params);","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Finally, we can solve the ODE using an explicit Runge-Kutta method with adaptive time stepping.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"sol = solve(ode, Tsit5(), saveat=range(first(tspan), stop=last(tspan), length=200));\n\nplot(xguide=L\"x\", yguide=L\"u\")\nplot!(evaluate_coefficients(sol[1], D1), label=L\"u_0\")\nplot!(evaluate_coefficients(sol[end], D1), label=L\"u_\\mathrm{numerical}\")\nsavefig(\"example_advection_diffusion.png\");","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"(Image: )","category":"page"},{"location":"tutorials/advection_diffusion/#Advanced-visualization","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Advanced visualization","text":"","category":"section"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"Let's create an animation of the numerical solution.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"using Printf; using Plots: Animation, frame, gif\n\nlet anim = Animation()\n idx = 1\n x, u = evaluate_coefficients(sol[idx], D1)\n fig = plot(x, u, xguide=L\"x\", yguide=L\"u\", xlim=extrema(x), ylim=(-1.05, 1.05),\n label=\"\", title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n for idx in 1:length(sol.t)\n fig[1] = x, sol.u[idx]\n plot!(title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n frame(anim)\n end\n gif(anim, \"example_advection_diffusion.gif\")\nend","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"(Image: example_advection_diffusion_animation)","category":"page"},{"location":"tutorials/advection_diffusion/#Package-versions","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Package versions","text":"","category":"section"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/advection_diffusion/","page":"Linear advection diffusion equation with periodic boundary conditions","title":"Linear advection diffusion equation with periodic boundary conditions","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"benchmarks/#Benchmarks","page":"Benchmarks","title":"Benchmarks","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Here are some simple benchmarks. Take them with a grain of salt since they run on virtual machines in the cloud to generate the documentation automatically.","category":"page"},{"location":"benchmarks/#First-derivative-operators","page":"Benchmarks","title":"First-derivative operators","text":"","category":"section"},{"location":"benchmarks/#Periodic-domains","page":"Benchmarks","title":"Periodic domains","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Let's set up some benchmark code.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using BenchmarkTools\nusing LinearAlgebra, SparseArrays\nusing SummationByPartsOperators, DiffEqOperators\n\nBLAS.set_num_threads(1) # make sure that BLAS is serial to be fair\n\nT = Float64\nxmin, xmax = T(0), T(1)\n\nD_SBP = periodic_derivative_operator(derivative_order=1, accuracy_order=2,\n xmin=xmin, xmax=xmax, N=100)\nx = grid(D_SBP)\nD_DEO = CenteredDifference(derivative_order(D_SBP), accuracy_order(D_SBP),\n step(x), length(x)) * PeriodicBC(eltype(D_SBP))\n\nD_sparse = sparse(D_SBP)\n\nu = randn(eltype(D_SBP), length(x)); du = similar(u);\n@show D_SBP * u ≈ D_DEO * u ≈ D_sparse * u\n\nfunction doit(D, text, du, u)\n println(text)\n sleep(0.1)\n show(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D, $u))\n println()\nend","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"First, we benchmark the implementation from SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_SBP, \"D_SBP:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Next, we compare this to the runtime obtained using a sparse matrix representation of the derivative operator. Depending on the hardware etc., this can be an order of magnitude slower than the optimized implementation from SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_sparse, \"D_sparse:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Finally, we benchmark the implementation of the same derivative operator in DiffEqOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_DEO, \"D_DEO:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"These results were obtained using the following versions.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"DiffEqOperators\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"benchmarks/#Bounded-domains","page":"Benchmarks","title":"Bounded domains","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"We start again by setting up some benchmark code.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using BenchmarkTools\nusing LinearAlgebra, SparseArrays\nusing SummationByPartsOperators, BandedMatrices\n\nBLAS.set_num_threads(1) # make sure that BLAS is serial to be fair\n\nT = Float64\nxmin, xmax = T(0), T(1)\n\nD_SBP = derivative_operator(MattssonNordström2004(), derivative_order=1,\n accuracy_order=6, xmin=xmin, xmax=xmax, N=10^3)\nD_sparse = sparse(D_SBP)\nD_banded = BandedMatrix(D_SBP)\n\nu = randn(eltype(D_SBP), size(D_SBP, 1)); du = similar(u);\n@show D_SBP * u ≈ D_sparse * u ≈ D_banded * u\n\nfunction doit(D, text, du, u)\n println(text)\n sleep(0.1)\n show(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D, $u))\n println()\nend","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"First, we benchmark the implementation from SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_SBP, \"D_SBP:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Again, we compare this to a representation of the derivative operator as a sparse matrix. No surprise - it is again much slower, as in periodic domains.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_sparse, \"D_sparse:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"FInally, we compare it to a representation as banded matrix. Disappointingly, this is still much slower than the optimized implementation from SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_banded, \"D_banded:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"These results were obtained using the following versions.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"BandedMatrices\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"benchmarks/#Dissipation-operators","page":"Benchmarks","title":"Dissipation operators","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"We follow the same structure as before. At first, we set up some benchmark code.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using BenchmarkTools\nusing LinearAlgebra, SparseArrays\nusing SummationByPartsOperators, BandedMatrices\n\nBLAS.set_num_threads(1) # make sure that BLAS is serial to be fair\n\nT = Float64\nxmin, xmax = T(0), T(1)\n\nD_SBP = derivative_operator(MattssonNordström2004(), derivative_order=1,\n accuracy_order=6, xmin=xmin, xmax=xmax, N=10^3)\nDi_SBP = dissipation_operator(MattssonSvärdNordström2004(), D_SBP)\nDi_sparse = sparse(Di_SBP)\nDi_banded = BandedMatrix(Di_SBP)\nDi_full = Matrix(Di_SBP)\n\nu = randn(eltype(D_SBP), size(D_SBP, 1)); du = similar(u);\n@show Di_SBP * u ≈ Di_sparse * u ≈ Di_banded * u ≈ Di_full * u\n\nfunction doit(D, text, du, u)\n println(text)\n sleep(0.1)\n show(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D, $u))\n println()\nend","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"At first, let us benchmark the derivative and dissipation operators implemented in SummationByPartsOperators.jl.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(D_SBP, \"D_SBP:\", du, u)\ndoit(Di_SBP, \"Di_SBP:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Next, we compare the results to sparse matrix representations. It will not come as a surprise that these are again much (around an order of magnitude) slower.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(Di_sparse, \"Di_sparse:\", du, u)\ndoit(Di_banded, \"Di_banded:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Finally, let's benchmark the same computation if a full (dense) matrix is used to represent the derivative operator. This is obviously a bad idea but 🤷","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"doit(Di_full, \"Di_full:\", du, u)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"These results were obtained using the following versions.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"BandedMatrices\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"benchmarks/#Structure-of-Arrays-(SoA)-and-Array-of-Structures-(AoS)","page":"Benchmarks","title":"Structure-of-Arrays (SoA) and Array-of-Structures (AoS)","text":"","category":"section"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"SummationByPartsOperators.jl tries to provide efficient support of","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"StaticVectors from StaticArrays.jl\nStructArrays.jl","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"To demonstrate this, let us set up some benchmark code.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using BenchmarkTools\nusing StaticArrays, StructArrays\nusing LinearAlgebra, SparseArrays\nusing SummationByPartsOperators\n\nBLAS.set_num_threads(1) # make sure that BLAS is serial to be fair\n\nstruct Vec5{T} <: FieldVector{5,T}\n x1::T\n x2::T\n x3::T\n x4::T\n x5::T\nend\n\n# Apply `mul!` to each component of a plain array of structures one after another\nfunction mul_aos!(du, D, u, args...)\n for i in 1:size(du, 1)\n mul!(view(du, i, :), D, view(u, i, :), args...)\n end\nend\n\nT = Float64\nxmin, xmax = T(0), T(1)\n\nD_SBP = derivative_operator(MattssonNordström2004(), derivative_order=1,\n accuracy_order=4, xmin=xmin, xmax=xmax, N=101)\nD_sparse = sparse(D_SBP)\nD_full = Matrix(D_SBP)","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"At first, we benchmark the application of the operators implemented in SummationByPartsOperators.jl and their representations as sparse and dense matrices in the scalar case. As before, the sparse matrix representation is around an order of magnitude slower and the dense matrix representation is far off.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Scalar case\")\nu = randn(T, size(D_SBP, 1)); du = similar(u)\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D_SBP, $u))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D_sparse, $u))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du, $D_full, $u))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Next, we use a plain array of structures (AoS) in the form of a two-dimensional array and our custom mul_aos! implementation that loops over each component, using mul! on views. Here, the differences between the timings are less pronounced.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Plain Array of Structures\")\nu_aos_plain = randn(T, 5, size(D_SBP, 1)); du_aos_plain = similar(u_aos_plain)\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul_aos!($du_aos_plain, $D_SBP, $u_aos_plain))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul_aos!($du_aos_plain, $D_sparse, $u_aos_plain))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul_aos!($du_aos_plain, $D_full, $u_aos_plain))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Now, we use an array of structures (AoS) based on reinterpret and standard mul!. This is much more efficient for the implementation in SummationByPartsOperators.jl. In Julia v1.6, this is also more efficient for sparse matrices but less efficient for dense matrices (compared to the plain AoS approach with mul_aos! above).","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Array of Structures (reinterpreted array)\")\nu_aos_r = reinterpret(reshape, Vec5{T}, u_aos_plain); du_aos_r = similar(u_aos_r)\n@show D_SBP * u_aos_r ≈ D_sparse * u_aos_r ≈ D_full * u_aos_r\nmul!(du_aos_r, D_SBP, u_aos_r)\n@show reinterpret(reshape, T, du_aos_r) ≈ du_aos_plain\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos_r, $D_SBP, $u_aos_r))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos_r, $D_sparse, $u_aos_r))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos_r, $D_full, $u_aos_r))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Next, we still use an array of structures (AoS), but copy the data into a plain Array instead of using the reinterpreted versions. There is no significant difference to the previous version in this case.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Array of Structures\")\nu_aos = Array(u_aos_r); du_aos = similar(u_aos)\n@show D_SBP * u_aos ≈ D_sparse * u_aos ≈ D_full * u_aos\nmul!(du_aos, D_SBP, u_aos)\n@show du_aos ≈ du_aos_r\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos, $D_SBP, $u_aos))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos, $D_sparse, $u_aos))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_aos, $D_full, $u_aos))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"Finally, let's look at a structure of arrays (SoA). Interestingly, this is slower than the array of structures we used above. On Julia v1.6, the sparse matrix representation performs particularly bad in this case.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"println(\"Structure of Arrays\")\nu_soa = StructArray(u_aos); du_soa = similar(u_soa)\n@show D_SBP * u_soa ≈ D_sparse * u_soa ≈ D_full * u_soa\nmul!(du_soa, D_SBP, u_soa)\n@show du_soa ≈ du_aos\nprintln(\"D_SBP\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_soa, $D_SBP, $u_soa))\nprintln(\"\\nD_sparse\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_soa, $D_sparse, $u_soa))\nprintln(\"\\nD_full\")\nshow(stdout, MIME\"text/plain\"(), @benchmark mul!($du_soa, $D_full, $u_soa))","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"These results were obtained using the following versions.","category":"page"},{"location":"benchmarks/","page":"Benchmarks","title":"Benchmarks","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"StaticArrays\", \"StructArrays\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"code_of_conduct/","page":"Code of conduct","title":"Code of conduct","text":"EditURL = \"https://github.com/ranocha/SummationByPartsOperators.jl/blob/main/CODE_OF_CONDUCT.md\"","category":"page"},{"location":"code_of_conduct/#code-of-conduct","page":"Code of conduct","title":"Code of Conduct","text":"","category":"section"},{"location":"code_of_conduct/","page":"Code of conduct","title":"Code of conduct","text":"Contributor Covenant Code of ConductOur PledgeWe as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.Our StandardsExamples of behavior that contributes to a positive environment for our community include:Demonstrating empathy and kindness toward other people\nBeing respectful of differing opinions, viewpoints, and experiences\nGiving and gracefully accepting constructive feedback\nAccepting responsibility and apologizing to those affected by our mistakes, and learning from the experience\nFocusing on what is best not just for us as individuals, but for the overall communityExamples of unacceptable behavior include:The use of sexualized language or imagery, and sexual attention or advances of any kind\nTrolling, insulting or derogatory comments, and personal or political attacks\nPublic or private harassment\nPublishing others' private information, such as a physical or email address, without their explicit permission\nOther conduct which could reasonably be considered inappropriate in a professional settingEnforcement ResponsibilitiesCommunity leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.ScopeThis Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.EnforcementInstances of abusive, harassing, or otherwise unacceptable behavior may be reported to Hendrik Ranocha. All complaints will be reviewed and investigated promptly and fairly.All community leaders are obligated to respect the privacy and security of the reporter of any incident.Enforcement GuidelinesCommunity leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:1. CorrectionCommunity Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.2. WarningCommunity Impact: A violation through a single incident or series of actions.Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.3. Temporary BanCommunity Impact: A serious violation of community standards, including sustained inappropriate behavior.Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.4. Permanent BanCommunity Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.Consequence: A permanent ban from any sort of public interaction within the community.AttributionThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/codeofconduct.html.Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.[homepage]: https://www.contributor-covenant.orgFor answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.","category":"page"},{"location":"api_reference/#SummationByPartsOperators.jl-API","page":"API reference","title":"SummationByPartsOperators.jl API","text":"","category":"section"},{"location":"api_reference/","page":"API reference","title":"API reference","text":"CurrentModule = SummationByPartsOperators","category":"page"},{"location":"api_reference/","page":"API reference","title":"API reference","text":"Modules = [SummationByPartsOperators]","category":"page"},{"location":"api_reference/#SummationByPartsOperators.SummationByPartsOperators","page":"API reference","title":"SummationByPartsOperators.SummationByPartsOperators","text":"SummationByPartsOperators\n\nSummationByPartsOperators.jl is a Julia library of summation-by-parts (SBP) operators, which are discrete derivative operators developed to get provably stable semidiscretizations, paying special attention to boundary conditions. Discretizations included in this framework are finite difference, Fourier pseudospectral, continuous Galerkin, and discontinuous Galerkin methods. The main aim of SummationByPartsOperators.jl is to be useful for researchers and students to learn the basic concepts by providing a unified framework of all of these seemingly different discretizations. At the same time, the implementation is optimized to achieve good performance without sacrificing flexibility.\n\nCheck out the documentation for further information. Some noticeable functions to start with are derivative_operator, legendre_derivative_operator, periodic_derivative_operator, fourier_derivative_operator, dissipation_operator, and grid.\n\nIf you use this package for your research, please cite it using\n\n@article{ranocha2021sbp,\n title={{SummationByPartsOperators.jl}: {A} {J}ulia library of provably stable\n semidiscretization techniques with mimetic properties},\n author={Ranocha, Hendrik},\n journal={Journal of Open Source Software},\n year={2021},\n month={08},\n doi={10.21105/joss.03454},\n volume={6},\n number={64},\n pages={3454},\n publisher={The Open Journal},\n url={https://github.com/ranocha/SummationByPartsOperators.jl}\n}\n\n\n\n\n\n","category":"module"},{"location":"api_reference/#SummationByPartsOperators.BeljaddLeFlochMishraParés2017","page":"API reference","title":"SummationByPartsOperators.BeljaddLeFlochMishraParés2017","text":"BeljaddLeFlochMishraParés2017()\n\nCoefficients of the periodic operators given in\n\nBeljadid, LeFloch, Mishra, Parés (2017) Schemes with Well-Controlled Dissipation. Hyperbolic Systems in Nonconservative Form. Communications in Computational Physics 21.4, pp. 913-946.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.BurgersNonperiodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.BurgersNonperiodicSemidiscretization","text":"BurgersNonperiodicSemidiscretization(D, Di, split_form, left_bc, right_bc)\n\nA semidiscretization of Burgers' equation partial_t u(tx) + partial_x fracu(tx)^22 = 0 with boundary conditions left_bc(t), right_bc(t).\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.BurgersPeriodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.BurgersPeriodicSemidiscretization","text":"BurgersPeriodicSemidiscretization(D, Di, split_form)\n\nA semidiscretization of Burgers' equation partial_t u(tx) + partial_x fracu(tx)^22 = 0 with periodic boundary conditions.\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.ConstantFilter","page":"API reference","title":"SummationByPartsOperators.ConstantFilter","text":"ConstantFilter\n\nRepresents the action of a modal filter on values in a nodal basis with fixed strength.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.ConstantFilter-Union{Tuple{T}, Tuple{FourierDerivativeOperator{T, Grid, RFFT, BRFFT} where {Grid, RFFT, BRFFT}, Any}} where T","page":"API reference","title":"SummationByPartsOperators.ConstantFilter","text":"ConstantFilter(D::FourierDerivativeOperator, filter)\n\nCreate a modal filter with constant parameters adapted to the Fourier derivative operator D with parameters given by the filter function filter.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.ConstantFilter-Union{Tuple{T}, Tuple{LegendreDerivativeOperator{T}, Any}, Tuple{LegendreDerivativeOperator{T}, Any, Any}} where T","page":"API reference","title":"SummationByPartsOperators.ConstantFilter","text":"ConstantFilter(D::LegendreDerivativeOperator, filter, TmpEltype=T)\n\nCreate a modal filter with constant parameters adapted to the Legendre derivative operator D with parameters given by the filter function filter.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.CubicNonperiodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.CubicNonperiodicSemidiscretization","text":"CubicNonperiodicSemidiscretization(D, Di, split_form, left_bc, right_bc)\n\nA semidiscretization of the cubic conservation law partial_t u(tx) + partial_x u(tx)^3 = 0 with nonperiodic boundary conditions left_bc(t), right_bc(t).\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.CubicPeriodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.CubicPeriodicSemidiscretization","text":"CubicPeriodicSemidiscretization(D, Di, split_form)\n\nA semidiscretization of the cubic conservation law partial_t u(tx) + partial_x u(tx)^3 = 0 with periodic boundary conditions.\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DerivativeCoefficientRow","page":"API reference","title":"SummationByPartsOperators.DerivativeCoefficientRow","text":"DerivativeCoefficientRow{T,Start,Length}\n\nA struct representing a row in the boundary block of an SBP derivative operator with scalar type T.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DerivativeCoefficients","page":"API reference","title":"SummationByPartsOperators.DerivativeCoefficients","text":"DerivativeCoefficients\n\nThe coefficients of a derivative operator on a nonperiodic grid.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DerivativeOperator","page":"API reference","title":"SummationByPartsOperators.DerivativeOperator","text":"DerivativeOperator\n\nA derivative operator on a nonperiodic finite difference grid. See derivative_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DienerDorbandSchnetterTiglio2007","page":"API reference","title":"SummationByPartsOperators.DienerDorbandSchnetterTiglio2007","text":"DienerDorbandSchnetterTiglio2007()\n\nCoefficients of the SBP operators given in\n\nDiener, Dorband, Schnetter, Tiglio (2007) Optimized high-order derivative and dissipation operators satisfying summation by parts, and applications in three-dimensional multi-block evolutions. Journal of Scientific Computing 32.1, pp. 109-145.\n\nSee also (second- and fourth-order operators)\n\nMattsson, Nordström (2004) Summation by parts operators for finite difference approximations of second derivatives. Journal of Computational Physics 199, pp. 503-540.\n\nThe dissipation operators proposed by Diener, Dorband, Schnetter, Tiglio (2007) for the diagonal-norm operators are the same as the ones of\n\nMattsson, Svärd, Nordström (2004) Stable and Accurate Artificial Dissipation. Journal of Scientific Computing 21.1, pp. 57-79.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.DissipationOperator","page":"API reference","title":"SummationByPartsOperators.DissipationOperator","text":"DissipationOperator\n\nA dissipation operator on a nonperiodic finite difference grid. See dissipation_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.ExponentialFilter","page":"API reference","title":"SummationByPartsOperators.ExponentialFilter","text":"ExponentialFilter\n\nRepresents the exponential filter function σ(η) = exp(-α*η^p).\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FactorisationWrapper","page":"API reference","title":"SummationByPartsOperators.FactorisationWrapper","text":"FactorisationWrapper\n\nA small wrapper around a a factorisation fact, allowing to represent multiplication by the inverse of fact.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FastMode","page":"API reference","title":"SummationByPartsOperators.FastMode","text":"FastMode()\n\nA (probably) faster execution mode that might depend on packages such as LoopVectorization.jl.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Fornberg1998","page":"API reference","title":"SummationByPartsOperators.Fornberg1998","text":"Fornberg1998()\n\nCoefficients of the periodic operators given in\n\nFornberg (1998) Calculation of Weights in Finite Difference Formulas. SIAM Rev. 40.3, pp. 685-691.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FourierConstantViscosity","page":"API reference","title":"SummationByPartsOperators.FourierConstantViscosity","text":"FourierConstantViscosity\n\nFourier viscosity operator with constant coefficients for the periodic 1st derivative Fourier operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FourierDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.FourierDerivativeOperator","text":"FourierDerivativeOperator{T}\n\nA derivative operator on a periodic grid with real scalar type T computing the first derivative using a spectral Fourier expansion via real discrete Fourier transforms.\n\nSee also fourier_derivative_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FourierDerivativeOperator-Union{Tuple{T}, Tuple{T, T, Integer}} where T<:Real","page":"API reference","title":"SummationByPartsOperators.FourierDerivativeOperator","text":"FourierDerivativeOperator(xmin::T, xmax::T, N::Integer) where {T<:Real}\n\nConstruct the FourierDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N÷2+1 complex Fourier modes.\n\nSee also fourier_derivative_operator.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.FourierDerivativeOperator2D","page":"API reference","title":"SummationByPartsOperators.FourierDerivativeOperator2D","text":"FourierDerivativeOperator2D{T<:Real}\n\nA derivative operator on a two-dimensional periodic grid with scalar type T computing the first derivatives using a spectral Fourier expansion via real discrete Fourier transforms.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.FourierDerivativeOperator2D-Union{Tuple{T}, Tuple{T, T, Int64, T, T, Int64}} where T<:Real","page":"API reference","title":"SummationByPartsOperators.FourierDerivativeOperator2D","text":"FourierDerivativeOperator2D(xmin, xmax, Nx, ymin, ymax, Ny)\n\nConstruct the FourierDerivativeOperator on a uniform grid between xmin and xmax using Nx nodes and ymin and ymax using Ny nodes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.GlaubitzNordströmÖffner2023","page":"API reference","title":"SummationByPartsOperators.GlaubitzNordströmÖffner2023","text":"GlaubitzNordströmÖffner2023()\n\nFunction space SBP (FSBP) operators given in\n\nGlaubitz, Nordström, Öffner (2023) Summation-by-parts operators for general function spaces. SIAM Journal on Numerical Analysis 61, 2, pp. 733-754.\n\nSee also\n\nGlaubitz, Nordström, Öffner (2024) An optimization-based construction procedure for function space based summation-by-parts operators on arbitrary grids. arXiv, arXiv:2405.08770v1.\n\nSee function_space_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Holoborodko2008","page":"API reference","title":"SummationByPartsOperators.Holoborodko2008","text":"Holoborodko2008()\n\nCoefficients of the periodic operators given in\n\nHoloborodko (2008) Smooth Noise Robust Differentiators. http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.LegendreDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.LegendreDerivativeOperator","text":"LegendreDerivativeOperator{T<:Real}\n\nA derivative operator on a nonperiodic Lobatto-Legendre grid with scalar type T computing the first derivative using a Legendre expansion.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.LegendreDerivativeOperator-Union{Tuple{T}, Tuple{T, T, Int64}} where T<:Real","page":"API reference","title":"SummationByPartsOperators.LegendreDerivativeOperator","text":"LegendreDerivativeOperator(xmin::T, xmax::T, N::Int) where {T<:Real}\n\nConstruct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.LegendreSecondDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.LegendreSecondDerivativeOperator","text":"LegendreSecondDerivativeOperator{T<:Real}\n\nA derivative operator on a nonperiodic Lobatto-Legendre grid with scalar type T computing the second derivative using a Legendre expansion.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.LinearlyCombinedDerivativeOperators","page":"API reference","title":"SummationByPartsOperators.LinearlyCombinedDerivativeOperators","text":"LinearlyCombinedDerivativeOperators\n\nForm linear combinations of several derivative operators lazily.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MadayTadmor1989","page":"API reference","title":"SummationByPartsOperators.MadayTadmor1989","text":"MadayTadmor1989()\n\nCoefficients of the Fourier spectral viscosity given in\n\nMaday, Tadmor (1989) Analysis of the Spectral Vanishing Viscosity Method for Periodic Conservation Laws. SIAM Journal on Numerical Analysis 26.4, pp. 854-870.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MatrixDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.MatrixDerivativeOperator","text":"MatrixDerivativeOperator{T <: Real}\nMatrixDerivativeOperator(xmin, xmax, nodes, weights, D, accuracy_order, source)\n\nA derivative operator on a nonperiodic grid with scalar type T computing a derivative as matrix vector product. This type is designed to make it easy to experiment with new operators given in matrix form.\n\nAn instance of this type can be constructed by passing the endpoints xmin, xmax of the desired grid as well as the nodes, weights, and the derivative operator D::Matrix on a reference interval, assuming that the nodes contain the boundary points of the reference interval. source is the source of coefficients and can be nothing for experimentation.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Mattsson2012","page":"API reference","title":"SummationByPartsOperators.Mattsson2012","text":"Mattsson2012()\n\nCoefficients of the SBP operators given in\n\nMattsson (2012) Summation by Parts Operators for Finite Difference Approximations of Second-Derivatives with Variable Coefficients. Journal of Scientific Computing 51, pp. 650-682.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Mattsson2014","page":"API reference","title":"SummationByPartsOperators.Mattsson2014","text":"Mattsson2014()\n\nCoefficients of the SBP operators given in\n\nMattsson (2014) Diagonal-norm summation by parts operators for finite difference approximations of third and fourth derivatives. Journal of Computational Physics 274, pp. 432-454.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Mattsson2017","page":"API reference","title":"SummationByPartsOperators.Mattsson2017","text":"Mattsson2017(version::Symbol)\n\nCoefficients of the upwind SBP operators given in\n\nMattsson (2017) Diagonal-norm upwind SBP operators. Journal of Computational Physics 335, pp. 283-310.\n\nYou can choose between the different versions :central, :plus, and :minus.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonAlmquistCarpenter2014Extended","page":"API reference","title":"SummationByPartsOperators.MattssonAlmquistCarpenter2014Extended","text":"MattssonAlmquistCarpenter2014Extended()\n\nCoefficients of the extended SBP operators given in\n\nMattsson, Almquist, Carpenter (2014) Optimal diagonal-norm SBP operators. Journal of Computational Physics 264, pp. 91-111.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonAlmquistCarpenter2014Optimal","page":"API reference","title":"SummationByPartsOperators.MattssonAlmquistCarpenter2014Optimal","text":"MattssonAlmquistCarpenter2014Optimal()\n\nCoefficients of the optimal SBP operators with nonuniform grid given in\n\nMattsson, Almquist, Carpenter (2014) Optimal diagonal-norm SBP operators. Journal of Computational Physics 264, pp. 91-111.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonAlmquistVanDerWeide2018Accurate","page":"API reference","title":"SummationByPartsOperators.MattssonAlmquistVanDerWeide2018Accurate","text":"MattssonAlmquistVanDerWeide2018Accurate()\n\nCoefficients of the optimized SBP operators with nonuniform grid given in\n\nMattsson, Almquist, van der Weide (2018) Boundary optimized diagonal-norm SBP operators. Journal of Computational Physics 374, pp. 1261-1266.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonAlmquistVanDerWeide2018Minimal","page":"API reference","title":"SummationByPartsOperators.MattssonAlmquistVanDerWeide2018Minimal","text":"MattssonAlmquistVanDerWeide2018Minimal()\n\nCoefficients of the optimized SBP operators with nonuniform grid given in\n\nMattsson, Almquist, van der Weide (2018) Boundary optimized diagonal-norm SBP operators. Journal of Computational Physics 374, pp. 1261-1266.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonNordström2004","page":"API reference","title":"SummationByPartsOperators.MattssonNordström2004","text":"MattssonNordström2004()\n\nCoefficients of the SBP operators given in\n\nMattsson, Nordström (2004) Summation by parts operators for finite difference approximations of second derivatives. Journal of Computational Physics 199, pp. 503-540.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonSvärdNordström2004","page":"API reference","title":"SummationByPartsOperators.MattssonSvärdNordström2004","text":"MattssonSvärdNordström2004()\n\nCoefficients of the SBP operators given in\n\nMattsson, Svärd, Nordström (2004) Stable and Accurate Artificial Dissipation. Journal of Scientific Computing 21.1, pp. 57-79.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.MattssonSvärdShoeybi2008","page":"API reference","title":"SummationByPartsOperators.MattssonSvärdShoeybi2008","text":"MattssonSvärdShoeybi2008()\n\nCoefficients of the SBP operators given in\n\nMattsson, Svärd, Shoeybi (2008) Stable and accurate schemes for the compressible Navier-Stokes equations. Journal of Computational Physics 227, pp. 2293-2316.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.PeriodicDerivativeCoefficients","page":"API reference","title":"SummationByPartsOperators.PeriodicDerivativeCoefficients","text":"PeriodicDerivativeCoefficients\n\nThe coefficients of a derivative operator on a periodic grid.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.PeriodicDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.PeriodicDerivativeOperator","text":"PeriodicDerivativeOperator\n\nA derivative operator on a uniform periodic grid. See periodic_derivative_operator and periodic_central_derivative_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.PeriodicDissipationOperator","page":"API reference","title":"SummationByPartsOperators.PeriodicDissipationOperator","text":"PeriodicDissipationOperator\n\nA dissipation operator on a periodic finite difference grid. See dissipation_operator.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.PeriodicUpwindOperators","page":"API reference","title":"SummationByPartsOperators.PeriodicUpwindOperators","text":"PeriodicUpwindOperators\nPeriodicUpwindOperators(D_minus, D_central, D_plus)\n\nA struct bundling the individual operators available for periodic upwind SBP operators. The individual operators are available as D.minus, D.plus (and optionally D.central, if provided), where D::PeriodicUpwindOperators.\n\nThe combined struct behaves as much as possible as an operator itself as long as no ambiguities arise. For example, upwind operators need to use the same grid and mass matrix, so mass_matrix, grid, xmin, xmax etc. are available but mul! is not.\n\nIt is recommended to construct an instance of PeriodicUpwindOperators using upwind_operators. An instance can also be constructed manually by passing the operators in the order D_minus, D_central, D_plus.\n\nSee also upwind_operators, UpwindOperators\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.QuarticNonconvexPeriodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.QuarticNonconvexPeriodicSemidiscretization","text":"QuarticNonconvexPeriodicSemidiscretization(D, Di, split_form)\n\nA semidiscretization of the quartic nonconvex conservation law partial_t u(tx) + partial_x ( u(tx)^4 - 10 u(tx)^2 + 3 u(tx) ) = 0 with periodic boundary conditions.\n\nD is a first-derivative SBP operator, Di an associated dissipation operator or nothing, and split_form::Union{Val(true), Val(false)} determines whether the canonical split form or the conservative form is used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.SafeMode","page":"API reference","title":"SummationByPartsOperators.SafeMode","text":"SafeMode()\n\nA safe execution mode relying only on basic functionality of Julia.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.SharanBradyLivescu2022","page":"API reference","title":"SummationByPartsOperators.SharanBradyLivescu2022","text":"SharanBradyLivescu2022(alpha_left, alpha_right)\n\nCoefficients of the cut-cell SBP operators given in\n\nSharan, Brady, Livescu (2022) High-order dimensionally-split Cartesian embedded boundary method for non-dissipative schemes. Journal of Computational Physics 464, 111341.\n\nHere, alpha_left * Δx is the spacing between the left endpoint and the second node, while alpha_right * Δx is the spacing between the right endpoint and the last node.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.SourceOfCoefficients","page":"API reference","title":"SummationByPartsOperators.SourceOfCoefficients","text":"SourceOfCoefficients\n\nAll sources of coefficients (articles) are subtypes of this abstract type.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Tadmor1989","page":"API reference","title":"SummationByPartsOperators.Tadmor1989","text":"Tadmor1989()\n\nCoefficients of the Fourier spectral viscosity given in\n\nTadmor (1989) Convergence of Spectral Methods for Nonlinear Conservation Laws. SIAM Journal on Numerical Analysis 26.1, pp. 30-44.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.Tadmor1993","page":"API reference","title":"SummationByPartsOperators.Tadmor1993","text":"Tadmor1993()\n\nCoefficients of the Fourier super spectral viscosity given in\n\nTadmor (1993) Super Viscosity and Spectral Approximations of Nonlinear Conservation Laws. Numerical Methods for Fluid Dynamics IV, pp. 69-82.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.TadmorWaagan2012Convergent","page":"API reference","title":"SummationByPartsOperators.TadmorWaagan2012Convergent","text":"TadmorWaagan2012Convergent()\n\nCoefficients of the Fourier spectral viscosity given in\n\nTadmor, Waagan (2012) Adaptive Spectral Viscosity for Hyperbolic Conservation Laws. SIAM Journal on Scientific Computing 34.2, pp. A993-A1009.\n\nSee also\n\nSchochet (1990) The Rate of Convergence of Spectral-Viscosity Methods for Periodic Scalar Conservation Laws. SIAM Journal on Numerical Analysis 27.5, pp. 1142-1159.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.TadmorWaagan2012Standard","page":"API reference","title":"SummationByPartsOperators.TadmorWaagan2012Standard","text":"TadmorWaagan2012Standard()\n\nCoefficients of the Fourier spectral viscosity given in\n\nTadmor, Waagan (2012) Adaptive Spectral Viscosity for Hyperbolic Conservation Laws. SIAM Journal on Scientific Computing 34.2, pp. A993-A1009.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.ThreadedMode","page":"API reference","title":"SummationByPartsOperators.ThreadedMode","text":"ThreadedMode()\n\nAn execution mode using multiple threads and possibly further optimizations, cf. FastMode.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.UniformMesh1D","page":"API reference","title":"SummationByPartsOperators.UniformMesh1D","text":"UniformMesh1D(xmin::Real, xmax::Real, Nx::Integer)\nUniformMesh1D(; xmin::Real, xmax::Real, Nx::Integer)\n\nA uniform mesh in one space dimension of Nx cells between xmin and xmax.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.UniformPeriodicMesh1D","page":"API reference","title":"SummationByPartsOperators.UniformPeriodicMesh1D","text":"UniformPeriodicMesh1D(xmin::Real, xmax::Real, Nx::Integer)\nUniformPeriodicMesh1D(; xmin::Real, xmax::Real, Nx::Integer)\n\nA uniform periodic mesh in one space dimension of Nx cells between xmin and xmax.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.UpwindOperators","page":"API reference","title":"SummationByPartsOperators.UpwindOperators","text":"UpwindOperators\nUpwindOperators(D_minus, D_central, D_plus)\n\nA struct bundling the individual operators available for non-periodic upwind SBP operators. The individual operators are available as D.minus, D.plus (and optionally D.central, if provided), where D::UpwindOperators.\n\nThe combined struct behaves as much as possible as an operator itself as long as no ambiguities arise. For example, upwind operators need to use the same grid and mass matrix, so mass_matrix, grid, xmin, xmax etc. are available but mul! is not.\n\nIt is recommended to construct an instance of UpwindOperators using upwind_operators. An instance can also be constructed manually by passing the operators in the order D_minus, D_central, D_plus.\n\nSee also upwind_operators, PeriodicUpwindOperators\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.VarCoefDerivativeCoefficients","page":"API reference","title":"SummationByPartsOperators.VarCoefDerivativeCoefficients","text":"VarCoefDerivativeCoefficients\n\nThe coefficients of a variable coefficient derivative operator on a nonperiodic grid.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.VarCoefDerivativeOperator","page":"API reference","title":"SummationByPartsOperators.VarCoefDerivativeOperator","text":"VarCoefDerivativeOperator\n\nA dissipation operator on a nonperiodic finite difference grid.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.VariableLinearAdvectionNonperiodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.VariableLinearAdvectionNonperiodicSemidiscretization","text":"VariableLinearAdvectionNonperiodicSemidiscretization(D, Di, a, split_form,\n left_bc, right_bc)\n\nA semidiscretization of the linear advection equation partial_t u(tx) + partial_x ( a(x) u(tx) ) = 0 with boundary conditions left_bc(t), right_bc(t).\n\nD is an SBP derivative operator, Di an associated dissipation operator or nothing, a(x) the variable coefficient, and split_form::Union{Val(false), Val(true)} determines whether the canonical split form or the conservative form should be used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.VariableLinearAdvectionPeriodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.VariableLinearAdvectionPeriodicSemidiscretization","text":"VariableLinearAdvectionPeriodicSemidiscretization(D, Di, a, split_form)\n\nA semidiscretization of the linear advection equation partial_t u(tx) + partial_x ( a(x) u(tx) ) = 0 with periodic boundary conditions.\n\nD is a periodic SBP derivative operator, Di an associated dissipation operator or nothing, a(x) the variable coefficient, and split_form::Union{Val(false), Val(true)} determines whether the canonical split form or the conservative form should be used.\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#SummationByPartsOperators.WaveEquationNonperiodicSemidiscretization","page":"API reference","title":"SummationByPartsOperators.WaveEquationNonperiodicSemidiscretization","text":"WaveEquationNonperiodicSemidiscretization(D, left_bc, right_bc)\n\nA semidiscretization of the linear wave equation partial_t^2 u(tx) = partial_x^2 u(tx).\n\nD is assumed to be a second-derivative SBP operator and the boundary conditions can be Val(:HomogeneousNeumann), Val(:HomogeneousDirichlet), or Val(:NonReflecting).\n\n\n\n\n\n","category":"type"},{"location":"api_reference/#LinearAlgebra.mul!","page":"API reference","title":"LinearAlgebra.mul!","text":"mul!(du, D::DerivativeOperator, u, α=true, β=false)\n\nEfficient in-place version of du = α * D * u + β * du. Note that du must not be aliased with u.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#PolynomialBases.compute_coefficients!-Tuple{Any, Any, SummationByPartsOperators.AbstractDerivativeOperator}","page":"API reference","title":"PolynomialBases.compute_coefficients!","text":"compute_coefficients!(uval, u, D::AbstractDerivativeOperator)\n\nCompute the nodal values of the function u at the grid associated to the derivative operator D and stores the result in uval.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.compute_coefficients-Tuple{Any, SummationByPartsOperators.AbstractDerivativeOperator}","page":"API reference","title":"PolynomialBases.compute_coefficients","text":"compute_coefficients(u, D::AbstractDerivativeOperator)\n\nCompute the nodal values of the function u at the grid associated to the derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.evaluate_coefficients!-Tuple{Any, Any, Any, SummationByPartsOperators.AbstractDerivativeOperator}","page":"API reference","title":"PolynomialBases.evaluate_coefficients!","text":"evaluate_coefficients!(xplot, uplot, u, D::AbstractDerivativeOperator)\n\nEvaluates the nodal coefficients u at a grid associated to the derivative operator D and stores the result in xplot, uplot. Returns xplot, uplot, where xplot contains the nodes and uplot the corresponding values of u.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.evaluate_coefficients-Tuple{Any, SummationByPartsOperators.AbstractDerivativeOperator}","page":"API reference","title":"PolynomialBases.evaluate_coefficients","text":"evaluate_coefficients(u, D::AbstractDerivativeOperator)\n\nEvaluates the nodal coefficients u at a grid associated to the derivative operator D. Returns xplot, uplot, where xplot contains the nodes and uplot the corresponding values of u.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.integrate-Tuple{Any, AbstractVector{T} where T, DerivativeOperator}","page":"API reference","title":"PolynomialBases.integrate","text":"integrate(func, u, D::DerivativeOperator)\n\nMap the function func to the coefficients u and integrate with respect to the quadrature rule associated with the SBP derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.integrate-Tuple{Any, AbstractVector{T} where T, PeriodicDerivativeOperator}","page":"API reference","title":"PolynomialBases.integrate","text":"integrate(func, u, D::PeriodicDerivativeOperator)\n\nMap the function func to the coefficients u and integrate with respect to the quadrature rule associated with the periodic derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#PolynomialBases.integrate-Tuple{Any, AbstractVector{T} where T, SummationByPartsOperators.AbstractPeriodicDerivativeOperator}","page":"API reference","title":"PolynomialBases.integrate","text":"integrate(func, u, D::AbstractPeriodicDerivativeOperator)\n\nMap the function func to the coefficients u and integrate with respect to the quadrature rule associated with the derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.accuracy_order","page":"API reference","title":"SummationByPartsOperators.accuracy_order","text":"accuracy_order(D)\n\nReturn the order of accuracy of a derivative operator D. For SBP finite difference operators, this refers to the interior order of accuracy.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.couple_continuously","page":"API reference","title":"SummationByPartsOperators.couple_continuously","text":"couple_continuously(D, mesh)\n\nReturn a derivative operator corresponding to a continuous coupling of D on the cells of the given mesh as in (nodal) continuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are CG spectral element methods (CGSEM). However, a continuous coupling of arbitrary SBP operators is supported.\n\nThe mesh can be a UniformMesh1D or a UniformPeriodicMesh1D.\n\nReferences\n\nRanocha, Mitsotakis, Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.couple_discontinuously","page":"API reference","title":"SummationByPartsOperators.couple_discontinuously","text":"couple_discontinuously(D, mesh, [coupling=Val(:central)])\n\nReturn a derivative operator corresponding to a discontinuous coupling of D on the cells of the given mesh as in (nodal) discontinuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are DG spectral element methods (DGSEM). However, a discontinuous coupling of arbitrary SBP operators is supported.\n\nThe mesh can be a UniformMesh1D or a UniformPeriodicMesh1D. The coupling can be\n\nVal(:central) (default), resulting in classical SBP properties\nVal(:minus) or Val(:plus), resulting in upwind SBP operators\n\nReferences\n\nRanocha, Mitsotakis, Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.derivative_left-Tuple{SummationByPartsOperators.AbstractNonperiodicDerivativeOperator, Any}","page":"API reference","title":"SummationByPartsOperators.derivative_left","text":"derivative_left(D::AbstractNonperiodicDerivativeOperator, der_order)\n\nGet a representation of the linear functional evaluation the Nth derivative at the left boundary node as (dense) vector.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.derivative_left-Union{Tuple{N}, Tuple{DerivativeOperator, Any, Val{N}}} where N","page":"API reference","title":"SummationByPartsOperators.derivative_left","text":"derivative_left(D::DerivativeOperator, u, der_order::Val{N})\n\nCompute the N-th derivative of the function given by the coefficients u at the left boundary of the grid.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.derivative_operator","page":"API reference","title":"SummationByPartsOperators.derivative_operator","text":"derivative_operator(source_of_coefficients,\n derivative_order, accuracy_order,\n xmin, xmax, N, mode=FastMode())\nderivative_operator(source_of_coefficients;\n derivative_order, accuracy_order,\n xmin, xmax, N, mode=FastMode())\n\nCreate a DerivativeOperator approximating the derivative_order-th derivative on a grid between xmin and xmax with N grid points up to order of accuracy accuracy_order. with coefficients given by source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.derivative_order","page":"API reference","title":"SummationByPartsOperators.derivative_order","text":"derivative_order(D)\n\nReturn the order of the derivative associated to the derivative operator D. For example, it will return 1 for a first-derivative SBP operator.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.derivative_right-Tuple{SummationByPartsOperators.AbstractNonperiodicDerivativeOperator, Any}","page":"API reference","title":"SummationByPartsOperators.derivative_right","text":"derivative_right(D::AbstractNonperiodicDerivativeOperator, der_order)\n\nGet a representation of the linear functional evaluation the Nth derivative at the right boundary node as (dense) vector.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.derivative_right-Union{Tuple{N}, Tuple{DerivativeOperator, Any, Val{N}}} where N","page":"API reference","title":"SummationByPartsOperators.derivative_right","text":"derivative_right(D::DerivativeOperator, u, der_order::Val{N})\n\nCompute the N-th derivative of the function given by the coefficients u at the right boundary of the grid.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.dissipation_operator","page":"API reference","title":"SummationByPartsOperators.dissipation_operator","text":"dissipation_operator(source_of_coefficients, order, xmin, xmax, N,\n left_weights, right_weights, mode=FastMode())\n\nCreate a negative semidefinite DissipationOperator using undivided differences approximating a weighted order-th derivative on a grid between xmin and xmax with N grid points up to order of accuracy 2 with coefficients given by source_of_coefficients. The norm matrix is given by left_weights and right_weights. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.dissipation_operator-Tuple{PeriodicDerivativeOperator}","page":"API reference","title":"SummationByPartsOperators.dissipation_operator","text":"dissipation_operator(D::PeriodicDerivativeOperator;\n strength=one(eltype(D)),\n order=accuracy_order(D),\n mode=D.coefficients.mode)\n\nCreate a negative semidefinite DissipationOperator using undivided differences approximating a order-th derivative with strength strength adapted to the derivative operator D. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.dissipation_operator-Union{Tuple{T}, Tuple{Any, DerivativeOperator{T, LeftBoundary, RightBoundary, LeftBoundaryDerivatives, RightBoundaryDerivatives, LowerOffset, UpperOffset, LeftWidth, RightWidth, ExecutionMode, SourceOfCoefficients, Grid} where {LeftBoundary, RightBoundary, LeftBoundaryDerivatives, RightBoundaryDerivatives, LowerOffset, UpperOffset, LeftWidth, RightWidth, ExecutionMode, SourceOfCoefficients, Grid}}} where T","page":"API reference","title":"SummationByPartsOperators.dissipation_operator","text":"dissipation_operator([source_of_coefficients=MattssonSvärdNordström2004()],\n D::DerivativeOperator{T};\n strength=one(T),\n order::Int=accuracy_order(D),\n mode=D.coefficients.mode)\n\nCreate a negative semidefinite DissipationOperator using undivided differences approximating a weighted order-th derivative adapted to the derivative operator D with coefficients given in source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.fornberg-Union{Tuple{T}, Tuple{Vector{T}, Int64}} where T","page":"API reference","title":"SummationByPartsOperators.fornberg","text":"fornberg(x::Vector{T}, m::Int) where {T}\n\nCalculate the weights of a finite difference approximation of the mth derivative with maximal order of accuracy at 0 using the nodes x, see Fornberg (1998) Calculation of Weights in Finite Difference Formulas SIAM Rev. 40.3, pp. 685-691.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.fourier_derivative_matrix","page":"API reference","title":"SummationByPartsOperators.fourier_derivative_matrix","text":"fourier_derivative_matrix(N, xmin::Real=0.0, xmax::Real=2π)\n\nCompute the Fourier derivative matrix with respect to the corresponding nodal basis using N nodes, see Kopriva (2009) Implementing Spectral Methods for PDEs, Algorithm 18.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.fourier_derivative_operator-Tuple{Real, Real, Integer}","page":"API reference","title":"SummationByPartsOperators.fourier_derivative_operator","text":"fourier_derivative_operator(xmin::Real, xmax::Real, N::Integer)\nfourier_derivative_operator(; xmin::Real, xmax::Real, N::Integer)\n\nConstruct the FourierDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N÷2+1 complex Fourier modes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.function_space_operator","page":"API reference","title":"SummationByPartsOperators.function_space_operator","text":"function_space_operator(basis_functions, nodes, source;\n derivative_order = 1, accuracy_order = 0,\n options = Optim.Options(g_tol = 1e-14, iterations = 10000))\n\nConstruct an operator that represents a first-derivative operator in a function space spanned by the basis_functions, which is an iterable of functions. The operator is constructed on the interval [x_min, x_max] with the nodes nodes, where x_min is taken as the minimal value in nodes and x_max the maximal value. Note that the nodes will be sorted internally. The accuracy_order is the order of the accuracy of the operator, which can optionally be passed, but does not have any effect on the operator. The operator is constructed solving an optimization problem with Optim.jl. You can specify the options for the optimization problem with the options argument, see also the documentation of Optim.jl.\n\nThe operator that is returned follows the general interface. Currently, it is wrapped in a MatrixDerivativeOperator, but this might change in the future. In order to use this function, the package Optim must be loaded.\n\nSee also GlaubitzNordströmÖffner2023.\n\ncompat: Julia 1.9\nThis function requires at least Julia 1.9.\n\nwarning: Experimental implementation\nThis is an experimental feature and may change in future releases.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.grid","page":"API reference","title":"SummationByPartsOperators.grid","text":"grid(D)\n\nReturn the grid associated to a derivative operator D.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.left_boundary_weight","page":"API reference","title":"SummationByPartsOperators.left_boundary_weight","text":"left_boundary_weight(D)\n\nReturn the left-boundary weight of the (diagonal) mass matrix M associated to the derivative operator D.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.legendre_derivative_operator-Tuple{Real, Real, Integer}","page":"API reference","title":"SummationByPartsOperators.legendre_derivative_operator","text":"legendre_derivative_operator(xmin::Real, xmax::Real, N::Integer)\nlegendre_derivative_operator(; xmin::Real, xmax::Real, N::Integer)\n\nConstruct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.legendre_second_derivative_operator-Tuple{Real, Real, Integer}","page":"API reference","title":"SummationByPartsOperators.legendre_second_derivative_operator","text":"legendre_second_derivative_operator(xmin::Real, xmax::Real, N::Integer)\nlegendre_second_derivative_operator(; xmin::Real, xmax::Real, N::Integer)\n\nConstruct the LegendreDerivativeOperator on a uniform grid between xmin and xmax using N nodes and N-1 Legendre modes.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.mass_matrix-Tuple{Union{DerivativeOperator, VarCoefDerivativeOperator}}","page":"API reference","title":"SummationByPartsOperators.mass_matrix","text":"mass_matrix(D::Union{DerivativeOperator,VarCoefDerivativeOperator})\n\nCreate the diagonal mass matrix for the SBP derivative operator D.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.mul_transpose_derivative_left!-Union{Tuple{N}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}, Any}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}, Any, Any}} where N","page":"API reference","title":"SummationByPartsOperators.mul_transpose_derivative_left!","text":"mul_transpose_derivative_left!(u, D::DerivativeOperator, der_order::Val{N}, α=true, β=false)\n\nSet the grid function u to α times the transposed N-th derivative functional applied to u plus β times u in the domain of the N-th derivative functional at the left boundary of the grid. Thus, the coefficients α, β have the same meaning as in mul!.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.mul_transpose_derivative_right!-Union{Tuple{N}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}, Any}, Tuple{AbstractVector{T} where T, DerivativeOperator, Val{N}, Any, Any}} where N","page":"API reference","title":"SummationByPartsOperators.mul_transpose_derivative_right!","text":"mul_transpose_derivative_right!(u, D::DerivativeOperator, der_order::Val{N}, α=true, β=false)\n\nSet the grid function u to α times the transposed N-th derivative functional applied to u plus β times u in the domain of the N-th derivative functional at the right boundary of the grid. Thus, the coefficients α, β have the same meaning as in mul!.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.periodic_central_derivative_coefficients","page":"API reference","title":"SummationByPartsOperators.periodic_central_derivative_coefficients","text":"periodic_central_derivative_coefficients(derivative_order, accuracy_order, T=Float64, mode=FastMode())\n\nCreate the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_central_derivative_operator","page":"API reference","title":"SummationByPartsOperators.periodic_central_derivative_operator","text":"periodic_central_derivative_operator(derivative_order, accuracy_order,\n xmin, xmax, N, mode=FastMode())\n\nCreate a PeriodicDerivativeOperator approximating the derivative_order-th derivative on a uniform grid between xmin and xmax with N grid points up to order of accuracy accuracy_order. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_coefficients","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_coefficients","text":"periodic_derivative_coefficients(derivative_order, accuracy_order,\n left_offset=-(accuracy_order+1)÷2,\n T=Float64, mode=FastMode())\n\nCreate the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()`.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_coefficients-Tuple{Holoborodko2008, Any, Any}","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_coefficients","text":"periodic_derivative_coefficients(source::Holoborodko2008, derivative_order, accuracy_order;\n T=Float64, mode=FastMode(),\n stencil_width=accuracy_order+3)\n\nCreate the PeriodicDerivativeCoefficients approximating the derivative_order-th derivative with an order of accuracy accuracy_order and scalar type T given by Holoborodko2008. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()`.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_operator","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_operator","text":"periodic_derivative_operator(derivative_order, accuracy_order, grid,\n left_offset=-(accuracy_order+1)÷2, mode=FastMode())\n\nCreate a PeriodicDerivativeOperator approximating the derivative_order-th derivative on the uniform grid up to order of accuracy accuracy_order where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_operator-2","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_operator","text":"periodic_derivative_operator(derivative_order, accuracy_order,\n xmin, xmax, N,\n left_offset=-(accuracy_order+1)÷2,\n mode=FastMode())\nperiodic_derivative_operator(; derivative_order, accuracy_order,\n xmin, xmax, N,\n left_offset=-(accuracy_order+1)÷2,\n mode=FastMode())\n\nCreate a PeriodicDerivativeOperator approximating the derivative_order-th derivative on a uniform grid between xmin and xmax with N grid points up to order of accuracy accuracy_order where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode()).\n\nExamples\n\njulia> periodic_derivative_operator(derivative_order=1, accuracy_order=2,\n xmin=0.0, xmax=1.0, N=11)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 1.0] using 11 nodes,\nstencils with 1 nodes to the left, 1 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.periodic_derivative_operator-Tuple{Holoborodko2008, Any, Any, Any, Any, Any}","page":"API reference","title":"SummationByPartsOperators.periodic_derivative_operator","text":"periodic_derivative_operator(source::Holoborodko2008,\n derivative_order, accuracy_order,\n xmin, xmax, N; mode=FastMode(), kwargs...)\nperiodic_derivative_operator(source::Holoborodko2008;\n derivative_order, accuracy_order,\n xmin, xmax, N, mode=FastMode(), kwargs...)\n\nCreate a PeriodicDerivativeOperator approximating the derivative_order-th derivative on a uniform grid between xmin and xmax with N grid points up to order of accuracy accuracy_order where the leftmost grid point used is determined by left_offset. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\nExamples\n\njulia> periodic_derivative_operator(Holoborodko2008(), derivative_order=1, accuracy_order=2,\n xmin=0.0, xmax=1.0, N=11)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 1.0] using 11 nodes,\nstencils with 2 nodes to the left, 2 nodes to the right, and coefficients of Holoborodko (2008)\n Smooth Noise Robust Differentiators.\n http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.right_boundary_weight","page":"API reference","title":"SummationByPartsOperators.right_boundary_weight","text":"right_boundary_weight(D)\n\nReturn the left-boundary weight of the (diagonal) mass matrix M associated to the derivative operator D.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.semidiscretize-Tuple{Any, SummationByPartsOperators.AbstractSemidiscretization, Any}","page":"API reference","title":"SummationByPartsOperators.semidiscretize","text":"semidiscretize(u0func, semi::AbstractSemidiscretization, tspan)\n\nApply the semidiscretization semi to the initial data given by u0func and return an ODEProblem with time span tspan.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.source_of_coefficients-Tuple{Any}","page":"API reference","title":"SummationByPartsOperators.source_of_coefficients","text":"source_of_coefficients(D)\n\nReturn the source of coefficients of the derivative operator D. If you use the operator D for your research, please cite this source in addition to SummationByPartsOperators.\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.upwind_operators-Tuple{Any, Vararg{Any, N} where N}","page":"API reference","title":"SummationByPartsOperators.upwind_operators","text":"upwind_operators(source_type, args...; derivative_order = 1, kwargs...)\n\nCreate UpwindOperators from the given source type. The positional arguments args... and keyword arguments kwargs... are passed directly to derivative_operator.\n\nExamples\n\njulia> D = upwind_operators(Mattsson2017, accuracy_order = 2,\n xmin = 0//1, xmax = 9//1, N = 10)\nUpwind SBP first-derivative operators of order 2 on a grid in [0//1, 9//1] using 10 nodes\nand coefficients of Mattsson2017\n\njulia> D.minus\nSBP first-derivative operator of order 2 on a grid in [0//1, 9//1] using 10 nodes\nand coefficients of Mattsson (2017)\n Diagonal-norm upwind SBP operators.\n Journal of Computational Physics 335, pp. 283-310.\n (upwind coefficients minus)\n\njulia> D.plus\nSBP first-derivative operator of order 2 on a grid in [0//1, 9//1] using 10 nodes\nand coefficients of Mattsson (2017)\n Diagonal-norm upwind SBP operators.\n Journal of Computational Physics 335, pp. 283-310.\n (upwind coefficients plus)\n\njulia> Matrix(D.central)\n10×10 Matrix{Rational{Int64}}:\n -2//1 3//1 -1//1 0//1 0//1 0//1 0//1 0//1 0//1 0//1\n -3//5 0//1 4//5 -1//5 0//1 0//1 0//1 0//1 0//1 0//1\n 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1 0//1 0//1 0//1\n 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1 0//1 0//1\n 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1 0//1\n 0//1 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1\n 0//1 0//1 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1\n 0//1 0//1 0//1 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4\n 0//1 0//1 0//1 0//1 0//1 0//1 1//5 -4//5 0//1 3//5\n 0//1 0//1 0//1 0//1 0//1 0//1 0//1 1//1 -3//1 2//1\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.upwind_operators-Tuple{typeof(periodic_derivative_operator)}","page":"API reference","title":"SummationByPartsOperators.upwind_operators","text":"upwind_operators(periodic_derivative_operator;\n derivative_order = 1, accuracy_order,\n xmin, xmax, N,\n mode = FastMode()))\n\nCreate PeriodicUpwindOperators from operators constructed by periodic_derivative_operator. The keyword arguments are passed directly to periodic_derivative_operator.\n\nExamples\n\njulia> D = upwind_operators(periodic_derivative_operator, accuracy_order = 2,\n xmin = 0//1, xmax = 8//1, N = 8)\nUpwind SBP first-derivative operators of order 2 on a grid in [0//1, 7//1] using 8 nodes\nand coefficients of Fornberg1998\n\njulia> D.minus\nPeriodic first-derivative operator of order 2 on a grid in [0//1, 8//1] using 8 nodes,\nstencils with 2 nodes to the left, 0 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> D.plus\nPeriodic first-derivative operator of order 2 on a grid in [0//1, 8//1] using 8 nodes,\nstencils with 0 nodes to the left, 2 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> Matrix(D.central)\n8×8 Matrix{Rational{Int64}}:\n 0//1 1//1 -1//4 0//1 0//1 0//1 1//4 -1//1\n -1//1 0//1 1//1 -1//4 0//1 0//1 0//1 1//4\n 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1 0//1\n 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1 0//1\n 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4 0//1\n 0//1 0//1 0//1 1//4 -1//1 0//1 1//1 -1//4\n -1//4 0//1 0//1 0//1 1//4 -1//1 0//1 1//1\n 1//1 -1//4 0//1 0//1 0//1 1//4 -1//1 0//1\n\n\n\n\n\n","category":"method"},{"location":"api_reference/#SummationByPartsOperators.var_coef_derivative_operator","page":"API reference","title":"SummationByPartsOperators.var_coef_derivative_operator","text":"var_coef_derivative_operator(source_of_coefficients, derivative_order, accuracy_order,\n xmin, xmax, N, left_weights, right_weights, bfunc,\n mode=FastMode())\n\nCreate a VarCoefDerivativeOperator approximating a derivative_order-th derivative with variable coefficients bfunc on a grid between xmin and xmax with N grid points up to order of accuracy accuracy_order with coefficients given by source_of_coefficients. The evaluation of the derivative can be parallelized using threads by choosing mode=ThreadedMode().\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.xmax","page":"API reference","title":"SummationByPartsOperators.xmax","text":"xmax(D)\n\nReturn the right boundary xmax of the domain specified when constructing the derivative operator D. Note that this might be different from the rightmost node of the grid of D when not all boundary nodes are included, e.g., for periodic derivative operators.\n\n\n\n\n\n","category":"function"},{"location":"api_reference/#SummationByPartsOperators.xmin","page":"API reference","title":"SummationByPartsOperators.xmin","text":"xmin(D)\n\nReturn the left boundary xmin of the domain specified when constructing the derivative operator D. Note that this might be different from the leftmost node of the grid of D when not all boundary nodes are included, e.g., for periodic derivative operators.\n\n\n\n\n\n","category":"function"},{"location":"license/","page":"License","title":"License","text":"EditURL = \"https://github.com/ranocha/SummationByPartsOperators.jl/blob/main/LICENSE.md\"","category":"page"},{"location":"license/#License","page":"License","title":"License","text":"","category":"section"},{"location":"license/","page":"License","title":"License","text":"MIT LicenseCopyright (c) 2017-present Hendrik Ranocha Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","category":"page"},{"location":"tutorials/wave_equation/#Wave-equation","page":"Wave equation","title":"Wave equation","text":"","category":"section"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"Consider the linear wave equation","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"beginaligned\n partial_t^2 u(tx) = partial_x^2 u(tx) t in (0T) x in (x_min x_max) \n u(0x) = u_0(x) x in (x_min x_max) \n partial_t u(0x) = v_0(x) x in (x_min x_max) \n textboundary conditions x in partial (x_min x_max)\nendaligned","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"SummationByPartsOperators.jl includes a pre-built semidiscretization of this equation: WaveEquationNonperiodicSemidiscretization. Have a look at the source code if you want to dig deeper. In particular, you can find applications of derivative_left, derivative_right mul_transpose_derivative_left!, and mul_transpose_derivative_right!. Below is an example demonstrating how to use this semidiscretization.","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"using SummationByPartsOperators, OrdinaryDiffEq\nusing LaTeXStrings; using Plots: Plots, plot, plot!, savefig\n\n# general parameters\nxmin = -1.\nxmax = +1.\ntspan = (0., 8.0)\nu0_func(x) = exp(-20x^2)\nv0_func(x) = zero(x)\n# HomogeneousNeumann, HomogeneousDirichlet, and NonReflecting BCs are available\nleft_bc = Val(:HomogeneousNeumann)\nright_bc = Val(:HomogeneousDirichlet)\n\n# setup spatial semidiscretization\nD2 = derivative_operator(MattssonSvärdShoeybi2008(), derivative_order=2,\n accuracy_order=4, xmin=xmin, xmax=xmax, N=101)\nsemi = WaveEquationNonperiodicSemidiscretization(D2, left_bc, right_bc)\node = semidiscretize(v0_func, u0_func, semi, tspan)\n\n# solve second-order ODE using a Runge-Kutta-Nyström method\nsol = solve(ode, DPRKN6(), saveat=range(first(tspan), stop=last(tspan), length=200))\n\n# visualize the result\nplot(xguide=L\"x\")\nplot!(evaluate_coefficients(sol[end].x[2], semi), label=L\"u\")\nplot!(evaluate_coefficients(sol[end].x[1], semi), label=L\"\\partial_t u\")\nsavefig(\"example_wave_equation.png\");","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"(Image: )","category":"page"},{"location":"tutorials/wave_equation/#Advanced-visualization-of-different-boundary-conditions","page":"Wave equation","title":"Advanced visualization of different boundary conditions","text":"","category":"section"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"Let's create animations of the numerical solutions for different boundary conditions.","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"using Printf; using Plots: Animation, frame, gif\n\nfunction create_gif(left_bc::Val{LEFT_BC}, right_bc::Val{RIGHT_BC}) where {LEFT_BC, RIGHT_BC}\n xmin = -1.\n xmax = +1.\n tspan = (0., 8.0)\n u0_func(x) = exp(-20x^2)\n v0_func(x) = zero(x)\n\n D2 = derivative_operator(MattssonSvärdShoeybi2008(), derivative_order=2,\n accuracy_order=4, xmin=xmin, xmax=xmax, N=101)\n semi = WaveEquationNonperiodicSemidiscretization(D2, left_bc, right_bc)\n ode = semidiscretize(v0_func, u0_func, semi, tspan)\n\n sol = solve(ode, DPRKN6(), saveat=range(first(tspan), stop=last(tspan), length=200))\n\n anim = Animation()\n idx = 1\n x, u = evaluate_coefficients(sol[idx].x[2], D2)\n fig = plot(x, u, xguide=L\"x\", yguide=L\"u\", xlim=extrema(x), ylim=(-1.05, 1.05),\n label=\"\", title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n for idx in 1:length(sol.t)\n fig[1] = x, sol.u[idx].x[2]\n plot!(title=@sprintf(\"\\$t = %6.2f \\$\", sol.t[idx]))\n frame(anim)\n end\n gif(anim, \"wave_equation_$(LEFT_BC)_$(RIGHT_BC).gif\")\nend\n\ncreate_gif(Val(:HomogeneousNeumann), Val(:HomogeneousNeumann))","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"(Image: wave_equation_HomogeneousNeumann_HomogeneousNeumann)","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"create_gif(Val(:HomogeneousNeumann), Val(:HomogeneousDirichlet))","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"(Image: wave_equation_HomogeneousNeumann_HomogeneousDirichlet)","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"create_gif(Val(:HomogeneousNeumann), Val(:NonReflecting))","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"(Image: wave_equation_HomogeneousNeumann_NonReflecting)","category":"page"},{"location":"tutorials/wave_equation/#Package-versions","page":"Wave equation","title":"Package versions","text":"","category":"section"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"These results were obtained using the following versions.","category":"page"},{"location":"tutorials/wave_equation/","page":"Wave equation","title":"Wave equation","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"OrdinaryDiffEq\"],\n mode=PKGMODE_MANIFEST)","category":"page"},{"location":"ad/#Automatic/algorithmic-differentiation-(AD)","page":"Automatic differentiation (AD)","title":"Automatic/algorithmic differentiation (AD)","text":"","category":"section"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"SummationByPartsOperators.jl is written using generic Julia code whenever possible. This means that standard AD tools just work. For example, computing the Jacobian using ForwardDiff.jl is possible using the following code.","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"julia> using SummationByPartsOperators, ForwardDiff\n\njulia> D = periodic_derivative_operator(derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 8)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 1.0] using 8 nodes,\nstencils with 1 nodes to the left, 1 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> u = rand(size(D, 2));\n\njulia> J = ForwardDiff.jacobian(u -> D * u, u)\n8×8 Matrix{Float64}:\n 0.0 4.0 0.0 0.0 0.0 0.0 0.0 -4.0\n -4.0 0.0 4.0 0.0 0.0 0.0 0.0 0.0\n 0.0 -4.0 0.0 4.0 0.0 0.0 0.0 0.0\n 0.0 0.0 -4.0 0.0 4.0 0.0 0.0 0.0\n 0.0 0.0 0.0 -4.0 0.0 4.0 0.0 0.0\n 0.0 0.0 0.0 0.0 -4.0 0.0 4.0 0.0\n 0.0 0.0 0.0 0.0 0.0 -4.0 0.0 4.0\n 4.0 0.0 0.0 0.0 0.0 0.0 -4.0 0.0\n\njulia> J ≈ Matrix(D)\ntrue","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"This works of course also for non-periodic SBP operators, e.g.,","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"julia> using SummationByPartsOperators, ForwardDiff\n\njulia> D = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 8)\nSBP first-derivative operator of order 2 on a grid in [0.0, 1.0] using 8 nodes\nand coefficients of Mattsson, Nordström (2004)\n Summation by parts operators for finite difference approximations of second\n derivatives.\n Journal of Computational Physics 199, pp. 503-540.\n\njulia> u = rand(size(D, 2));\n\njulia> J = ForwardDiff.jacobian(u -> D * u, u)\n8×8 Matrix{Float64}:\n -7.0 7.0 0.0 0.0 0.0 0.0 0.0 0.0\n -3.5 0.0 3.5 0.0 0.0 0.0 0.0 0.0\n 0.0 -3.5 0.0 3.5 0.0 0.0 0.0 0.0\n 0.0 0.0 -3.5 0.0 3.5 0.0 0.0 0.0\n 0.0 0.0 0.0 -3.5 0.0 3.5 0.0 0.0\n 0.0 0.0 0.0 0.0 -3.5 0.0 3.5 0.0\n 0.0 0.0 0.0 0.0 0.0 -3.5 0.0 3.5\n 0.0 0.0 0.0 0.0 0.0 0.0 -7.0 7.0\n\njulia> J ≈ Matrix(D)\ntrue","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"However, this does not work for Fourier derivative operators - and all other operators involving an FFT - since FFTW.jl cannot handle dual numbers and a simple reinterpret trick does also not help since FFTW.jl requires unit strides.","category":"page"},{"location":"ad/#Jacobian-vector-products","page":"Automatic differentiation (AD)","title":"Jacobian-vector products","text":"","category":"section"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"There is a nat trick that you can use if you are only interested in Jacobian-vector products. ForwardDiff.jl does not offer such a functionality at the time of writing, but Simon Byrne suggested the following implementation.","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"using SummationByPartsOperators, ForwardDiff, StructArrays\n\nfunction StructDual(x::AbstractVector{T}, w::AbstractVector{T}) where {T}\n @assert length(x) == length(w)\n # This was the original suggestion. However, it is currently not stable\n # under broadcasting. Thus, we use a slightly different version.\n # partials = StructArray{ForwardDiff.Partials{1, T}}(\n # (StructArray{Tuple{T}}(\n # (w,)\n # ),)\n # )\n partials = reinterpret(reshape, ForwardDiff.Partials{1, T}, w)\n duals = StructArray{ForwardDiff.Dual{Nothing, T, 1}}((x, partials))\n return duals\nend\n\nfunction ForwardDiff.value(dx::StructArray{D}) where {D <: ForwardDiff.Dual}\n return dx.value\nend\n\nfunction ForwardDiff.partials(dx::StructArray{<: ForwardDiff.Dual{Tag, T, 1}}, i) where {Tag, T}\n # This was the original suggestion. We need to update it (see above).\n # return getproperty(dx.partials.values, i)\n @assert i == 1\n return reinterpret(reshape, T, dx.partials)\nend","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"You can use it as follows to compute the Jacobian-vector product","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"J_f(u) cdot v","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"for the function f given by","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"f(u) = D u","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"D = fourier_derivative_operator(xmin = 0.0, xmax = 1.0, N = 8)\n\nu = randn(size(D, 2)); # the point `u` where we want to compute the derivative\nv = randn(size(D, 2)); # the direction `v` in which we want to compute the derivative\nu_v = StructDual(u, v); # combined StructArray containing the value and direction\n\nf_df = D * u_v # compute the function value and its derivative\n\n@assert ForwardDiff.value(f_df) ≈ D * u\n\n@assert ForwardDiff.partials(f_df, 1) ≈ D * v # the Jacobian of `f(u) = D * u` is `D`","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"You can of course also use this with nonlinear functions, e.g.,","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"f(u, D) = u .* (D * (u.^2))\n\nf_df = f(u_v, D)","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"The Jacobian of this function is","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"using LinearAlgebra\n\nJ = Diagonal(D * u.^2) + 2 .* u .* Matrix(D) * Diagonal(u)\n\n@assert ForwardDiff.value(f_df) ≈ f(u, D)\n\n@assert ForwardDiff.partials(f_df, 1) ≈ J * v","category":"page"},{"location":"ad/#Reproducibility","page":"Automatic differentiation (AD)","title":"Reproducibility","text":"","category":"section"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"These results were obtained using the following versions.","category":"page"},{"location":"ad/","page":"Automatic differentiation (AD)","title":"Automatic differentiation (AD)","text":"using InteractiveUtils\nversioninfo()\n\nusing Pkg\nPkg.status([\"SummationByPartsOperators\", \"ForwardDiff\", \"StructArrays\"],\n mode=PKGMODE_MANIFEST)\nnothing # hide","category":"page"},{"location":"introduction/#intro-introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Summation-by-parts (SBP) operators are discrete derivative operators designed to enable (semi-) discrete stability proofs mimicking the energy method from the continuous level. To do so, SBP operators mimic integration-by-parts discretely. Here, we will briefly explain the basic concepts. If you want to learn more about this subject, the classical review articles of [SvärdNordström2014] and [FernándezHickenZingg2014] are good starting points. More recent references and applications of SBP operators from many classes implemented in SummationByPartsOperators.jl are given by [RanochaMitsotakisKetcheson2021].","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Since SBP operators are designed to mimic integration-by-parts, they need a notion of derivatives and integrals. Here, derivatives are interpreted as linear operators D (derivative matrices) and integrals are interpreted as discrete inner products, represented by the associated mass/norm matrices M. Thus, the discrete derivative of a grid function u is D * u and the discrete inner product of two grid functions u and v is dot(u, M, v), where M = mass_matrix(D). Here, we have already introduced some basic interfaces provided by SummationByPartsOperators.jl:","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Derivative operators act as linear operators implementing * (and mul! for more efficient in-place updates avoiding allocations).\nThe mass matrix associated to an SBP derivative operator can be retrieved via mass_matrix.","category":"page"},{"location":"introduction/#Periodic-domains","page":"Introduction","title":"Periodic domains","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Periodic (central) SBP operators mimic the properties of differential operators on periodic domains. Hence, they are","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"skew-symmetric if they approximate odd derivatives\nsymmetric and semi-definite if they approximate even derivatives; second-derivative operators are negative semi-definite, fourth-derivative operators are positive semi-definite etc.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Classical central finite difference operators on periodic domains are periodic SBP operators. They can be constructed via periodic_derivative_operator. Similarly, Fourier collocation methods can be interpreted as periodic SBP operators, which can be constructed via fourier_derivative_operator.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"julia> using SummationByPartsOperators, LinearAlgebra\n\njulia> D = periodic_derivative_operator(derivative_order=1, accuracy_order=2,\n xmin=0.0, xmax=2.0, N=20)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 2.0] using 20 nodes,\nstencils with 1 nodes to the left, 1 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> M = mass_matrix(D)\nUniformScaling{Float64}\n0.1*I\n\njulia> M * Matrix(D) + Matrix(D)' * M |> norm\n0.0\n\njulia> D = fourier_derivative_operator(xmin=0.0, xmax=2.0, N=20)\nPeriodic 1st derivative Fourier operator {T=Float64}\non a grid in [0.0, 2.0] using 20 nodes and 11 modes\n\njulia> M = mass_matrix(D)\nUniformScaling{Float64}\n0.1*I\n\njulia> norm(M * Matrix(D) + Matrix(D)' * M) < 10 * eps(eltype(D))\ntrue","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"As you have seen above, conversion methods to other common types such as Matrix, sparse from the standard library SparseArrays, and BandedMatrix from BandedMatrices.jl are available.","category":"page"},{"location":"introduction/#Non-periodic-domains","page":"Introduction","title":"Non-periodic domains","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"On non-periodic domains, additional boundary terms appear. Thus, the basic symmetry properties of SBP operators are the same as the ones of periodic SBP operators modulo boundary terms. Note that the correct handling of boundary terms is the basic reason of the success of SBP operators. In particular for hyperbolic problems, other boundary treatments that might appear senseful can result in catastrophic failure.","category":"page"},{"location":"introduction/#First-derivative-operators","page":"Introduction","title":"First-derivative operators","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"First-derivative SBP operators need to mimic","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":" int_x_mathrmmin^x_mathrmmax u(x) bigl( partial_x v(x) bigr) mathrmdx\n+ int_x_mathrmmin^x_mathrmmax bigl( partial_x u(x) bigr) v(x) mathrmdx\n= u(x_mathrmmax) v(x_mathrmmax) - u(x_mathrmmin) v(x_mathrmmin)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Thus, a discrete evaluation at the boundary of the domain is necessary. For SBP operators with a grid including the boundary nodes, this can be achieved by simply picking the first/last nodal coefficient of a grid function u. If boundary nodes are not included, some interpolation is necessary in general. Nevertheless, getting a boundary value is a linear functional that is often represented in the literature using (transposed) vectors tL, tR. Then, an SBP operator has to satisfy M * D + D' * M == tR * tR' - tL * tL'. The boundary operators are represented matrix-free via derivative_left and derivative_right for zeroth-order derivatives.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0//1, xmax = 1//1, N = 9)\ntL = zeros(eltype(D), size(D, 1)); tL[1] = 1; tL'\ntR = zeros(eltype(D), size(D, 1)); tR[end] = 1; tR'\nM = mass_matrix(D)\n\nM * Matrix(D) + Matrix(D)' * M == tR * tR' - tL * tL'\nu = randn(size(grid(D))); derivative_left(D, u, Val(0)) == u[begin]\nu = randn(size(grid(D))); derivative_right(D, u, Val(0)) == u[end]","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Here, we have introduced some additional features. Firstly, exact rational coefficients are provided, based on the type of xmin and xmax (if available). Secondly, a source_of_coefficients has to be provided when constructing the SBP operator. You can list them using","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using InteractiveUtils, SummationByPartsOperators\nsubtypes(SourceOfCoefficients)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Here and in the following, the order of accuracy of (finite difference) SBP operators refers to the local order of accuracy in the interior, cf. accuracy_order.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"A special case of first-derivative SBP operators are polynomial derivative operators on Lobatto-Legendre nodes, implemented in legendre_derivative_operator.","category":"page"},{"location":"introduction/#Second-derivative-operators","page":"Introduction","title":"Second-derivative operators","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"To mimic integration-by-parts of second derivatives,","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":" int_x_mathrmmin^x_mathrmmax u(x) bigl( partial_x^2 v(x) bigr) mathrmdx\n= - int_x_mathrmmin^x_mathrmmax bigl( partial_x u(x) bigr) bigl( partial_x v(x) bigr) mathrmdx\n + u(x_mathrmmax) bigl( partial_x v(x_mathrmmax) bigr)\n - bigl( partial_x u(x_mathrmmin)) v(x_mathrmmin)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"the evaluation of the first derivative at the boundaries is necessary. These linear functionals are available as derivative_left and derivative_right. In the literature, they are often called dL and dR. Then, a second-derivative SBP operator has to be of the form M * D == -A + tR * dR' - tL * dL', where A is symmetric and positive semidefinite.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nD = derivative_operator(MattssonNordström2004(), derivative_order=2, accuracy_order=2,\n xmin=0//1, xmax=1//1, N=9)\n\nM = mass_matrix(D)\ntL = derivative_left(D, Val(0)); tL'\ntR = derivative_right(D, Val(0)); tR'\ndL = derivative_left(D, Val(1)); dL'\ndR = derivative_right(D, Val(1)); dR'\n\nA = -M * Matrix(D) + tR * dR' - tL * dL'\nisposdef(A)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Usually, there is no need to form dL, dR explicitly. Instead, you can use the matrix-free variants derivative_left and derivative_right. Some procedures imposing boundary conditions weakly require adding the transposed boundary derivatives to a grid function, which can be achieved by mul_transpose_derivative_left! and mul_transpose_derivative_right!. You can find applications of these operators in the source code of WaveEquationNonperiodicSemidiscretization.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"A special case of second-derivative SBP operators are polynomial derivative operators on Lobatto-Legendre nodes, implemented in legendre_second_derivative_operator.","category":"page"},{"location":"introduction/#intro-upwind-operators","page":"Introduction","title":"Upwind operators","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Upwind SBP operators were introduced by Mattsson2017. They combine two derivative operators Dp (:plus) and Dm (:minus) such that M * Dp + Dm' * M == tR * tR' - tL * tL' and M * (Dp - Dm) is negative semidefinite.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nDp = derivative_operator(Mattsson2017(:plus), derivative_order=1, accuracy_order=2,\n xmin=0//1, xmax=1//1, N=9)\nMatrix(Dp)\nDm = derivative_operator(Mattsson2017(:minus), derivative_order=1, accuracy_order=2,\n xmin=0//1, xmax=1//1, N=9)\nMatrix(Dm)\n\nM = mass_matrix(Dp)\nM * Matrix(Dp) + Matrix(Dm)' * M\nminimum(eigvals(-M * (Matrix(Dp) - Matrix(Dm)))) # > 0 up to floating point tolerances","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"You can also set up fully periodic upwind operators by setting the argument left_offset of periodic_derivative_operator appropriately. For example,","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nDp = periodic_derivative_operator(derivative_order=1, accuracy_order=2, left_offset=0,\n xmin=0//1, xmax=1//1, N=8)\nMatrix(Dp)\nDm = periodic_derivative_operator(derivative_order=1, accuracy_order=2, left_offset=-2,\n xmin=0//1, xmax=1//1, N=8)\nMatrix(Dm)\n\nM = mass_matrix(Dp)\nM * Matrix(Dp) + Matrix(Dm)' * M |> iszero\nminimum(eigvals(-M * (Matrix(Dp) - Matrix(Dm)))) # > 0 up to floating point tolerances","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Note that we used N=8 here, i.e., one node less than for the non-periodic example. This is necessary since the additional node at the right boundary is identified with the left boundary node for periodic operators.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"To create all upwind operators for a single setup, you can use upwind_operators.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators\n\nD = upwind_operators(Mattsson2017, derivative_order=1, accuracy_order=2,\n xmin=0, xmax=1//1, N=9)\nMatrix(D.plus)\nMatrix(D.minus)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"This also works with periodic upwind operators.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators\n\nD = upwind_operators(periodic_derivative_operator, accuracy_order = 2,\n xmin = 0, xmax = 1//1, N = 10)\nMatrix(D.plus)\nMatrix(D.minus)","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"You can also couple upwind operators continuously across elements using couple_continuously to obtain global upwind operators, see below and Theorem 2.4 of [RanochaMitsotakisKetcheson2021].","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Similarly, you can couple classical and upwind operators discontinuously across elements using couple_discontinuously to obtain global upwind operators, see below and Theorem 2.2 of [RanochaMitsotakisKetcheson2021].","category":"page"},{"location":"introduction/#intro-CGSEM","page":"Introduction","title":"Continuous Galerkin methods","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"SBP operators can be coupled to obtain (nodal) continuous Galerkin (CG) methods. If the underlying SBP operators are LegendreDerivativeOperators, these are CG spectral element methods (CGSEM). However, a continuous coupling of arbitrary SBP operators is supported.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nD = couple_continuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=3),\n UniformMesh1D(xmin=0.0, xmax=1.0, Nx=3))\nMatrix(D)\nmass_matrix(D)","category":"page"},{"location":"introduction/#intro-DGSEM","page":"Introduction","title":"Discontinuous Galerkin methods","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"SBP operators can also be coupled as in discontinuous Galerkin (DG) methods. Using a central numerical flux results in central SBP operators; upwind fluxes yield upwind SBP operators. If LegendreDerivativeOperators are used, the discontinuous coupling yields DG spectral element methods (DGSEM).","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nD = couple_discontinuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=3),\n UniformPeriodicMesh1D(xmin=0.0, xmax=1.0, Nx=3),\n Val(:central))\n\nM = mass_matrix(D);\nM * Matrix(D) + Matrix(D)' * M |> iszero","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Right now, only uniform meshes UniformMesh1D and UniformPeriodicMesh1D are implemented.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"You can also specify a different coupling than Val(:central) to obtain upwind operators.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"using SummationByPartsOperators, LinearAlgebra\n\nDp = couple_discontinuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=3),\n UniformPeriodicMesh1D(xmin=0.0, xmax=1.0, Nx=3),\n Val(:plus))\n\nMatrix(Dp)\n\nDm = couple_discontinuously(\n legendre_derivative_operator(xmin=-1.0, xmax=1.0, N=3),\n UniformPeriodicMesh1D(xmin=0.0, xmax=1.0, Nx=3),\n Val(:minus))\n\nMatrix(Dm)","category":"page"},{"location":"introduction/#Basic-interfaces-and-additional-features","page":"Introduction","title":"Basic interfaces and additional features","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"To actually compute and plot the discrete grid functions, a few additional ingredients are necessary.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"The discrete coefficients of a function on the grid of an SBP operator can usually be computed as x = grid(D); u = u_function.(x), at least for nodal bases. In general, compute_coefficients (or the in-place version compute_coefficients!) can also be used for this task.\nTo get a grid and discrete values suitable for plotting, you can use evaluate_coefficients (or the in-place version evaluate_coefficients!). The plot nodes returned from evaluate_coefficients can be different from the nodes of the grid associated to an SBP operator.\nTo implement boundary procedures, the weights of the mass matrix at the boundary are often needed. These can be obtained without forming M = mass_matrix(D) explicitly via left_boundary_weight and right_boundary_weight.\nInstead of forming a mass matrix explicitly, discrete integrals can be evaluated efficiently using integrate.\nDissipation operators based on the same discrete inner product as SBP derivative operators can be obtained via dissipation_operator.","category":"page"},{"location":"introduction/#Next-steps","page":"Introduction","title":"Next steps","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"If you are familiar with SBP operators in general, this introduction might already be enough for you to apply SummationByPartsOperators.jl to your problems. Otherwise, you might want to have a look at the references, the tutorials coming next, or some ready-to-use semidiscretizations of the following partial differential equations (PDEs). These are shipped with this package and you are encouraged to look at their source code to learn more about it.","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Linear scalar advection with variable coefficient: VariableLinearAdvectionPeriodicSemidiscretization, VariableLinearAdvectionNonperiodicSemidiscretization\nBurgers' equation (inviscid): BurgersPeriodicSemidiscretization, BurgersNonperiodicSemidiscretization\nScalar conservation law with cubic flux: CubicPeriodicSemidiscretization, CubicNonperiodicSemidiscretization\nA scalar conservation law with quartic, non-convex flux: QuarticNonconvexPeriodicSemidiscretization\nThe second-order wave equation: WaveEquationNonperiodicSemidiscretization","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"Some additional examples are included as Jupyter notebooks in the directory notebooks. Even more examples and research articles making use of SummationByPartsOperators.jl are listed in the section Applications. If you want to know even more, you can have a look at the test.","category":"page"},{"location":"introduction/#References","page":"Introduction","title":"References","text":"","category":"section"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"[SvärdNordström2014]: Svärd, Nordström (2014). Review of summation-by-parts schemes for initial–boundary-value problems. DOI: 10.1016/j.jcp.2014.02.031","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"[FernándezHickenZingg2014]: Fernández, Hicken, Zingg (2014). Review of summation-by-parts operators with simultaneous approximation terms for the numerical solution of partial differential equations. DOI: 10.1016/j.compfluid.2014.02.016","category":"page"},{"location":"introduction/","page":"Introduction","title":"Introduction","text":"[RanochaMitsotakisKetcheson2021]: Ranocha, Mitsotakis, Ketcheson (2021). A Broad Class of Conservative Numerical Methods for Dispersive Wave Equations. DOI: 10.4208/cicp.OA-2020-0119","category":"page"},{"location":"tutorials/basic_interface/#Basic-interface","page":"Basic interface","title":"Basic interface","text":"","category":"section"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"Here, we discuss the basic interface of SummationByPartsOperators.jl. We assume you are already familiar with the concept of SBP operators in general and the introduction describing how to construct specific operators.","category":"page"},{"location":"tutorials/basic_interface/#Applying-SBP-operators","page":"Basic interface","title":"Applying SBP operators","text":"","category":"section"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"All SBP operators implement the general interface of matrix vector multiplication in Julia. The most simple version is to just use *, e.g.,","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nx = grid(D)\n\nu = @. sin(pi * x)\n\nD * u\n\n@allocated D * u","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"As you can see above, calling D * u allocates a new vector for the result. If you want to apply an SBP operator multiple times and need good performance, you should consider using pre-allocating the output and using in-place update instead. This strategy is also described in the performance tips in the Julia manual. Julia provides the function mul! for this purpose.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using LinearAlgebra, InteractiveUtils\n\n@doc mul!","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"To improve the performance, you can pre-allocate an output vector and call the non-allocating function mul!.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nx = grid(D)\n\nu = @. sin(pi * x)\n\ndu = similar(u); mul!(du, D, u)\n\ndu ≈ D * u\n\n@allocated mul!(du, D, u)","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"All operators provided by SummationByPartsOperators.jl implement this 3-argument version of mul!. Most operators also implement the 5-argument version of mul! that can be used to scale the output and add it to some multiple of the result vector.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nx = grid(D); u = @. sin(pi * x); du = similar(u); mul!(du, D, u);\n\nmul!(du, D, u, 2) # equivalent to du .= 2 * D * u\n\ndu ≈ 2 * D * u\n\n@allocated mul!(du, D, u, 2)\n\ndu_background = rand(length(du)); du .= du_background\n\nmul!(du, D, u, 2, 3) # equivalent to du .= 2 * D * u + 3 * du\n\ndu ≈ 2 * D * u + 3 * du_background\n\n@allocated mul!(du, D, u, 2, 3)","category":"page"},{"location":"tutorials/basic_interface/#Integration-and-the-mass/norm-matrix","page":"Basic interface","title":"Integration and the mass/norm matrix","text":"","category":"section"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"SBP operators come with a mass matrix yielding a quadrature rule. In SummationByPartsOperators.jl, all operators typically have diagonal mass/norm matrices. You can access them via mass_matrix, e.g.,","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nmass_matrix(D)\n\nD = periodic_derivative_operator(derivative_order = 1,\n accuracy_order = 2,\n xmin = 0.0, xmax = 1.0,\n N = 8)\n\nmass_matrix(D)","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"If you want to use the quadrature associated with a mass matrix, you do not need to form it explicitly. Instead, it is recommended to use the function integrate, e.g.,","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nM = mass_matrix(D)\n\nx = grid(D)\n\nu = x.^2\n\nintegrate(u, D)\n\nintegrate(u, D) ≈ sum(M * u)\n\nintegrate(u, D) ≈ integrate(x -> x^2, x, D)","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"For example, you can proceed as follows to compute the error of the SBP operator when computing a derivative as follows.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nM = mass_matrix(D)\n\nx = grid(D)\n\ndifference = D * x.^3 - 3 * x.^2\n\nerror_l2 = sqrt(integrate(abs2, difference, D))","category":"page"},{"location":"tutorials/basic_interface/#Multi-dimensional-cases-or-multiple-variables","page":"Basic interface","title":"Multi-dimensional cases or multiple variables","text":"","category":"section"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"If you want to work with multiple space dimensions, you can still use the 1D operators provided by SummationByPartsOperators.jl if you apply them in a tensor product fashion along each space dimension.","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"using SummationByPartsOperators\n\nD = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 4,\n xmin = 0.0, xmax = 1.0, N = 9)\n\nx = y = grid(D)\n\nu = x .* y'.^2 # u(x, y) = x y^2\n\nlet du_dx = zero(u)\n for j in axes(u, 2)\n mul!(view(du_dx, :, j), D, view(u, :, j))\n end\n # The derivative of x*y^2 with respect to x is just y^2.\n # Thus, the result is constant in each column and varies\n # in the rows.\n du_dx\nend\n\nlet du_dy = zero(u)\n for i in axes(u, 1)\n mul!(view(du_dy, i, :), D, view(u, i, :))\n end\n # The derivative of x*y^2 with respect to y is 2*x*y.\n du_dy\nend\n\n2 .* x .* y'","category":"page"},{"location":"tutorials/basic_interface/","page":"Basic interface","title":"Basic interface","text":"Here, we have used views to interpret parts of the memory of the multi-dimensional arrays as one-diemnsional vectors that can be used together with the operators of SummationByPartsOperators.jl. You can use the same trick if you collect values of multiple variables in a multi-dimensional array.","category":"page"},{"location":"#SummationByPartsOperators.jl","page":"Home","title":"SummationByPartsOperators.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The Julia library SummationByPartsOperators.jl provides a unified interface of different discretization approaches including finite difference, Fourier pseudospectral, continuous Galerkin, and discontinuous Galerkin methods. This unified interface is based on the notion of summation-by-parts (SBP) operators. Originally developed for finite difference methods, SBP operators are discrete derivative operators designed specifically to get provably stable (semi-) discretizations, mimicking energy/entropy estimates from the continuous level discretely and paying special attention to boundary conditions.","category":"page"},{"location":"","page":"Home","title":"Home","text":"SummationByPartsOperators.jl is mainly written to be useful for both students learning the basic concepts and researchers developing new numerical algorithms based on SBP operators. Thus, this package uses Julia's multiple dispatch and strong type system to provide a unified framework of all of these seemingly different discretizations while being reasonably optimized at the same time, achieving good performance without sacrificing flexibility.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"SummationByPartsOperators.jl is a registered Julia package. Thus, you can install it from the Julia REPL via","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.add(\"SummationByPartsOperators\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"If you want to update SummationByPartsOperators.jl, you can use","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.update(\"SummationByPartsOperators\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"As usual, if you want to update SummationByPartsOperators.jl and all other packages in your current project, you can execute","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using Pkg; Pkg.update()","category":"page"},{"location":"#Basic-examples","page":"Home","title":"Basic examples","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Compute the derivative on a periodic domain using a central finite difference operator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using SummationByPartsOperators\n\njulia> using Plots: plot, plot!\n\njulia> D = periodic_derivative_operator(derivative_order = 1,\n accuracy_order = 2,\n xmin = 0.0, xmax = 2.0,\n N = 20)\nPeriodic first-derivative operator of order 2 on a grid in [0.0, 2.0] using 20 nodes,\nstencils with 1 nodes to the left, 1 nodes to the right, and coefficients of Fornberg (1998)\n Calculation of Weights in Finite Difference Formulas.\n SIAM Rev. 40.3, pp. 685-691.\n\njulia> x = grid(D); u = sinpi.(x);\n\njulia> plot(x, D * u, label = \"numerical\")\n\njulia> plot!(x, π .* cospi.(x), label = \"analytical\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"You should see a plot like the following.","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"","page":"Home","title":"Home","text":"Compute the derivative on a bounded domain using an SBP finite difference operator.","category":"page"},{"location":"","page":"Home","title":"Home","text":"julia> using SummationByPartsOperators\n\njulia> using Plots: plot, plot!\n\njulia> D = derivative_operator(MattssonNordström2004(),\n derivative_order = 1, accuracy_order = 2,\n xmin = 0.0, xmax = 1.0, N = 21)\nSBP first-derivative operator of order 2 on a grid in [0.0, 1.0] using 21 nodes\nand coefficients of Mattsson, Nordström (2004)\n Summation by parts operators for finite difference approximations of second\n derivatives.\n Journal of Computational Physics 199, pp. 503-540.\n\njulia> x = grid(D); u = exp.(x);\n\njulia> plot(x, D * u, label = \"numerical\")\n\njulia> plot!(x, exp.(x), label = \"analytical\")","category":"page"},{"location":"","page":"Home","title":"Home","text":"You should see a plot like the following.","category":"page"},{"location":"","page":"Home","title":"Home","text":"(Image: )","category":"page"},{"location":"#Referencing","page":"Home","title":"Referencing","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you use SummationByPartsOperators.jl for your research, please cite it using the bibtex entry","category":"page"},{"location":"","page":"Home","title":"Home","text":"@article{ranocha2021sbp,\n title={{SummationByPartsOperators.jl}: {A} {J}ulia library of provably stable\n semidiscretization techniques with mimetic properties},\n author={Ranocha, Hendrik},\n journal={Journal of Open Source Software},\n year={2021},\n month={08},\n doi={10.21105/joss.03454},\n volume={6},\n number={64},\n pages={3454},\n publisher={The Open Journal},\n url={https://github.com/ranocha/SummationByPartsOperators.jl}\n}","category":"page"},{"location":"","page":"Home","title":"Home","text":"Please also cite the appropriate references for specific SBP operators you use, which can be obtained via source_of_coefficients.","category":"page"},{"location":"#License-and-contributing","page":"Home","title":"License and contributing","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This project is licensed under the MIT license (see License). Since it is an open-source project, we are very happy to accept contributions from the community. Please refer to the section Contributing for more details.","category":"page"}] } diff --git a/dev/tutorials/advection_diffusion/index.html b/dev/tutorials/advection_diffusion/index.html index 1826a6ae..3573a47f 100644 --- a/dev/tutorials/advection_diffusion/index.html +++ b/dev/tutorials/advection_diffusion/index.html @@ -74,4 +74,4 @@ JULIA_PKG_SERVER_REGISTRY_PREFERENCE = eager Status `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl/docs/Manifest.toml` [1dea7af3] OrdinaryDiffEq v6.51.2 - [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` + [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` diff --git a/dev/tutorials/basic_interface/index.html b/dev/tutorials/basic_interface/index.html index 1d42f5c5..1a6b28a7 100644 --- a/dev/tutorials/basic_interface/index.html +++ b/dev/tutorials/basic_interface/index.html @@ -96,15 +96,15 @@ Summation by parts operators for finite difference approximations of second derivatives. Journal of Computational Physics 199, pp. 503-540.
julia> x = grid(D); u = @. sin(pi * x); du = similar(u); mul!(du, D, u);
julia> mul!(du, D, u, 2) # equivalent to du .= 2 * D * u
julia> du ≈ 2 * D * utrue
julia> @allocated mul!(du, D, u, 2)0
julia> du_background = rand(length(du)); du .= du_background9-element Vector{Float64}: - 0.3925569656274246 - 0.5926824134813977 - 0.49999405510078 - 0.1496705748268896 - 0.5361482640845132 - 0.5354985071406062 - 0.6233668393908027 - 0.30452725977531436 - 0.46370920236818636
julia> mul!(du, D, u, 2, 3) # equivalent to du .= 2 * D * u + 3 * du
julia> du ≈ 2 * D * u + 3 * du_backgroundtrue
julia> @allocated mul!(du, D, u, 2, 3)0

Integration and the mass/norm matrix

SBP operators come with a mass matrix yielding a quadrature rule. In SummationByPartsOperators.jl, all operators typically have diagonal mass/norm matrices. You can access them via mass_matrix, e.g.,

julia> using SummationByPartsOperators
julia> D = derivative_operator(MattssonNordström2004(), + 0.8258783766045397 + 0.6130782684711269 + 0.740951193761477 + 0.48156249863334866 + 0.40789502762647634 + 0.7144352391867894 + 0.28105225579133397 + 0.16225267276273247 + 0.8649698830852659
julia> mul!(du, D, u, 2, 3) # equivalent to du .= 2 * D * u + 3 * du
julia> du ≈ 2 * D * u + 3 * du_backgroundtrue
julia> @allocated mul!(du, D, u, 2, 3)0

Integration and the mass/norm matrix

SBP operators come with a mass matrix yielding a quadrature rule. In SummationByPartsOperators.jl, all operators typically have diagonal mass/norm matrices. You can access them via mass_matrix, e.g.,

julia> using SummationByPartsOperators
julia> D = derivative_operator(MattssonNordström2004(), derivative_order = 1, accuracy_order = 2, xmin = 0.0, xmax = 1.0, N = 9)SBP first-derivative operator of order 2 on a grid in [0.0, 1.0] using 9 nodes and coefficients of Mattsson, Nordström (2004) @@ -230,4 +230,4 @@ 0.0 0.15625 0.3125 0.46875 0.625 0.78125 0.9375 1.09375 1.25 0.0 0.1875 0.375 0.5625 0.75 0.9375 1.125 1.3125 1.5 0.0 0.21875 0.4375 0.65625 0.875 1.09375 1.3125 1.53125 1.75 - 0.0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0

Here, we have used views to interpret parts of the memory of the multi-dimensional arrays as one-diemnsional vectors that can be used together with the operators of SummationByPartsOperators.jl. You can use the same trick if you collect values of multiple variables in a multi-dimensional array.

+ 0.0 0.25 0.5 0.75 1.0 1.25 1.5 1.75 2.0

Here, we have used views to interpret parts of the memory of the multi-dimensional arrays as one-diemnsional vectors that can be used together with the operators of SummationByPartsOperators.jl. You can use the same trick if you collect values of multiple variables in a multi-dimensional array.

diff --git a/dev/tutorials/constant_linear_advection/index.html b/dev/tutorials/constant_linear_advection/index.html index 75b82d47..29daba45 100644 --- a/dev/tutorials/constant_linear_advection/index.html +++ b/dev/tutorials/constant_linear_advection/index.html @@ -105,4 +105,4 @@ JULIA_PKG_SERVER_REGISTRY_PREFERENCE = eager Status `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl/docs/Manifest.toml` [1dea7af3] OrdinaryDiffEq v6.51.2 - [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` + [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` diff --git a/dev/tutorials/kdv/index.html b/dev/tutorials/kdv/index.html index b87e35ef..1c2121c1 100644 --- a/dev/tutorials/kdv/index.html +++ b/dev/tutorials/kdv/index.html @@ -101,4 +101,4 @@ JULIA_PKG_SERVER_REGISTRY_PREFERENCE = eager Status `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl/docs/Manifest.toml` [1dea7af3] OrdinaryDiffEq v6.51.2 - [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` + [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` diff --git a/dev/tutorials/variable_linear_advection/index.html b/dev/tutorials/variable_linear_advection/index.html index d998a3fc..d9595fa2 100644 --- a/dev/tutorials/variable_linear_advection/index.html +++ b/dev/tutorials/variable_linear_advection/index.html @@ -54,4 +54,4 @@ JULIA_PKG_SERVER_REGISTRY_PREFERENCE = eager Status `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl/docs/Manifest.toml` [1dea7af3] OrdinaryDiffEq v6.51.2 - [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` + [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` diff --git a/dev/tutorials/wave_equation/index.html b/dev/tutorials/wave_equation/index.html index 00dbe636..1c6c7b96 100644 --- a/dev/tutorials/wave_equation/index.html +++ b/dev/tutorials/wave_equation/index.html @@ -76,4 +76,4 @@ JULIA_PKG_SERVER_REGISTRY_PREFERENCE = eager Status `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl/docs/Manifest.toml` [1dea7af3] OrdinaryDiffEq v6.51.2 - [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl` + [9f78cca6] SummationByPartsOperators v0.5.61 `~/work/SummationByPartsOperators.jl/SummationByPartsOperators.jl`