Skip to content

Initial conditions ​

The initial state is set by the [initial_conditions] section: type selects one of the fourteen initial conditions below, and the primitive states of the regions are given in [initial_conditions_region_N] sections. The value of every key is checked: an unknown type, a missing key or an inconsistent value stops the run with a message naming the accepted values.

typeEulerMHD (none)MHD (glm)Region sections
uniform✓✓✓1
isentropic-vortex✓✗✗1
riemann-problem✓✓✓regions_number
shu-osher✓✗✗2
rotated-riemann✓✓✓2
glm-pulse, divb-peak, mhd-linear-wave, mhd-cpaw, mhd-vortex, mhd-rotor, field-loop✗✓✓1
orszag-tang✗✓✓0
linear (verification)✓✓✓1
polytrope (self-gravity)✓✗✗1 (the atmosphere)

"MHD" in the error messages means [physics] physical_model = mhd-ideal. glm versus none is chosen separately by [mhd] divergence_control.

Conventions ​

State vectors. The conservative variables are q=(ρ,ρu,ρv,ρw,E[,Bx,By,Bz[,ψ]]), with nv=5 (Euler), 8 (MHD, [mhd] divergence_control = none) or 9 (MHD with GLM). The ratio of specific heats is γ=cp/cv and the gas constant is R=cp−cv.

Primitive to conservative conversion is used by every initial condition and by the inflow boundary condition. MHD uses rationalised units, so no 4π appears:

E=pγ−1+12ρ(u2+v2+w2)[+12(Bx2+By2+Bz2)]

Sources: Euler at common/adam_flume_euler_library.F90, MHD at common/adam_flume_mhd_library.F90. The MHD sums go through mhd_sum3, which sorts the three terms before adding them so that a rotated problem gives bitwise-identical results.

ψ at t=0 is always zero. The model dispatcher primitive_state_to_conservative sets q(IQ_PSI) = 0 for MODEL_MHD_GLM. Every initial condition goes through this routine, either directly or through the pre-converted region states q_region. The one exception is mhd-linear-wave, which adds its eigenvector only to components 1–8, so ψ also stays 0 there.

Coordinates. Every initial condition is a point value at the cell centre, not a cell average: field%x_cell(i,b), y_cell(j,b), z_cell(k,b), and xc=xmin−Δx/2+lin_space(i). set_initial_conditions fills only the interior cells 1..ni×1..nj×1..nk. The ghost cells come from the update_ghost call that follows.

Keys common to every type. Both are read from [initial_conditions]:

keytypemeaning
typestring (control characters are blanked by strip_control, so CRLF files parse)one of the 22 names below. Any other value stops the run and the message lists all 22.
amr_iterationsinteger, requiredthe number of init-time AMR passes (set the IC, refine, repeat). The value is clamped to ≥0. The loop is at cpu/adam_flume_cpu_object.F90 and fnl/adam_flume_fnl_object.F90. When the value is >0, every refined non-null axis must have an even block cell count of at least 2 ngc, otherwise error_stop.

Region sections are named [initial_conditions_region_N], with N=1..regions_number. They hold the primitive keys r, u, v, w, p, plus bx, by, bz for either MHD model. Every one of these keys is required. ψ has no key. The number of region sections read depends on the type:

typeregions readextent keys
uniform, isentropic-vortex, glm-pulse, divb-peak, mhd-linear-wave, mhd-cpaw, mhd-vortex, mhd-rotor, field-loop, linear1none
shu-osher, rotated-riemann2none (any extent keys present are ignored)
riemann-problemregions_number (from the INI)emin_x, emin_y, emin_z, emax_x, emax_y, emax_z (required)
orszag-tang0none

uniform: seeded uniform state ​

Model: any. Keys: [initial_conditions] s (real, required), plus region 1.

The state of region 1 is imposed everywhere, with density and pressure perturbed by a relative amplitude s:

ρ=ρ1(1+sh1),p=p1(1+sh2),h1,h2∈[−1,1)

The pair (h1,h2) comes from hash_cell(code, i, j, k). The hash is a chained integer mix of the block Morton code and the cell indexes: xorshift steps (13, 7, 17), then a multiplication by 39083855 modulo 252 in 26-bit limbs. It uses no RNG state, so the values do not depend on the rank decomposition or the backend. The velocity and field are those of region 1.

