Planned maintenance on Wednesday, 2021-01-20, 17:00-18:00. Expect some interruptions during that time

Commit af0e98cb authored by Rainer Weinberger's avatar Rainer Weinberger

Added example shocktube_1d

parent c94143dd
#!/bin/bash # this line only there to enable syntax highlighting in this file
## examples/shocktube_1d/Config.sh
## config file for 1d shocktube probelm
#--------------------------------------- Basic operation mode of code
ONEDIMS # 1d simulation
REFLECTIVE_X=2 # X Boundary; 1: Reflective, 2: Inflow/Outflow; not active: periodic
GAMMA=1.4 # Adiabatic index of gas; 5/3 if not set
#--------------------------------------- Mesh motion and regularization
REGULARIZE_MESH_CM_DRIFT # Mesh regularization; Move mesh generating point towards center of mass to make cells rounder.
REGULARIZE_MESH_CM_DRIFT_USE_SOUNDSPEED # Limit mesh regularization speed by local sound speed
REGULARIZE_MESH_FACE_ANGLE # Use maximum face angle as roundness criterion in mesh regularization
#--------------------------------------- Time integration options
FORCE_EQUAL_TIMESTEPS # variable but global timestep
#---------------------------------------- Single/Double Precision
DOUBLEPRECISION=1 # Mode of double precision: not defined: single; 1: full double precision 2: mixed, 3: mixed, fewer single precisions; unless short of memory, use 1.
INPUT_IN_DOUBLEPRECISION # initial conditions are in double precision
OUTPUT_IN_DOUBLEPRECISION # snapshot files will be written in double precision
#--------------------------------------- Output/Input options
HAVE_HDF5 # needed when HDF5 I/O support is desired (recommended)
#--------------------------------------- Testing and Debugging options
DEBUG # enables core-dumps
""" @package examples/shocktube_1d/Riemann.py
exact solution to Riemann problem
created by Rainer Weinberger, last modified: 19.02.2019
"""
import numpy as np
def f_K(pres, W_K, gamma):
"""
Flux functions for left or right state of a Riemann problem;
Auxiliary function for NewtonRaphson.
\param[in] pres float pressure of central state
\param[in] W_K array, shape (3,), left/right hand side state of Riemann problem
\param[in] gamma float, adiabatic index of gas
"""
integy_K = W_K[2] / ( gamma - 1.0 ) / W_K[0]
a_K = np.sqrt( gamma * W_K[2] / W_K[0] )
A = 2.0 / ( gamma + 1.0 ) / W_K[0]
B = ( gamma - 1.0 ) / ( gamma + 1.0 ) * W_K[2]
if pres > W_K[2] : ##shock
return ( pres - W_K[2] ) * np.sqrt( A / ( pres + B ) )
else: ## rarefaction
exponent = ( gamma - 1.0) / 2.0 / gamma
return ( 2.0 * a_K / ( gamma - 1.0 ) ) * ( ( pres / W_K[2] )**exponent - 1.0 )
def f_K_prime(pres, W_K, gamma_K):
"""
Derivative of flux functions for left or right state of a Riemann problem;
Auxiliary function for NewtonRaphson.
\param[in] pres float pressure of central state
\param[in] W_K array, shape (3,), left/right hand side state of Riemann problem
\param[in] gamma float, adiabatic index of gas
"""
integy_K = W_K[2] / ( gamma_K - 1.0 ) / W_K[0]
a_K = np.sqrt( gamma_K * W_K[2] / W_K[0] )
A = 2.0 / ( gamma_K + 1.0 ) / W_K[0]
B = ( gamma_K - 1.0 ) / ( gamma_K + 1.0 ) * W_K[2]
if pres > W_K[2] : ##shock
return np.sqrt( A / ( B + pres ) ) * ( 1.0 - ( pres - W_K[2] ) / ( 2.0 * ( B + pres ) ) )
else: ## rarefaction
exponent = -( gamma_K + 1.0 ) / 2.0 / gamma_K
return ( pres / W_K[2] )**exponent / W_K[0] / a_K
def NewtonRaphson(pres, W_L, W_R, gamma):
"""
NewtonRaphson iteration to determine central pressure of a Riemann problem
\param[in] W_L array, shape (3,) left hand side density, velocity and pressure
\param[in] W_R array, shape (3,) right hand side density, velocity and pressure
\param[in] gamma float, adiabatic index of gas
\return pres pressure of central region
"""
change = 1.0
iter = 0
while np.abs(change) > 1e-6:
iter += 1
## root finding for function
function = f_K(pres, W_L, gamma) + f_K(pres, W_R, gamma) + W_R[1] - W_L[1]
function_prime = f_K_prime(pres, W_L, gamma) + f_K_prime(pres, W_R, gamma)
pres_new = pres - function / function_prime
change = 2.0 * ( pres_new - pres ) / ( pres_new + pres )
pres = pres_new
if(iter > 100):
print("ERROR: NewtonRaphson: maximum number of iterations reached! Could not converge!")
break
return pres
def rarefaction_fan_left(W_K, gamma, xx, time):
gm1 = (gamma - 1.0)
gp1 = (gamma + 1.0)
gamma_ratio = gm1 / gp1
a = np.sqrt( gamma * W_K[2] / W_K[0] )
rho = W_K[0] * (2.0 / gp1 + gamma_ratio / a * ( W_K[1] - xx / time ) )**( 2.0 / gm1 )## wrong?
vel = 2.0 / gp1 * ( a + gm1 / 2.0 * W_K[1] + xx / time )
pres = W_K[2] * ( 2.0 / gp1 + gamma_ratio / a * ( W_K[1] - xx / time ) )**( 2.0 * gamma / gm1 )
return np.array([rho, vel, pres]).T
def rarefaction_fan_right(W_K, gamma, xx, time):
gm1 = (gamma - 1.0)
gp1 = (gamma + 1.0)
gamma_ratio = gm1 / gp1
a = np.sqrt( gamma * W_K[2] / W_K[0] )
rho = W_K[0] * (2.0 / gp1 - gamma_ratio / a * ( W_K[1] - xx / time ) )**( 2.0 / gm1 )
vel = 2.0 / gp1 * ( -a + gm1 / 2.0 * W_K[1] + xx / time )
pres = W_K[2] * ( 2.0 / gp1 - gamma_ratio / a * ( W_K[1] - xx / time ) )**( 2.0 * gamma / gm1 )
return np.array([rho, vel, pres]).T
def RiemannProblem(xx, x0, W_L, W_R, gamma, time):
"""
RiemannProblem: Samples the solution of a Riemann problem at a given time at positions xx
\param[in] xx, array, shape (n,), 1d coordinate of grid
\param[in] x0, float initial coordinate of discontinuety
\param[in] W_L, array, shape(3,), density, velocity and pressure of left state
\param[in] W_R, array, shape(3,), density, velocity and pressure of right state
\param[in] gamma, float, adiabatic index of gas
\param[in] time, time since initial conditions
\return xx, W, x_shock; xx: as input; W: array, shape(n,3) densiy, velocity and pressure at pos xx
x_shock: postition of charactaeristic features
"""
## some auxiliary quantitites
a_L = np.sqrt( gamma * W_L[2] / W_L[0] ) ## sound speeds
a_R = np.sqrt( gamma * W_R[2] / W_R[0] )
gm1 = gamma - 1.0 ## gamma +- 1
gp1 = gamma + 1.0
gamma_ratio = gm1 / gp1
PosOfCharacteristics = np.zeros(5) ## 0: left most to 4: right most; 2 is rarefaction; if 0 and 1 (3 and 4) have the same value, there is a shock, otherwise rarefaction wave
## calculate central pressure; initial guess: arithmetic mean
pstar = 0.5 * ( W_L[2] + W_R[2] )
pstar = NewtonRaphson( pstar, W_L, W_R, gamma)
## calculate central velocity and sound speed
ustar = 0.5 * ( W_L[1] + W_R[1] ) + 0.5 * ( f_K(pstar, W_R, gamma) - f_K(pstar, W_L, gamma) )
astar_L = a_L * ( pstar / W_L[2] )**( (gamma - 1.0) / (2.0 * gamma) )
astar_R = a_R * ( pstar / W_R[2] )**( (gamma - 1.0) / (2.0 * gamma) )
## decide on shock or rarefaction on left and right; get velocities of features
PosOfCharacteristics[2] = ustar
if pstar > W_L[2]: ## shock on left
PosOfCharacteristics[0] = W_L[1] - a_L * np.sqrt( gp1 / 2.0 / gamma * pstar / W_L[2] + gm1 / 2.0 / gamma )
PosOfCharacteristics[1] = PosOfCharacteristics[0]
leftShock = True
else: ## rarefaction wave on left
PosOfCharacteristics[0] = W_L[1] - a_L ## outer
PosOfCharacteristics[1] = ustar - astar_L ## inner
if pstar > W_R[2]: ## shock on right
PosOfCharacteristics[4] = W_R[1] + a_R * np.sqrt( gp1 / 2.0 / gamma * pstar / W_R[2] + gm1 / 2.0 / gamma )
PosOfCharacteristics[3] = PosOfCharacteristics[4]
rightShock = True
else: ## rarefaction wave on right
PosOfCharacteristics[4] = W_R[1] + a_R ## outer
PosOfCharacteristics[3] = ustar + astar_R ## inner
## self-similar, i.e. pos = velocity * time
PosOfCharacteristics[:] *= time
## select different regions
i_L, = np.where(xx-x0 < PosOfCharacteristics[0])
i_star_L, = np.where( (xx-x0 >= PosOfCharacteristics[1]) & (xx-x0 < PosOfCharacteristics[2]) )
i_star_R, = np.where( (xx-x0 >= PosOfCharacteristics[2]) & (xx-x0 < PosOfCharacteristics[3]) )
i_R, = np.where(xx-x0 >= PosOfCharacteristics[4])
## sample solution
W = np.zeros( [len(xx), 3], dtype=np.float64 )
## left most and right most state: same as initial conditions
W[i_L,:] = W_L[:]
W[i_R, :] = W_R[:]
if PosOfCharacteristics[0] != PosOfCharacteristics[1]: ## rarefaction wave on left
i_fan_L, = np.where( (xx-x0 >= PosOfCharacteristics[0]) & (xx-x0 < PosOfCharacteristics[1]) )
W[i_fan_L,:] = rarefaction_fan_left(W_L, gamma, xx[i_fan_L]-x0, time)
W[i_star_L, 0] = (pstar / W_L[2])**(1./gamma) * W_L[0]
else: ## shock on left
W[i_star_L, 0] = W_L[0] * ( ( pstar / W_L[2] + gamma_ratio ) / ( gamma_ratio * pstar / W_L[2] + 1.0 ) )
W[i_star_L, 1] = ustar
W[i_star_L, 2] = pstar
if PosOfCharacteristics[3] != PosOfCharacteristics[4]: ## rarefaction wave on right
i_fan_R, = np.where( (xx-x0 >= PosOfCharacteristics[3]) & (xx-x0 < PosOfCharacteristics[4]) )
W[i_fan_R, :] = rarefaction_fan_right(W_R, gamma, xx[i_fan_R]-x0, time)
W[i_star_R, 0] = (pstar / W_R[2])**(1./gamma) * W_R[0]
else: ## shock on right
W[i_star_R, 0] = W_R[0] * ( ( pstar / W_R[2] + gamma_ratio ) / ( gamma_ratio * pstar / W_R[2] + 1.0 ) )
W[i_star_R, 1] = ustar
W[i_star_R, 2] = pstar
return xx, W, PosOfCharacteristics
This diff is collapsed.
""" @package examples/shocktube_1d/create.py
Code that creates 1d shocktube problem initial conditions
supposed to be as siple as possible and self-contained
created by Rainer Weinberger, 19.02.2019
"""
""" load libraries """
import sys # system specific calls
import numpy as np # scientific computing package
import h5py # hdf5 format
simulation_directory = str(sys.argv[1])
print("examples/shocktube_1d/create.py: creating ICs in directory " + simulation_directory)
FloatType = np.float64 # double precision: np.float64, for single use np.float32
IntType = np.int32
Boxsize = FloatType(20.0)
NumberOfCells = IntType(128)
""" initial condition parameters """
FilePath = simulation_directory + '/IC.hdf5'
## Riemann problem
position_0 = FloatType(10.0) # initial position of discontinuity
density_0 = FloatType(1.0)
density_1 = FloatType(0.125)
velocity_0 = FloatType(0.0)
velocity_1 = FloatType(0.0)
pressure_0 = FloatType(1.0)
pressure_1 = FloatType(0.1)
gamma = FloatType(1.4) ## note: this has to be consistent with the parameter settings for Arepo!
gamma_minus1 = gamma - FloatType(1.0)
uthermal_0 = pressure_0 / gamma_minus1 / density_0
uthermal_1 = pressure_1 / gamma_minus1 / density_1
""" set up grid: uniform 1d grid """
## spacing
dx = Boxsize / FloatType(NumberOfCells)
## position of first and last cell
pos_first, pos_last = FloatType(0.5) * dx, Boxsize - FloatType(0.5) * dx
## set up grid
Pos = np.zeros([NumberOfCells, 3], dtype=FloatType)
Pos[:,0] = np.linspace(pos_first, pos_last, NumberOfCells, dtype=FloatType)
Volume = np.full(NumberOfCells, dx, dtype=FloatType)
""" set up hydrodynamical quantitites """
## left state
Density = np.full(Pos.shape[0], density_0, dtype=FloatType)
Velocity = np.zeros(Pos.shape, dtype=FloatType)
Velocity[:,0] = velocity_0
Uthermal = np.full(Pos.shape[0], uthermal_0, dtype=FloatType)
## right state
i_right, = np.where( Pos[:,0] > position_0)
Density[i_right] = density_1
Velocity[i_right,0] = velocity_1
Uthermal[i_right] = uthermal_1
## mass instead of density needed for input
Mass = Density * Volume
""" write *.hdf5 file; minimum number of fields required by Arepo """
IC = h5py.File(FilePath, 'w') # open/create file
## create hdf5 groups
header = IC.create_group("Header") # create header group
part0 = IC.create_group("PartType0") # create particle group for gas cells
## write header entries
NumPart = np.array([NumberOfCells, 0, 0, 0, 0, 0], dtype=IntType)
header.attrs.create("NumPart_ThisFile", NumPart)
header.attrs.create("NumPart_Total", NumPart)
header.attrs.create("NumPart_Total_HighWord", np.zeros(6, dtype=IntType) )
header.attrs.create("MassTable", np.zeros(6, dtype=IntType) )
header.attrs.create("Time", 0.0)
header.attrs.create("Redshift", 0.0)
header.attrs.create("BoxSize", Boxsize)
header.attrs.create("NumFilesPerSnapshot", 1)
header.attrs.create("Omega0", 0.0)
header.attrs.create("OmegaB", 0.0)
header.attrs.create("OmegaLambda", 0.0)
header.attrs.create("HubbleParam", 1.0)
header.attrs.create("Flag_Sfr", 0)
header.attrs.create("Flag_Cooling", 0)
header.attrs.create("Flag_StellarAge", 0)
header.attrs.create("Flag_Metals", 0)
header.attrs.create("Flag_Feedback", 0)
if Pos.dtype == np.float64:
header.attrs.create("Flag_DoublePrecision", 1)
else:
header.attrs.create("Flag_DoublePrecision", 0)
## write cell data
part0.create_dataset("ParticleIDs", data=np.arange(1, NumberOfCells+1) )
part0.create_dataset("Coordinates", data=Pos)
part0.create_dataset("Masses", data=Mass)
part0.create_dataset("Velocities", data=Velocity)
part0.create_dataset("InternalEnergy", data=Uthermal)
## close file
IC.close()
""" normal exit """
sys.exit(0)
%% examples/shocktube_1d/param.txt
% parameter file for 1d shocktube problem
%% system options
MaxMemSize 2500
CpuTimeBetRestartFile 9000
TimeLimitCPU 90000
%% initial conditions
InitCondFile ./run/examples/shocktube_1d/IC
ICFormat 3
%% output options
OutputDir ./run/examples/shocktube_1d/output/
SnapshotFileBase snap
SnapFormat 3
NumFilesPerSnapshot 1
NumFilesWrittenInParallel 1
%% resubmit opitions
ResubmitOn 0
ResubmitCommand my-scriptfile
OutputListFilename ol
OutputListOn 0
%% simulation mode
CoolingOn 0
StarformationOn 0
PeriodicBoundariesOn 1
ComovingIntegrationOn 0
%% Cosmological parameters
Omega0 0.0
OmegaBaryon 0.0
OmegaLambda 0.0
HubbleParam 1.0
%% Simulation parameters
BoxSize 20.0
TimeOfFirstSnapshot 0.0
TimeBetStatistics 0.1
TimeBegin 0.0
TimeMax 5.0
TimeBetSnapshot 1.0
%% Units
UnitVelocity_in_cm_per_s 1.0
UnitLength_in_cm 1.0
UnitMass_in_g 1.0
GravityConstantInternal 0.0
%% settings for gravity
ErrTolIntAccuracy 0.1
ErrTolTheta 0.1
ErrTolForceAcc 0.1
%% timestepping
MaxSizeTimestep 0.1
MinSizeTimestep 1e-5
TypeOfTimestepCriterion 0
%% moving mesh
CellShapingSpeed 0.5
CellMaxAngleFactor 2.25
TypeOfOpeningCriterion 1
%% hydrodynamics
CourantFac 0.3
LimitUBelowThisDensity 0.0
LimitUBelowCertainDensityToThisValue 0.0
DesNumNgb 64
MaxNumNgbDeviation 2
InitGasTemp 0.0
MinGasTemp 0.0
MinEgySpec 0.0
MinimumDensityOnStartUp 0.0
%% domain decomposition
MultipleDomains 2
TopNodeFactor 4
ActivePartFracForNewDomainDecomp 0.01
%% gravitational softening
GasSoftFactor 0.01
SofteningComovingType0 0.1
SofteningComovingType1 0.1
SofteningComovingType2 0.1
SofteningComovingType3 0.1
SofteningComovingType4 0.1
SofteningComovingType5 0.1
SofteningMaxPhysType0 0.1
SofteningMaxPhysType1 0.1
SofteningMaxPhysType2 0.1
SofteningMaxPhysType3 0.1
SofteningMaxPhysType4 0.1
SofteningMaxPhysType5 0.1
SofteningTypeOfPartType0 0
SofteningTypeOfPartType1 0
SofteningTypeOfPartType2 0
SofteningTypeOfPartType3 0
SofteningTypeOfPartType4 0
SofteningTypeOfPartType5 0
......@@ -13,6 +13,7 @@ NUMBER_OF_TASKS=1
TESTS=""
## available 1d test cases
TESTS+="wave_1d "
TESTS+="shocktube_1d "
## loop over all tests
for TEST in $TESTS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment