PDE Architecture & Exact Solutions

Every equation is a struct subtyping HyperbolicPDE{D, M, T}, where D is the spatial dimension, M the number of variables and T the floating-point type. The numerical schemes only access an equation through a small set of functions, so new physics plugs in without touching the solver. The full contract, including which scheme needs which method, is HyperCloudCore's API Contracts.

Equation interface

FunctionRequiredReturns
flux(eq, U)yesFlux{D, M, T}: the physical flux $F_d(U)$ for every direction d.
max_eigenvalue(eq, U, d)yesLargest absolute wave speed in direction d (used for the CFL step and Rusanov flux).
prim2cons(eq, V), cons2prim(eq, U)yesConversion between primitive and conservative variables (identity for scalar laws).
velocity(eq, U, d)upwind schemes, WENO, UpwindFluxFlux Jacobian $\partial F_d / \partial U$ as an M × M static matrix.
fluid_velocity(eq, U)Lagrangian grid moversVelocity the particles move with, a Space{D, T}.
is_admissible(eq, U)optionalPhysical admissibility for MOOD (default: all components finite).
max_eigenvalue(eq, U, d, shift)optionalExact relative wave speed on moving grids.
kinetic_wave_speed(eq, d, k)kinetic systemsSpeed of kinetic variable k in direction d.
analytic_closure(eq, ic, geom)optionalExact solution, see below.

The functions run inside the time step, on a GPU as device code, so they have to follow HyperCloudCore's rules for kernel bodies. Import them from HyperCloudCore before adding methods (import HyperCloudCore: flux, max_eigenvalue).

A builder method makes the equation available from configurations:

function HyperCloud.build_equation(::Val{:my_pde}, pde_conf::Dict, context::Dict)
    T = context[:T]::DataType
    return MyPDE{pde_conf[:D], T}()
end

Representations

Some equations exist in several formulations. They carry a representation tag, a subtype of EquationRepresentation. Conservative is the conservative form; NCRepresentation covers non-conservative (e.g. primitive) forms, whose integration paths are configured through parse_representation. Methods such as flux and max_eigenvalue dispatch on the tag.

Exact solutions

analytical_solution builds the equation, domain and initial condition from a configuration and calls analytic_closure. The result is a closure

exact = analytical_solution(params)
exact(SVector(x..., t))   # -> State{M}

that evaluates the exact solution at any spacetime point. It is used as the reference for error statistics and plots. The reference is computed in params[:real_type] (default Float64), independently of the simulation precision.

Exact solutions currently available:

EquationInitial conditionDimension
LinearAdvectionanyany D (commuting velocity matrices)
BurgersEquationRiemann, SRiemannany D
BurgersEquationGaussany D, before the breaking time
BurgersEquationBox1D
EulerEquationRiemann1D

Other combinations fall back to a warning. Burgers returns the initial condition (exact only at t = 0); every other equation returns nothing.

To add an exact solution, add a method for your combination:

function HyperCloud.analytic_closure(eq::MyPDE{D, T}, ic::Gauss, geom::GeometricDomain) where {D, T}
    # precompute everything that does not depend on (x, t) here
    return function (st::SVector)
        t = T(st[end])
        x = SVector{D, T}(ntuple(d -> T(st[d]), Val(D)))
        # ...
        return State{1, T}(u)
    end
end

geom gives access to the domain bounds (geom.mins, geom.maxs) and periodicity (geom.is_periodic).

API

HyperCloud.analytical_solution — Function
analytical_solution(shared_params::ParamDict)

Builds the equation, domain and initial condition from the PDE, Grid and IC namespaces and returns the standalone closure exact_u(st) from analytic_closure. st is the spacetime vector SVector(x..., t).

The reference is computed in shared_params[:real_type] (default Float64), independently of the simulation precision :T, so Float32 runs are still compared to a Float64 reference.

source
HyperCloud.analytic_closure — Function
analytic_closure(eq::HyperbolicPDE, ic::InitialCondition, geom::GeometricDomain)

Returns a closure st -> State{M} evaluating the exact solution at the spacetime point st = SVector(x..., t). PDEs add methods for the initial conditions they can solve exactly.

This generic fallback only emits a warning and returns nothing when no method exists for the combination of equation, initial condition and domain.

source
HyperCloud.EquationRepresentation — Type
EquationRepresentation

Abstract base type for categorizing the mathematical formulation of a PDE system.

Subtypes

  • Conservative: Concrete type indicating the system evaluates standard conservative fluxes and eigenvalues.
  • NCRepresentation: Abstract type for non-conservative evaluations (e.g., primitive or Lagrangian representations).
source