test/test_relative_velocities.jl

Snapshot from this documentation build. SHA-256: 51ecb23999a953510babd64bbfec6e8d0017679d65e1e32d62528cf6e986d485

    1 using Test, Statistics
    2 import PMFGLM
    3 ENV["MHD_BACKEND"]="cpu"
    4 include(joinpath(@__DIR__,"..","src","production","runner.jl"))
    5 
    6 @testset "photon expansion preserves physical dipole and monopole" begin
    7     for TT in (Float32,Float64)
    8         s=MHDKernels.allocate_state(MHDKernels.backend(:cpu),TT,(8,8,8);dx=1/8)
    9         fill!(s.U[1],1); fill!(s.U[2],0.125); fill!(s.U[3],0); fill!(s.U[4],0)
   10         fill!(s.U[5],2); foreach(x->fill!(x,0),s.U[6:9])
   11         photons=MHDKernels.allocate_photon_moment_state(s)
   12         fill!(photons.hat_batch,complex(TT(0.1),TT(0.2)))
   13         monopole=copy(photons.delta_hat)
   14         dipole=copy(photons.velocity_hat[1])
   15         a0=1/1201; a1=1/601; vunit=8e5
   16         half=sqrt(_hubble_momentum_decay(a0,a1,a0))
   17         for _=1:2
   18             MHDKernels.apply_linear_drag!(s,half)
   19             MHDKernels.rescale_photon_velocities!(photons,inv(half))
   20         end
   21         unit=_cosmological_velocity_unit(vunit,a1,a0)
   22         @test photons.delta_hat == monopole
   23         @test photons.velocity_hat[1].*unit ≈ dipole.*vunit rtol=5eps(TT)
   24         @test mean(s.U[2])*unit ≈ 0.125vunit*a0/a1 rtol=20eps(TT)
   25         @test_throws ArgumentError MHDKernels.rescale_photon_velocities!(photons,NaN)
   26     end
   27 end
   28 
   29 @testset "gravity source step resolves the fast slip eigenvalue" begin
   30     for mode in (:godunov,:radiation,:aware,:semiimplicit), R in (0.,0.2,10.)
   31         cap=_source_drag_impulse_cap(mode,Inf,true,0.01,1+R)
   32         q=(1+R)*cap
   33         @test q ≈ 0.01
   34         # Exact relative bias of repeated final kicks for a constant-force
   35         # exponential relaxation; a bound on the old stiff-splitting failure.
   36         @test q/(-expm1(-q))-1 < 0.00501
   37     end
   38     @test isinf(_source_drag_impulse_cap(:radiation,Inf,false,0.01))
   39     @test _source_drag_impulse_cap(:aware,0.001,true,0.01) == 0.001
   40 end
   41 
   42 @testset "Eulerian particle velocity follows translated particles" begin
   43     for TT in (Float32,Float64), lattice in (false,true)
   44         n=16
   45         q=TT[(i-0.5)/n for i=1:n,j=1:n,k=1:n]
   46         qy=TT[(j-0.5)/n for i=1:n,j=1:n,k=1:n]
   47         qz=TT[(k-0.5)/n for i=1:n,j=1:n,k=1:n]
   48         v=vec(cos.(2TT(pi).*q)); dx=fill(TT(0.25),n^3); zeroes=zeros(TT,n^3)
   49         px=lattice ? dx : vec(mod.(q.+TT(0.25),one(TT)))
   50         py=lattice ? zeroes : vec(qy); pz=lattice ? zeroes : vec(qz)
   51         velocity=zeros(TT,n^3); density=similar(velocity); scratch=similar(velocity)
   52         MHDKernels.deposit_particle_velocity!(velocity,density,px,py,pz,v;
   53                                              N=n,lattice_displacements=lattice)
   54         @test density ≈ ones(TT,n^3)
   55         @test sum(density.*velocity) ≈ sum(v) atol=1e-3
   56         mode=_device_complex_mode!(MHDKernels.backend(:cpu),scratch,velocity,n,1)
   57         @test mode ≈ -im atol=3e-6
   58     end
   59 end
   60 
   61 @testset "physical box controls DM velocity and mode wavenumber" begin
   62     n=8; s=MHDKernels.allocate_state(MHDKernels.backend(:cpu),Float32,(n,n,n);dx=1/n)
   63     fill!(s.U[1],1); foreach(x->fill!(x,0),s.U[2:9]); fill!(s.U[5],1.5)
   64     q=Float32[(i-0.5)/n for i=1:n,j=1:n,k=1:n]
   65     v=vec(cos.(2f0*Float32(pi).*q)); dx=fill(0.25f0,n^3); dz=zeros(Float32,n^3)
   66     mktempdir() do dir
   67         path=joinpath(dir,"modes.tsv")
   68         _emit_diagnostics!(be_p=s.be,s=s,ρdm=zeros(Float32,n^3),
   69             scratch=zeros(Float32,n^3),px=dx,py=dz,pz=dz,vx=v,vy=dz,vz=dz,
   70             N=n,ncells=n^3,gravity=true,cycle=0,measured=0,a=0.001,
   71             pk_path="",history_path="",pdf_path="",pdf_counts=nothing,
   72             pdf_loglo=-1.,pdf_loghi=1.,nmu=1,nbins=4,boxsize=1.,axis=1,
   73             lattice_displacements=true,mode_history_path=path,
   74             physical_box_ckpc_h=1000.)
   75         lines=split.(readlines(path),'\t'); header=lines[1]
   76         row=only(filter(x->x[1]=="dm_v_x",lines[2:end]))
   77         getval(name)=parse(Float64,row[findfirst(==(name),header)])
   78         @test getval("imag") ≈ -_particle_velocity_cms_per_code(.001,1000.) rtol=3e-6
   79         @test getval("k_comoving_mpc_inv") ≈ 2pi*.674
   80     end
   81 end
   82 
   83 @testset "pre-fix photon checkpoint cannot silently resume" begin
   84     mktempdir() do dir
   85         path=joinpath(dir,"old.jls")
   86         _write_pmf_checkpoint(path,(N=8,),(a=.001,),["x"=>zeros(Float32,1)])
   87         @test_throws ErrorException _restore_pmf_checkpoint!(path,
   88             (N=8,velocity_transport_version=2),["x"=>zeros(Float32,1)])
   89     end
   90 end
   91 
   92 include("relative_velocity_checks.jl")
   93 @testset "reused deposition buffers and photon scaling on CPU" begin
   94     for TT in (Float32,Float64)
   95         relative_velocity_checks(:cpu,TT)
   96     end
   97 end