Validation: none on s. Setting |s|≥1 can produce ρ≤0 or p≤0 without any error at this stage.

Test input: src/tests/flume/verification/uniform/input.ini

ini
[initial_conditions]
type           = uniform
amr_iterations = 0
s              = 0.0 ; relative amplitude of the seeded density/pressure perturbation

[initial_conditions_region_1]
r = 1.2
u = 10.0
v = 0.0
w = 0.0
p = 101325.0

MHD with GLM, from src/tests/flume/verification/mhd/plumbing/mhd-uniform-glm.ini:

ini
[initial_conditions]
type           = uniform
amr_iterations = 0
s              = 0.05 ; relative amplitude of the seeded density/pressure perturbation

[initial_conditions_region_1]
r  = 1.0
u  = 0.3
v  = -0.2
w  = 0.1
p  = 1.0
bx = 0.8
by = 0.5
bz = -0.3

The companion file is mhd-uniform-none.ini, and src/tests/flume/regression/amr-periodic-reflux/input.ini and regression/uniform-amr-mhd/input.ini use this type too.

isentropic-vortex ​

Reference: Shu 1998, ICASE 97-65, §5.1, generalised to any free stream. Model: Euler only. Any other model stops the run with requires [physics].(physical_model) = euler. Keys: x0, y0, radius, strength, plus region 1 (r,u,v,w,p, the free stream). Validation: radius <= 0 stops the run.

Let ε be strength, Rv be radius, x~=(x−x0)/Rv, y~=(y−y0)/Rv and e=exp(12(1−x~2−y~2)). With T0=p1/ρ1:

T=T0−γ−1γε28π2e2,ρ=ρ1(TT0)1/(γ−1),p=ρTu=u1−ε2πy~e,v=v1+ε2πx~e,w=w1

Here T stands for p/ρ, not the thermodynamic temperature. The flow is isentropic (p/ργ is constant) and it satisfies the radial balance ∂rp=ρvθ2/r for any T0 and any Rv, so it is an exact steady solution convected by the free stream. The profile is 2-D; z is not used.

Test input: src/tests/flume/verification/vortex/vortex-n064.ini (and -n128, -n256, regression/vortex-periodic)

ini
[initial_conditions]
type           = isentropic-vortex
amr_iterations = 0
x0             = 0.5
y0             = 0.5
radius         = 0.07
strength       = 5.0

[initial_conditions_region_1]
r = 1.0
u = 1.0
v = 1.0
w = 0.0
p = 1.0

riemann-problem: piecewise-constant axis-aligned regions ​

Model: any. Keys: [initial_conditions] regions_number (integer, required, must be ≥1). Each region section also needs the six extent keys.

A cell with centre c belongs to region r if, for every axis d, emin,d(r)<cd≤emax,d(r). The region sections are scanned in order and the first match wins, so overlapping regions are allowed and region 1 has priority. A cell covered by no region is fatal: cell center (x, y, z) is covered by no [initial_conditions_region_*]. The half-open interval puts a cell centre that sits exactly on an interface into the lower region.

The z extent must also bracket the cell centres, including on 2-D grids with null_z. The tests use emin_z = 0, emax_z = 1.

Test input (Sod along x): src/tests/flume/verification/sod/sod-x.ini

ini
[initial_conditions]
type           = riemann-problem
regions_number = 2
amr_iterations = 0

[initial_conditions_region_1]
r      = 1.0
u      = 0.0
v      = 0.0
w      = 0.0
p      = 1.0
emin_x = 0.0
emin_y = 0.0
emin_z = 0.0
emax_x = 0.5
emax_y = 1.0
emax_z = 1.0

[initial_conditions_region_2]
r      = 0.125
u      = 0.0
v      = 0.0
w      = 0.0
p      = 0.1
emin_x = 0.5
emin_y = 0.0
emin_z = 0.0
emax_x = 1.0
emax_y = 1.0
emax_z = 1.0

MHD (Brio-Wu): src/tests/flume/regression/brio-wu/input.ini

ini
[initial_conditions]
type = riemann-problem
regions_number = 2
amr_iterations = 0

[initial_conditions_region_1]
r = 1.0
u = 0.0
v = 0.0
w = 0.0
p = 1.0
emin_x = 0.0
emin_y = 0.0
emin_z = 0.0
emax_x = 0.5
emax_y = 1.0
emax_z = 1.0
bx = 0.75
by = 1.0
bz = 0.0

[initial_conditions_region_2]
r = 0.125
u = 0.0
v = 0.0
w = 0.0
p = 0.1
emin_x = 0.5
emin_y = 0.0
emin_z = 0.0
emax_x = 1.0
emax_y = 1.0
emax_z = 1.0
bx = 0.75
by = -1.0
bz = 0.0

Other inputs that use this type: sod-{y,z}.ini, sod-wall-{x,y,z}.ini, regression/rj2a-{x,y,z}, regression/sod-{x,y,z}, and the multi-realm *-r1.ini/*-r2.ini files.

shu-osher: shock and density-wave interaction ​

Reference: Shu & Osher 1989, J. Comput. Phys. 83, example 8. Model: Euler only. Any other model stops the run with requires [physics].(physical_model) = euler. Keys: axis, interface, rho_amplitude, rho_wavenumber, plus regions 1 and 2, without extents. Validation: ρ2−|A|≤0 stops the run with rho_amplitude must be smaller than the density of [initial_conditions_region_2].

Let s be the cell-centre coordinate along axis:

q={q1s≤sIq(ρ2+Asin⁡(ks),u2,p2)s>sI

The phase is ks in the absolute coordinate, not k(s−sI).

Test input: the RV-3 shu-osher leg of src/tests/flume/verification/riemann-flux/check.sh (function set_shu_osher) rewrites verification/sod/sod-{x,y,z}.ini, for example:

ini
[initial_conditions]
axis           = x
interface      = -4.0
rho_amplitude  = 0.2
rho_wavenumber = 5.0
type           = shu-osher
regions_number = 2
amr_iterations = 0

[initial_conditions_region_1]
r      = 3.857143
u      = 2.629369
v      = 0.0
w      = 0.0
p      = 10.33333
emin_x = 0.0
emin_y = 0.0
emin_z = 0.0
emax_x = 0.5
emax_y = 1.0
emax_z = 1.0

[initial_conditions_region_2]
r      = 1.0
u      = 0.0
v      = 0.0
w      = 0.0
p      = 1.0
emin_x = 0.5
emin_y = 0.0
emin_z = 0.0
emax_x = 1.0
emax_y = 1.0
emax_z = 1.0

regions_number and the emin_*/emax_* keys are left over from the Sod input and are ignored for this type.

glm-pulse: Gaussian pulse in one field component ​

Reference: the GLM d'Alembert test (issue #41, MV-3). Model: MHD (mhd-ideal, with or without GLM). Euler stops the run with requires [physics].(physical_model) = mhd-ideal. Keys: pulse_axis, pulse_center, pulse_width, pulse_amplitude, plus region 1 (8 keys). Validation: pulse_width <= 0 stops the run. No check stops a pulse along a null axis.

With a the chosen axis and s the cell-centre coordinate along it:

Ba=Ba,1+Aexp(−(s−scσ)2),

All other primitives are those of region 1, and ψ=0. When a is the axis the pulse varies along, the pulse is a pure ∇⋅B error.

Test input: src/tests/flume/regression/glm-pulse/input.ini

ini
[initial_conditions]
type = glm-pulse
amr_iterations = 0
pulse_axis = x
pulse_center = 0.5
pulse_width = 0.1
pulse_amplitude = 0.1

[initial_conditions_region_1]
r = 1.0
u = 0.0
v = 0.0
w = 0.0
p = 1.0
bx = 0.0
by = 0.0
bz = 0.0

(The verification variant is generated by src/tests/flume/verification/mhd/glm-pulse/make_glm_pulse.py.)

divb-peak: Dedner et al. peak in Bx ​

