Bugfix KP07 and refactoring

This commit is contained in:
André R. Brodtkorb 2018-11-19 13:39:03 +01:00
parent 815b4493b5
commit cfcaa65bbe
7 changed files with 602 additions and 1149 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -102,8 +102,8 @@ class EE2D_KP07_dimsplit (BaseSimulator):
2, 2, 2, 2,
[None, None, None, None]) [None, None, None, None])
self.cfl_data = gpuarray.GPUArray(self.grid_size, dtype=np.float32) self.cfl_data = gpuarray.GPUArray(self.grid_size, dtype=np.float32)
dt_x = np.min(self.dx / (np.abs(hu0/h0) + np.sqrt(gamma*h0))) dt_x = np.min(self.dx / (np.abs(rho_u/rho) + np.sqrt(gamma*rho)))
dt_y = np.min(self.dy / (np.abs(hv0/h0) + np.sqrt(gamma*h0))) dt_y = np.min(self.dy / (np.abs(rho_v/rho) + np.sqrt(gamma*rho)))
dt = min(dt_x, dt_y) dt = min(dt_x, dt_y)
self.cfl_data.fill(dt, stream=self.stream) self.cfl_data.fill(dt, stream=self.stream)

View File

@ -116,6 +116,10 @@ class LxF (Simulator.BaseSimulator):
def download(self): def download(self):
return self.u0.download(self.stream) return self.u0.download(self.stream)
def check(self):
self.u0.check()
self.u1.check()
def computeDt(self): def computeDt(self):
max_dt = gpuarray.min(self.cfl_data, stream=self.stream).get(); max_dt = gpuarray.min(self.cfl_data, stream=self.stream).get();

View File

@ -159,7 +159,7 @@ class BaseSimulator(object):
return "{:s} [{:d}x{:d}]".format(self.__class__.__name__, self.nx, self.ny) return "{:s} [{:d}x{:d}]".format(self.__class__.__name__, self.nx, self.ny)
def simulate(self, t): def simulate(self, t, dt=None):
""" """
Function which simulates t_end seconds using the step function Function which simulates t_end seconds using the step function
Requires that the step() function is implemented in the subclasses Requires that the step() function is implemented in the subclasses
@ -167,27 +167,31 @@ class BaseSimulator(object):
printer = Common.ProgressPrinter(t) printer = Common.ProgressPrinter(t)
t_end = self.simTime() + t t_start = self.simTime()
t_end = t_start + t
dt = None local_dt = dt
if (local_dt == None):
local_dt = self.computeDt()
while(self.simTime() < t_end): while(self.simTime() < t_end):
if (self.simSteps() % 100 == 0): if (dt == None and self.simSteps() % 100 == 0):
dt = self.computeDt()*self.cfl_scale local_dt = self.computeDt()
# Compute timestep for "this" iteration (i.e., shorten last timestep) # Compute timestep for "this" iteration (i.e., shorten last timestep)
dt = np.float32(min(dt, t_end-self.simTime())) local_dt = np.float32(min(local_dt*self.cfl_scale, t_end-self.simTime()))
# Stop if end reached (should not happen) # Stop if end reached (should not happen)
if (dt <= 0.0): if (local_dt <= 0.0):
self.logger.warning("Timestep size {:d} is less than or equal to zero!".format(self.simSteps())) self.logger.warning("Timestep size {:d} is less than or equal to zero!".format(self.simSteps()))
break break
# Step forward in time # Step forward in time
self.step(dt) self.step(local_dt)
#Print info #Print info
print_string = printer.getPrintString(t_end - self.simTime()) print_string = printer.getPrintString(self.simTime() - t_start)
if (print_string): if (print_string):
self.logger.info("%s: %s", self, print_string) self.logger.info("%s: %s", self, print_string)
try: try:

View File

@ -201,12 +201,12 @@ __global__ void KP07Kernel(
const int i = tx + 2; //Skip local ghost cells, i.e., +2 const int i = tx + 2; //Skip local ghost cells, i.e., +2
const int j = ty + 2; const int j = ty + 2;
const float h1 = Q[0][j][i] + (F[0][ty][tx] - F[0][ty ][tx+1]) * dt_ / dx_ Q[0][j][i] += (F[0][ty][tx] - F[0][ty ][tx+1]) * dt_ / dx_
+ (G[0][ty][tx] - G[0][ty+1][tx ]) * dt_ / dy_; + (G[0][ty][tx] - G[0][ty+1][tx ]) * dt_ / dy_;
const float hu1 = Q[1][j][i] + (F[1][ty][tx] - F[1][ty ][tx+1]) * dt_ / dx_ Q[1][j][i] += (F[1][ty][tx] - F[1][ty ][tx+1]) * dt_ / dx_
+ (G[1][ty][tx] - G[1][ty+1][tx ]) * dt_ / dy_; + (G[1][ty][tx] - G[1][ty+1][tx ]) * dt_ / dy_;
const float hv1 = Q[2][j][i] + (F[2][ty][tx] - F[2][ty ][tx+1]) * dt_ / dx_ Q[2][j][i] += (F[2][ty][tx] - F[2][ty ][tx+1]) * dt_ / dx_
+ (G[2][ty][tx] - G[2][ty+1][tx ]) * dt_ / dy_; + (G[2][ty][tx] - G[2][ty+1][tx ]) * dt_ / dy_;
float* const h_row = (float*) ((char*) h1_ptr_ + h1_pitch_*tj); float* const h_row = (float*) ((char*) h1_ptr_ + h1_pitch_*tj);
float* const hu_row = (float*) ((char*) hu1_ptr_ + hu1_pitch_*tj); float* const hu_row = (float*) ((char*) hu1_ptr_ + hu1_pitch_*tj);
@ -214,14 +214,14 @@ __global__ void KP07Kernel(
if (getOrder(step_order_) == 2 && getStep(step_order_) == 1) { if (getOrder(step_order_) == 2 && getStep(step_order_) == 1) {
//Write to main memory //Write to main memory
h_row[ti] = 0.5f*(h_row[ti] + h1); h_row[ti] = 0.5f*(h_row[ti] + Q[0][j][i]);
hu_row[ti] = 0.5f*(hu_row[ti] + hu1); hu_row[ti] = 0.5f*(hu_row[ti] + Q[1][j][i]);
hv_row[ti] = 0.5f*(hv_row[ti] + hv1); hv_row[ti] = 0.5f*(hv_row[ti] + Q[2][j][i]);
} }
else { else {
h_row[ti] = h1; h_row[ti] = Q[0][j][i];
hu_row[ti] = hu1; hu_row[ti] = Q[1][j][i];
hv_row[ti] = hv1; hv_row[ti] = Q[2][j][i];
} }
} }

View File

@ -22,6 +22,83 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from GPUSimulators.Simulator import BoundaryCondition from GPUSimulators.Simulator import BoundaryCondition
import numpy as np import numpy as np
import gc
def downsample(highres_solution, x_factor, y_factor=None):
if (y_factor == None):
y_factor = x_factor
assert(highres_solution.shape[1] % x_factor == 0)
assert(highres_solution.shape[0] % y_factor == 0)
if (x_factor*y_factor == 1):
return highres_solution
if (len(highres_solution.shape) == 1):
highres_solution = highres_solution.reshape((1, highres_solution.size))
nx = highres_solution.shape[1] / x_factor
ny = highres_solution.shape[0] / y_factor
return highres_solution.reshape([int(ny), int(y_factor), int(nx), int(x_factor)]).mean(3).mean(1)
def bump(nx, ny, width, height, bump_size=None, h_ref=0.5, h_amp=0.1, u_ref=0.0, u_amp=0.1, v_ref=0.0, v_amp=0.1, ref_nx=None, ref_ny=None):
if (ref_nx == None):
ref_nx = nx
assert(ref_nx >= nx)
if (ref_ny == None):
ref_ny = ny
assert(ref_ny >= ny)
if (bump_size == None):
bump_size = width/5.0
ref_dx = width / float(ref_nx)
ref_dy = height / float(ref_ny)
x_center = ref_dx*ref_nx/2.0
y_center = ref_dy*ref_ny/2.0
x = ref_dx*(np.arange(0, ref_nx, dtype=np.float32)+0.5) - x_center
y = ref_dy*(np.arange(0, ref_ny, dtype=np.float32)+0.5) - y_center
xv, yv = np.meshgrid(x, y, sparse=False, indexing='xy')
r = np.sqrt(xv**2 + yv**2)
xv = None
yv = None
gc.collect()
#Generate highres then downsample
#h_highres = 0.5 + 0.1*np.exp(-(xv**2/size + yv**2/size))
h_highres = h_ref + h_amp*0.5*(1.0 + np.cos(np.pi*r/bump_size)) * (r < bump_size)
h = downsample(h_highres, ref_nx/nx, ref_ny/ny)
h_highres = None
gc.collect()
#hu_highres = 0.1*np.exp(-(xv**2/size + yv**2/size))
u_highres = u_ref + u_amp*0.5*(1.0 + np.cos(np.pi*r/bump_size)) * (r < bump_size)
hu = downsample(u_highres, ref_nx/nx, ref_ny/ny)*h
u_highres = None
gc.collect()
#hu_highres = 0.1*np.exp(-(xv**2/size + yv**2/size))
v_highres = v_ref + v_amp*0.5*(1.0 + np.cos(np.pi*r/bump_size)) * (r < bump_size)
hv = downsample(v_highres, ref_nx/nx, ref_ny/ny)*h
v_highres = None
gc.collect()
dx = width/nx
dy = height/ny
return h, hu, hv, dx, dy
def genShockBubble(nx, ny, gamma): def genShockBubble(nx, ny, gamma):
""" """
@ -61,13 +138,8 @@ def genShockBubble(nx, ny, gamma):
p = np.where(left, 10.0, p) p = np.where(left, 10.0, p)
E = 0.5*rho*(u**2+v**2) + p/(gamma-1.0) E = 0.5*rho*(u**2+v**2) + p/(gamma-1.0)
#Estimate dt
scale = 0.45
max_rho_estimate = 5.0
max_u_estimate = 5.0
dx = width/nx dx = width/nx
dy = height/ny dy = height/ny
dt = scale * min(dx, dy) / (max_u_estimate + np.sqrt(gamma*max_rho_estimate))
bc = BoundaryCondition({ bc = BoundaryCondition({
'north': BoundaryCondition.Type.Reflective, 'north': BoundaryCondition.Type.Reflective,
@ -80,7 +152,7 @@ def genShockBubble(nx, ny, gamma):
arguments = { arguments = {
'rho': rho, 'rho_u': rho*u, 'rho_v': rho*v, 'E': E, 'rho': rho, 'rho_u': rho*u, 'rho_v': rho*v, 'E': E,
'nx': nx, 'ny': ny, 'nx': nx, 'ny': ny,
'dx': dx, 'dy': dy, 'dt': dt, 'dx': dx, 'dy': dy,
'g': g, 'g': g,
'gamma': gamma, 'gamma': gamma,
'boundary_conditions': bc 'boundary_conditions': bc
@ -169,13 +241,8 @@ def genKelvinHelmholtz(nx, ny, gamma, roughness=0.125):
E = 0.5*rho*(u**2+v**2) + p/(gamma-1.0) E = 0.5*rho*(u**2+v**2) + p/(gamma-1.0)
#Estimate dt
scale = 0.9
max_rho_estimate = 3.0
max_u_estimate = 2.0
dx = width/nx dx = width/nx
dy = height/ny dy = height/ny
dt = scale * min(dx, dy) / (max_u_estimate + np.sqrt(gamma*max_rho_estimate))
bc = BoundaryCondition({ bc = BoundaryCondition({
@ -189,7 +256,7 @@ def genKelvinHelmholtz(nx, ny, gamma, roughness=0.125):
arguments = { arguments = {
'rho': rho, 'rho_u': rho*u, 'rho_v': rho*v, 'E': E, 'rho': rho, 'rho_u': rho*u, 'rho_v': rho*v, 'E': E,
'nx': nx, 'ny': ny, 'nx': nx, 'ny': ny,
'dx': dx, 'dy': dy, 'dt': dt, 'dx': dx, 'dy': dy,
'g': g, 'g': g,
'gamma': gamma, 'gamma': gamma,
'boundary_conditions': bc 'boundary_conditions': bc
@ -233,13 +300,8 @@ def genRayleighTaylor(nx, ny, gamma, version=0):
p = 2.5 - rho*g*yv p = 2.5 - rho*g*yv
E = 0.5*rho*(u**2+v**2) + p/(gamma-1.0) E = 0.5*rho*(u**2+v**2) + p/(gamma-1.0)
#Estimate dt
scale = 0.9
max_rho_estimate = 3.0
max_u_estimate = 1.0
dx = width/nx dx = width/nx
dy = height/ny dy = height/ny
dt = scale * min(dx, dy) / (max_u_estimate + np.sqrt(gamma*max_rho_estimate))
bc = BoundaryCondition({ bc = BoundaryCondition({
'north': BoundaryCondition.Type.Reflective, 'north': BoundaryCondition.Type.Reflective,
@ -252,7 +314,7 @@ def genRayleighTaylor(nx, ny, gamma, version=0):
arguments = { arguments = {
'rho': rho, 'rho_u': rho*u, 'rho_v': rho*v, 'E': E, 'rho': rho, 'rho_u': rho*u, 'rho_v': rho*v, 'E': E,
'nx': nx, 'ny': ny, 'nx': nx, 'ny': ny,
'dx': dx, 'dy': dy, 'dt': dt, 'dx': dx, 'dy': dy,
'g': g, 'g': g,
'gamma': gamma, 'gamma': gamma,
'boundary_conditions': bc 'boundary_conditions': bc