Reference: after Dedner et al. 2002, §5.1 (issue #41, MV-10); the support convention of peak_radius (a radius here) is being checked against the paper. Model: MHD. Keys: peak_x0, peak_y0, peak_radius, peak_amplitude, plus region 1. Validation: peak_radius <= 0 stops the run.

With r~=(x−x0)2+(y−y0)2/R:

Bx=Bx,1+A(1−r~2)2for r~<1,Bx=Bx,1 otherwise.

∇⋅B≠0 at t=0 by construction.

Test input: generated by src/tests/flume/verification/mhd/divb-peak/make_divb_peak.py, for example:

ini
[initial_conditions]
type = divb-peak
amr_iterations = 1
peak_x0 = 0.0
peak_y0 = 0.0
peak_radius = 0.125
peak_amplitude = 0.28209479177387814

[initial_conditions_region_1]
r = 1.0
u = 1.0
v = 1.0
w = 0.0
p = 6.0
bx = 0.0
by = 0.0
bz = 0.28209479177387814

mhd-linear-wave: small-amplitude MHD eigenmode ​

Reference: Stone et al. 2008, ApJS 178, §8.2 (issue #41, MV-5). The eigenvector normalisation is that of Stone et al. 2008, appendix B. Model: MHD. Keys: wave, wave_angle (degrees, in the x-y plane), wave_amplitude, wavelength, plus region 1, which is the background q0 in the global frame. Validation: wavelength <= 0 stops the run.

The background is rotated into the wave frame, un=cu+sv, ut=−su+cv, and likewise for B, with c=cos⁡α, s=sin⁡α. The right eigenvectors of the x-direction system of that frame are then computed (mhd_eigenvectors, d = 1; tangents are cyclic, so t1=y′, t2=z). The column k is chosen from the wave, in the order (un−cf,un−ca,un−cs,un,un+cs,un+ca,un+cf,Bn):

wavecolumneigenvalue
fast7un+cf
alfven6un+ca
slow5un+cs
entropy4un

The momentum and field components of rk are rotated back, rx=crn−srt, ry=srn+crt. Each cell then gets:

q(x,y)=q0+Asin(2π(xcos⁡α+ysin⁡α)λ)rk(components 1..8; ψ=0)

The perturbation is added to the conservative vector, and A is measured in the normalisation of rk.

Test input: generated by src/tests/flume/verification/mhd/linear-wave/make_linear_wave.py, for example:

ini
[initial_conditions]
type = mhd-linear-wave
amr_iterations = 0
wave = alfven
wave_angle = 0.0
wave_amplitude = 1.0e-7
wavelength = 1.0

[initial_conditions_region_1]
r = 1.0
u = 0.0
v = 0.0
w = 0.0
p = 0.6
bx = 1.0
by = 1.4142135623730951
bz = 0.5

mhd-cpaw: circularly polarised Alfvén wave ​

Reference: Tóth 2000, J. Comput. Phys. 161 (issue #41, MV-6). This is an exact nonlinear solution of any amplitude. Model: MHD. Keys: polarisation (right gives h=+1, left gives h=−1; any other value is fatal), wave_angle, wave_amplitude, wavelength, b_par, plus region 1. Validation: wavelength <= 0 is fatal and b_par == 0 is fatal. Region 1 must have u = v = w = bx = by = bz = 0, otherwise the run stops. Only ρ1 and p1 are used.

With α = wave_angle, n=(cos⁡α,sin⁡α,0), t1=(−sin⁡α,cos⁡α,0), t2=z^ and ϕ=2π(xcos⁡α+ysin⁡α)/λ:

B⊥=A(sin⁡ϕt1+hcos⁡ϕt2),B=b∥n+B⊥,u=−sign(b∥)B⊥ρ1

ρ=ρ1 and p=p1 everywhere. |B⊥| is uniform, so the total pressure is uniform too. The wave travels along +n at |b∥|/ρ1, and after one period λρ1/|b∥| the exact solution is the initial state.

Test input: generated by src/tests/flume/verification/mhd/cpaw/make_cpaw.py, for example:

ini
[initial_conditions]
type = mhd-cpaw
amr_iterations = 0
polarisation = left
b_par = 1.0
wave_angle = 63.43494882292201
wave_amplitude = 0.1
wavelength = 1.0

[initial_conditions_region_1]
r = 1.0
u = 0.0
v = 0.0
w = 0.0
p = 0.1
bx = 0.0
by = 0.0
bz = 0.0

mhd-vortex: magnetised vortex ​

Reference: Balsara 2004, ApJS 151 (issue #41, MV-7). Model: MHD. Keys: x0, y0, radius, kappa, mu, plus region 1 (the free stream). Validation: radius <= 0 is fatal. Region 1 must have bx = by = 0, otherwise error_stop with the message "an equilibrium only without an in-plane free-stream field". bz is kept.

With x~=(x−x0)/Rv, y~=(y−y0)/Rv, r~2=x~2+y~2 and e=exp(12(1−r~2)):

u=u1−κ2πy~e,v=v1+κ2πx~e,Bx=−μ2πy~e,By=μ2πx~e,p=p1+μ2(1−r~2)−ρ1κ28π2e2,ρ=ρ1, w=w1, Bz=Bz,1.

The field is divergence-free pointwise, and the vortex is an exact steady equilibrium convected by the free stream.

Test input: generated by src/tests/flume/verification/mhd/vortex/make_mhd_vortex.py, for example:

ini
[initial_conditions]
type = mhd-vortex
amr_iterations = 0
x0 = 0.0
y0 = 0.0
radius = 1.0
kappa = 1.0
mu = 1.0

[initial_conditions_region_1]
r = 1.0
u = 1.0
v = 1.0
w = 0.0
p = 1.0
bx = 0.0
by = 0.0
bz = 0.0

orszag-tang ​

Reference: Stone et al. 2008, §8.4 (issue #41, MV-12). Model: MHD. Keys: none beyond type and amr_iterations. regions_number = 0, so no region section is read. The unit period is assumed: the domain is not checked against [0,1]2.

With s=2x−1 and t=2y−1:

ρ=2536π,p=512π,u=sin⁡(πt),v=−sin⁡(πs),w=0,Bx=sin⁡(πt)4π,By=sin⁡(2πs)4π,Bz=0.

These equal the textbook u=−sin⁡2πy, v=sin⁡2πx, Bx=−sin⁡(2πy)/4π, By=sin⁡(4πx)/4π. The code evaluates them as odd functions of s,t so that the state is bitwise symmetric under the 180° rotation about (1/2,1/2) when cell centres are binary fractions.

Test input: src/tests/flume/regression/orszag-tang/input.ini

ini
[initial_conditions]
type = orszag-tang
amr_iterations = 0

mhd-rotor ​

Reference: Balsara & Spicer 1999 and Tóth 2000, first rotor (issue #41, MV-13). Model: MHD. Keys: x0, y0, r0, r1, rho_in, v0, plus region 1 (ambient). Validation: the run stops unless 0<r0<r1, with the message needs 0 < r0 < r1, and stops if ρin≤0.

With Δx=x−x0, Δy=y−y0 and r=Δx2+Δy2:

r<r0:ρ=ρin,(u,v)=(u1,v1)+v0r0(−Δy, Δx)r0≤r<r1:f=r1−rr1−r0,ρ=ρ1+(ρin−ρ1)f,(u,v)=(u1,v1)+fv0r(−Δy, Δx)

Pressure, w and B are those of region 1 everywhere, and the rotation velocity is added to the ambient one.

Test input: src/tests/flume/regression/rotor/input.ini

ini
[initial_conditions]
type = mhd-rotor
amr_iterations = 0
x0 = 0.5
y0 = 0.5
r0 = 0.1
r1 = 0.115
rho_in = 10.0
v0 = 2.0

[initial_conditions_region_1]
r = 1.0
u = 0.0
v = 0.0
w = 0.0
p = 1.0
bx = 1.4104739588693909
by = 0.0
bz = 0.0

field-loop: advected field loop ​

Reference: Gardiner & Stone 2005; Mignone & Tzeferacos 2010, §4.4.1 (issue #41, MV-9). Model: MHD. Keys: x0, y0, loop_radius, loop_amplitude. The centre keys are plain x0/y0, not loop_x0. Region 1 is also required. Validation: loop_radius <= 0 is fatal.

The field comes from the vector potential Az=A(R−r) for r<R, where r=|(x−x0,y−y0)|. Its curl is computed analytically at the cell centre:

0<r<R:Bx=Bx,1−Ay−y0r,By=By,1+Ax−x0r;otherwise B=B1.

The centre cell itself (r=0 exactly) is excluded. The field is point-sampled and not built from a discrete curl of Az, so the discrete ∇⋅B is non-zero at the loop edge (the discontinuity at r=R). With a uniform w≠0 this discrete divergence feeds Bz.

Test input: src/tests/flume/regression/field-loop/input.ini

ini
[initial_conditions]
type = field-loop
amr_iterations = 0
x0 = 0.0
y0 = 0.0
loop_radius = 0.3
loop_amplitude = 1.0e-3

[initial_conditions_region_1]
r = 1.0
u = 2.0
v = 1.0
w = 1.0
p = 1.0
bx = 0.0
by = 0.0
bz = 0.0

rotated-riemann: 1-D Riemann problem rotated in x-y, periodic along its normal ​

Reference: Tóth 2000, J. Comput. Phys. 161, §6.3.2 (issue #41, MV-8). Model: any. It is not restricted to MHD; for Euler only u, v are rotated. Keys: normal_x, normal_y, interface_1, interface_2, period, interface_2_width, plus regions 1 and 2. The region states are given in the frame of the normal: u and bx are the normal components, v and by the tangential ones, w and bz lie along z. Validation:

  • normal_x = normal_y = 0 is fatal;
  • period <= 0 is fatal;
  • the run stops unless I1<I2, w≥0 and I2+w<I1+P.

Rotation to x, y. With n^=n/|n| and t^=(−n^y,n^x): u=unn^x−utn^y, v=unn^y+utn^x, and the same for B.

Region assignment. Let s=nxx+nyy (unnormalised), f=mod(s−I1,P) and d=I2−I1:

q={q20<f≤dq(P2+(P1−P2)f−dw)d<f<d+w(linear ramp in the global-frame primitives)q1otherwise (including f=0 and f≥d+w)

With w=0 the ramp branch is empty, so there is no division by zero. With integer normal components on a square domain of side P, the state is periodic in both x and y.

Test input: src/tests/flume/regression/rotated-shock-tube/input.ini

ini
[initial_conditions]
type = rotated-riemann
amr_iterations = 0
normal_x = 1.0
normal_y = 2.0
interface_1 = 0.25390625
interface_2 = 0.50390625
interface_2_width = 0.4
period = 1.0

[initial_conditions_region_1]
r = 1.0
u = 10.0
v = 0.0
w = 0.0
p = 20.0
bx = 1.4104739588693909
by = 1.4104739588693909
bz = 0.0

[initial_conditions_region_2]
r = 1.0
u = -10.0
v = 0.0
w = 0.0
p = 1.0
bx = 1.4104739588693909
by = 1.4104739588693909
bz = 0.0

linear: a linear field (verification) ​

Every conservative variable is linear in space,

q(x)=q1(1+g⋅x),

where q1 is the conservative state of [initial_conditions_region_1] and g = (gradient_x, gradient_y, gradient_z) a relative gradient (inverse length; the [reference] layer scales it by L0). The three keys are required.

It is not a flow. It is the field on which every ghost fill FLUME uses is exact: the same-level copy, the 2:1 restriction (the mean of the fine cells) and the tricubic coarse-to-fine fill reproduce a linear field to round-off, and every boundary condition maps it to a known value. The ghost probe GP (verification, verification/ghosts/) runs it for one negligible step (CFL = 1e-30) and checks every face and edge ghost against that value. The state is admissible only while 1+g⋅x>0 over the domain; nothing checks it, since the probe takes no real step. Give the velocity non-zero components, so that every wall sign flip shows.

ini
[initial_conditions]
type = linear
gradient_x = 0.05
gradient_y = 0.11
gradient_z = 0.07
amr_iterations = 1

[initial_conditions_region_1]
r = 1.0
u = 0.3
v = -0.2
w = 0.1
p = 1.0

polynomial: a polynomial field (verification) ​

The linear field raised to a per-direction degree n = degree (an integer, at least 1; n=1 is linear):

q(x)=q1(1+∑dgdxdn).

The keys are those of linear plus degree, all required. The copies and every boundary condition still map it to a known value (they copy cells), but each seam operator reproduces it only up to its degree: the mean restriction and the restriction-compatible fill n=1, the tricubic fill n=3, the lagrange6 restriction and the quintic fill n=5 (#68 D1). GP with --degree N runs it, so the probe checks the high-order seam operators in situ: their footprints, shifts and every exchange path. gd has dimension L−n, which the [reference] layer does not convert: a reference with polynomial is fatal.

sine-wave: a small sine wave on a uniform state (verification) ​

A sine of amplitude A along the unit normal n=(cos⁡θ,sin⁡θ,0) in the x-y plane, on the state of [initial_conditions_region_1] (ρ0, u0, p0), with s=Asin⁡(2πn⋅x/λ):

wave_modePerturbationwave_amplitude
shearu=u0+st, t=(−sin⁡θ,cos⁡θ,0)a velocity
acousticρ=ρ0(1+s), u=u0+a0sn, p=p0(1+γs): the right-running linear acoustic waverelative
entropyρ=ρ0(1+s): a density wave at uniform velocity and pressure, advected exactly (under a constant gravity it falls freely: the convergence case of the gravity sources, verification)relative
magnetic (MHD)B=B0+st: a transverse field, which decays by resistivity and, with B0⋅n≠0, drives a damped Alfvén wavea field
jeans (self-gravity)ρ=ρ0(1+s), p=p0(1+γs) and, with ω2=a02k2−4πGρ0, k=2π/λ: for ω2≥0 the right-running Jeans wave, u=u0+(ω/k)sn; for ω2<0 the growing mode, u=u0+(σ/k)Acos⁡(2πn⋅x/λ)n, σ2=−ω2 (#81, verification)relative

Keys: wave_mode (shear, acoustic, entropy, magnetic or jeans, other → fatal; magnetic needs mhd-ideal, jeans needs [gravity] self_gravity), wave_angle θ (degrees), wave_amplitude A, wavelength λ (> 0). The values are point values at the cell centres. It is the initial state of the viscous verifications VV-1 (shear-wave decay) and VV-2 (viscous-thermal acoustic attenuation) (verification) and of the Ohmic ones VV-5 and VV-6 (verification); the wave is periodic in a box whose sides are multiples of λ/cos⁡θ and λ/sin⁡θ.

ini
[initial_conditions]
type           = sine-wave
amr_iterations = 0
wave_mode      = shear
wave_angle     = 45.0
wave_amplitude = 1.0e-4
wavelength     = 0.7071067811865476

couette: exact compressible Couette flow (verification) ​

The steady compressible Couette flow with constant μ and k (Euler with a viscosity and a conductivity, constant law; fatal otherwise): a fixed isothermal wall at y0, an adiabatic wall at y0+H moving at U along x, uniform pressure p0 ([initial_conditions_region_1] p; the other region keys are read and ignored), and, with s=y−y0,

u=UsH,T=Tw+μU2kH(s−s22H),ρ=p0RT.

It is an exact solution of the compressible Navier–Stokes equations, so a run started from it keeps it as its exact solution at every time, and any departure is the error of the scheme (VV-3, with the walls wall-isothermal at y0 and wall-noslip with wall_u = U at y0+H). Keys: wall_y0, height (H>0), wall_velocity (U), wall_temperature (Tw>0, the code temperature p/(ρR)).

becker-shock: Becker's exact viscous shock (verification) ​

Becker's (1922) steady shock along x, in the shock frame: constant viscosity and Prandtl number 3/4 ([physics] prandtl = 0.75, fatal otherwise), for which the total enthalpy H=cpT+u2/2 is uniform and the momentum integral reduces to 43μuu′=mγ+12γ(u−u1)(u−u2), m=ρ1u1. Its solution is the implicit

K(x−x0)=F(u)−F(u1+u22),F(u)=u1ln⁡(u1−u)−u2ln⁡(u−u2)u1−u2,K=3m(γ+1)8γμ,

solved by bisection in each cell (F is monotone). The upstream state is ρ1, p1 of [initial_conditions_region_1] moving at u1=Ma1 towards +x; u2 is the Rankine–Hugoniot downstream velocity, ρ=m/u, T=(H−u2/2)/cp. Keys: mach (M>1), shock_x0. Pair it with an inflow of the upstream state at bc_x_min and extrapolation at bc_x_max. It is the initial state of VV-4: like couette, an exact steady solution, so the error needs no relaxation run and no fit of the shock position.

isothermal-atmosphere, polytropic-atmosphere: hydrostatic equilibria under gravity ​

The hydrostatic equilibrium of the constant gravity g of [gravity] (required, fatal otherwise), with the state of [initial_conditions_region_1] at the origin (#73, M7-G0):

isothermal:ρ=ρ1eg⋅x/T1,p=ρT1,T1=p1/ρ1;polytropic:ρ=ρ1s1/(G−1),p=p1sG/(G−1),s=1+G−1Gρ1p1g⋅x,

with the region's velocity and field uniform. polytropic_gamma G>1; the polytrope is fatal where s≤0 (the top of the atmosphere inside the domain). Optional, both: a relative pressure pulse p(1+Ae−|x−x0|2/w2) (pulse_amplitude, pulse_x, pulse_y, pulse_z, pulse_width; M7-G2b). Close them with hydrostatic faces along g; with [gravity] equilibrium = atmosphere the atmosphere at rest is an exact discrete steady state (verification).

ini
[initial_conditions]
type             = polytropic-atmosphere
amr_iterations   = 1
polytropic_gamma = 1.2

rayleigh-taylor: two isothermal layers, heavy over light ​

A heavy cold layer over a light hot one under the gravity of [gravity], which must lie along one axis (M7-G3). With the height h=−g⋅x/|g| and z=(h−h0)/δ, the temperature is

T=a+btanh⁡z,a=Tl+Th2,b=Th−Tl2,Tl=p1ρ1,Th=TlR,

and the pressure is hydrostatic in closed form, p=p1exp⁡(−|g|δaz−bln⁡(acosh⁡z+bsinh⁡z)+bln⁡aa2−b2) (p(h0)=p1), ρ=p/T: two isothermal, hence stably stratified, layers whose interface is the only instability, with density ratio R across it at equal pressure. The state is at rest, with the field of region 1 (the light layer), and seeded with a divergence-free single mode,

vh=Acos⁡(kxt)f(h),ut=−Aksin⁡(kxt)f′(h),f=e−((h−h0)/w)2,k=2πλ,

vh along −g and ut along xt, the first axis other than g's. A velocity-only seed that is not solenoidal also starts sound waves, which beat against the growing mode for several e-foldings; this one does not. Keys: rt_height h0, rt_width δ, rt_density_ratio R (R<1: light over heavy, the stable control), rt_wavelength λ, rt_amplitude A (0: the unseeded layers), rt_seed_width w; all required, δ,R,λ,w>0. The linear growth rate of the mode is the eigenvalue that verification/gravity/rt_oracle.py computes from the same profile (GV-4, verification); [gravity] equilibrium = atmosphere keeps the unseeded layers.

ini
[initial_conditions]
type             = rayleigh-taylor
amr_iterations   = 1
rt_height        = 0.5
rt_width         = 0.05
rt_density_ratio = 2.0
rt_wavelength    = 0.5
rt_amplitude     = 1.0e-5
rt_seed_width    = 0.1

polytrope: an n = 1 polytrope star (self-gravity) ​

A self-gravitating star in equilibrium (#81, M8-P4; Euler, [gravity] self_gravity required). The n = 1 polytrope, p=Kρ2, is the Lane–Emden solution ρs=ρcsin⁡(kr)/(kr), k=π/a, of radius a, in equilibrium under its own gravity when K=2Ga2/π; its mass is M=4ρca3/π. Region 1 sets a light atmosphere (ρ1, p1, the velocity):

  • inside, r<a: ρ=ρ1+ρs, p=p1+fKρs2;
  • outside: the atmosphere isothermal at T=p1/ρ1 and hydrostatic in the star's field, ρ=ρ1exp⁡(GM/T(1/r−1/a)), p=ρT. A uniform atmosphere would fall onto the star and thin at its surface.

Density and pressure are continuous at the surface. star_pressure_factor f=1 is the equilibrium of the star alone (the atmosphere's own weight and gravity perturb it, by the atmosphere's share of the mass); f<1 collapses it. Keys: star_radius a, star_density ρc (both required, >0), star_x0, star_y0, star_z0 (the centre, default 0), star_pressure_factor (default 1, >0). With [gravity] poisson_bc = isolated the star sits in a box without its periodic images (SV-7, SV-8, verification). A light atmosphere (ρ1≲10−3ρc) needs [numerics] positivity_limiter = cell at the surface.

ini
[gravity]
self_gravity = .true.
G            = 1.0
poisson_bc   = isolated

[initial_conditions]
type                 = polytrope
amr_iterations       = 0
star_radius          = 0.5
star_density         = 1.0
star_pressure_factor = 1.0

[initial_conditions_region_1]
r = 1.0e-4
u = 0.0
v = 0.0
w = 0.0
p = 1.5915494309189535e-05