def unsplitFluxes(my_data, my_aux, rp, vars, solid, tc, dt): """ unsplitFluxes returns the fluxes through the x and y interfaces by doing an unsplit reconstruction of the interface values and then solving the Riemann problem through all the interfaces at once currently we assume a gamma-law EOS The runtime parameter grav is assumed to be the gravitational acceleration in the y-direction Parameters ---------- my_data : CellCenterData2d object The data object containing the grid and advective scalar that we are advecting. rp : RuntimeParameters object The runtime parameters for the simulation vars : Variables object The Variables object that tells us which indices refer to which variables tc : TimerCollection object The timers we are using to profile dt : float The timestep we are advancing through. Returns ------- out : ndarray, ndarray The fluxes on the x- and y-interfaces """ tm_flux = tc.timer("unsplitFluxes") tm_flux.begin() myg = my_data.grid gamma = rp.get_param("eos.gamma") #========================================================================= # compute the primitive variables #========================================================================= # Q = (rho, u, v, p) dens = my_data.get_var("density") xmom = my_data.get_var("x-momentum") ymom = my_data.get_var("y-momentum") ener = my_data.get_var("energy") r = dens # get the velocities u = xmom/dens v = ymom/dens # get the pressure e = (ener - 0.5*(xmom**2 + ymom**2)/dens)/dens p = eos.pres(gamma, dens, e) smallp = 1.e-10 p.d = p.d.clip(smallp) # apply a floor to the pressure #========================================================================= # compute the flattening coefficients #========================================================================= # there is a single flattening coefficient (xi) for all directions use_flattening = rp.get_param("compressible.use_flattening") if use_flattening: delta = rp.get_param("compressible.delta") z0 = rp.get_param("compressible.z0") z1 = rp.get_param("compressible.z1") xi_x = reconstruction_f.flatten(1, p.d, u.d, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi_y = reconstruction_f.flatten(2, p.d, v.d, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi = reconstruction_f.flatten_multid(xi_x, xi_y, p.d, myg.qx, myg.qy, myg.ng) else: xi = 1.0 # monotonized central differences in x-direction tm_limit = tc.timer("limiting") tm_limit.begin() limiter = rp.get_param("compressible.limiter") if limiter == 0: limitFunc = reconstruction_f.nolimit elif limiter == 1: limitFunc = reconstruction_f.limit2 else: limitFunc = reconstruction_f.limit4 ldelta_rx = xi*limitFunc(1, r.d, myg.qx, myg.qy, myg.ng) ldelta_ux = xi*limitFunc(1, u.d, myg.qx, myg.qy, myg.ng) ldelta_vx = xi*limitFunc(1, v.d, myg.qx, myg.qy, myg.ng) ldelta_px = xi*limitFunc(1, p.d, myg.qx, myg.qy, myg.ng) # monotonized central differences in y-direction ldelta_ry = xi*limitFunc(2, r.d, myg.qx, myg.qy, myg.ng) ldelta_uy = xi*limitFunc(2, u.d, myg.qx, myg.qy, myg.ng) ldelta_vy = xi*limitFunc(2, v.d, myg.qx, myg.qy, myg.ng) ldelta_py = xi*limitFunc(2, p.d, myg.qx, myg.qy, myg.ng) tm_limit.end() #========================================================================= # x-direction #========================================================================= # left and right primitive variable states tm_states = tc.timer("interfaceStates") tm_states.begin() V_l, V_r = interface_f.states(1, myg.qx, myg.qy, myg.ng, myg.dx, dt, vars.nvar, gamma, r.d, u.d, v.d, p.d, ldelta_rx, ldelta_ux, ldelta_vx, ldelta_px) tm_states.end() # transform interface states back into conserved variables U_xl = myg.scratch_array(vars.nvar) U_xr = myg.scratch_array(vars.nvar) U_xl.d[:,:,vars.idens] = V_l[:,:,vars.irho] U_xl.d[:,:,vars.ixmom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iu] U_xl.d[:,:,vars.iymom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iv] U_xl.d[:,:,vars.iener] = eos.rhoe(gamma, V_l[:,:,vars.ip]) + \ 0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2) U_xr.d[:,:,vars.idens] = V_r[:,:,vars.irho] U_xr.d[:,:,vars.ixmom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iu] U_xr.d[:,:,vars.iymom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iv] U_xr.d[:,:,vars.iener] = eos.rhoe(gamma, V_r[:,:,vars.ip]) + \ 0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2) #========================================================================= # y-direction #========================================================================= # left and right primitive variable states tm_states.begin() V_l, V_r = interface_f.states(2, myg.qx, myg.qy, myg.ng, myg.dy, dt, vars.nvar, gamma, r.d, u.d, v.d, p.d, ldelta_ry, ldelta_uy, ldelta_vy, ldelta_py) tm_states.end() # transform interface states back into conserved variables U_yl = myg.scratch_array(vars.nvar) U_yr = myg.scratch_array(vars.nvar) U_yl.d[:,:,vars.idens] = V_l[:,:,vars.irho] U_yl.d[:,:,vars.ixmom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iu] U_yl.d[:,:,vars.iymom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iv] U_yl.d[:,:,vars.iener] = eos.rhoe(gamma, V_l[:,:,vars.ip]) + \ 0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2) U_yr.d[:,:,vars.idens] = V_r[:,:,vars.irho] U_yr.d[:,:,vars.ixmom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iu] U_yr.d[:,:,vars.iymom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iv] U_yr.d[:,:,vars.iener] = eos.rhoe(gamma, V_r[:,:,vars.ip]) + \ 0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2) #========================================================================= # apply source terms #========================================================================= grav = rp.get_param("compressible.grav") ymom_src = my_aux.get_var("ymom_src") ymom_src.v()[:,:] = dens.v()*grav my_aux.fill_BC("ymom_src") E_src = my_aux.get_var("E_src") E_src.v()[:,:] = ymom.v()*grav my_aux.fill_BC("E_src") # ymom_xl[i,j] += 0.5*dt*dens[i-1,j]*grav U_xl.v(buf=1, n=vars.iymom)[:,:] += 0.5*dt*ymom_src.ip(-1, buf=1) U_xl.v(buf=1, n=vars.iener)[:,:] += 0.5*dt*E_src.ip(-1, buf=1) # ymom_xr[i,j] += 0.5*dt*dens[i,j]*grav U_xr.v(buf=1, n=vars.iymom)[:,:] += 0.5*dt*ymom_src.v(buf=1) U_xr.v(buf=1, n=vars.iener)[:,:] += 0.5*dt*E_src.v(buf=1) # ymom_yl[i,j] += 0.5*dt*dens[i,j-1]*grav U_yl.v(buf=1, n=vars.iymom)[:,:] += 0.5*dt*ymom_src.jp(-1, buf=1) U_yl.v(buf=1, n=vars.iener)[:,:] += 0.5*dt*E_src.jp(-1, buf=1) # ymom_yr[i,j] += 0.5*dt*dens[i,j]*grav U_yr.v(buf=1, n=vars.iymom)[:,:] += 0.5*dt*ymom_src.v(buf=1) U_yr.v(buf=1, n=vars.iener)[:,:] += 0.5*dt*E_src.v(buf=1) #========================================================================= # compute transverse fluxes #========================================================================= tm_riem = tc.timer("riemann") tm_riem.begin() riemann = rp.get_param("compressible.riemann") if riemann == "HLLC": riemannFunc = interface_f.riemann_hllc elif riemann == "CGF": riemannFunc = interface_f.riemann_cgf else: msg.fail("ERROR: Riemann solver undefined") _fx = riemannFunc(1, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, solid.xl, solid.xr, gamma, U_xl.d, U_xr.d) _fy = riemannFunc(2, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, solid.yl, solid.yr, gamma, U_yl.d, U_yr.d) F_x = patch.ArrayIndexer(d=_fx, grid=myg) F_y = patch.ArrayIndexer(d=_fy, grid=myg) tm_riem.end() #========================================================================= # construct the interface values of U now #========================================================================= """ finally, we can construct the state perpendicular to the interface by adding the central difference part to the trasverse flux difference. The states that we represent by indices i,j are shown below (1,2,3,4): j+3/2--+----------+----------+----------+ | | | | | | | | j+1 -+ | | | | | | | | | | | 1: U_xl[i,j,:] = U j+1/2--+----------XXXXXXXXXXXX----------+ i-1/2,j,L | X X | | X X | j -+ 1 X 2 X | 2: U_xr[i,j,:] = U | X X | i-1/2,j,R | X 4 X | j-1/2--+----------XXXXXXXXXXXX----------+ | | 3 | | 3: U_yl[i,j,:] = U | | | | i,j-1/2,L j-1 -+ | | | | | | | | | | | 4: U_yr[i,j,:] = U j-3/2--+----------+----------+----------+ i,j-1/2,R | | | | | | | i-1 i i+1 i-3/2 i-1/2 i+1/2 i+3/2 remember that the fluxes are stored on the left edge, so F_x[i,j,:] = F_x i-1/2, j F_y[i,j,:] = F_y i, j-1/2 """ tm_transverse = tc.timer("transverse flux addition") tm_transverse.begin() dtdx = dt/myg.dx dtdy = dt/myg.dy b = (2,1) for n in range(vars.nvar): # U_xl[i,j,:] = U_xl[i,j,:] - 0.5*dt/dy * (F_y[i-1,j+1,:] - F_y[i-1,j,:]) U_xl.v(buf=b, n=n)[:,:] += \ - 0.5*dtdy*(F_y.ip_jp(-1, 1, buf=b, n=n) - F_y.ip(-1, buf=b, n=n)) # U_xr[i,j,:] = U_xr[i,j,:] - 0.5*dt/dy * (F_y[i,j+1,:] - F_y[i,j,:]) U_xr.v(buf=b, n=n)[:,:] += \ - 0.5*dtdy*(F_y.jp(1, buf=b, n=n) - F_y.v(buf=b, n=n)) # U_yl[i,j,:] = U_yl[i,j,:] - 0.5*dt/dx * (F_x[i+1,j-1,:] - F_x[i,j-1,:]) U_yl.v(buf=b, n=n)[:,:] += \ - 0.5*dtdx*(F_x.ip_jp(1, -1, buf=b, n=n) - F_x.jp(-1, buf=b, n=n)) # U_yr[i,j,:] = U_yr[i,j,:] - 0.5*dt/dx * (F_x[i+1,j,:] - F_x[i,j,:]) U_yr.v(buf=b, n=n)[:,:] += \ - 0.5*dtdx*(F_x.ip(1, buf=b, n=n) - F_x.v(buf=b, n=n)) tm_transverse.end() #========================================================================= # construct the fluxes normal to the interfaces #========================================================================= # up until now, F_x and F_y stored the transverse fluxes, now we # overwrite with the fluxes normal to the interfaces tm_riem.begin() _fx = riemannFunc(1, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, solid.xl, solid.xr, gamma, U_xl.d, U_xr.d) _fy = riemannFunc(2, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, solid.yl, solid.yr, gamma, U_yl.d, U_yr.d) F_x = patch.ArrayIndexer(d=_fx, grid=myg) F_y = patch.ArrayIndexer(d=_fy, grid=myg) tm_riem.end() #========================================================================= # apply artificial viscosity #========================================================================= cvisc = rp.get_param("compressible.cvisc") _ax, _ay = interface_f.artificial_viscosity( myg.qx, myg.qy, myg.ng, myg.dx, myg.dy, cvisc, u.d, v.d) avisco_x = patch.ArrayIndexer(d=_ax, grid=myg) avisco_y = patch.ArrayIndexer(d=_ay, grid=myg) b = (2,1) # F_x = F_x + avisco_x * (U(i-1,j) - U(i,j)) F_x.v(buf=b, n=vars.idens)[:,:] += \ avisco_x.v(buf=b)*(dens.ip(-1, buf=b) - dens.v(buf=b)) F_x.v(buf=b, n=vars.ixmom)[:,:] += \ avisco_x.v(buf=b)*(xmom.ip(-1, buf=b) - xmom.v(buf=b)) F_x.v(buf=b, n=vars.iymom)[:,:] += \ avisco_x.v(buf=b)*(ymom.ip(-1, buf=b) - ymom.v(buf=b)) F_x.v(buf=b, n=vars.iener)[:,:] += \ avisco_x.v(buf=b)*(ener.ip(-1, buf=b) - ener.v(buf=b)) # F_y = F_y + avisco_y * (U(i,j-1) - U(i,j)) F_y.v(buf=b, n=vars.idens)[:,:] += \ avisco_y.v(buf=b)*(dens.jp(-1, buf=b) - dens.v(buf=b)) F_y.v(buf=b, n=vars.ixmom)[:,:] += \ avisco_y.v(buf=b)*(xmom.jp(-1, buf=b) - xmom.v(buf=b)) F_y.v(buf=b, n=vars.iymom)[:,:] += \ avisco_y.v(buf=b)*(ymom.jp(-1, buf=b) - ymom.v(buf=b)) F_y.v(buf=b, n=vars.iener)[:,:] += \ avisco_y.v(buf=b)*(ener.jp(-1, buf=b) - ener.v(buf=b)) tm_flux.end() return F_x, F_y
def unsplitFluxes(my_data, dt): """ unsplitFluxes returns the fluxes through the x and y interfaces by doing an unsplit reconstruction of the interface values and then solving the Riemann problem through all the interfaces at once currently we assume a gamma-law EOS grav is the gravitational acceleration in the y-direction """ pf = profile.timer("unsplitFluxes") pf.begin() myg = my_data.grid rp = my_data.rp #========================================================================= # compute the primitive variables #========================================================================= # Q = (rho, u, v, p) dens = my_data.get_var("density") xmom = my_data.get_var("x-momentum") ymom = my_data.get_var("y-momentum") ener = my_data.get_var("energy") r = dens # get the velocities u = xmom/dens v = ymom/dens # get the pressure e = (ener - 0.5*(xmom**2 + ymom**2)/dens)/dens p = eos.pres(dens, e) smallp = 1.e-10 p = p.clip(smallp) # apply a floor to the pressure #========================================================================= # compute the flattening coefficients #========================================================================= # there is a single flattening coefficient (xi) for all directions use_flattening = rp.get_param("compressible.use_flattening") if use_flattening: delta = rp.get_param("compressible.delta") z0 = rp.get_param("compressible.z0") z1 = rp.get_param("compressible.z1") xi_x = reconstruction_f.flatten(1, p, u, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi_y = reconstruction_f.flatten(2, p, v, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi = reconstruction_f.flatten_multid(xi_x, xi_y, p, myg.qx, myg.qy, myg.ng) else: xi = 1.0 #========================================================================= # x-direction #========================================================================= # monotonized central differences in x-direction pfa = profile.timer("limiting") pfa.begin() limiter = rp.get_param("compressible.limiter") if limiter == 0: limitFunc = reconstruction_f.nolimit elif limiter == 1: limitFunc = reconstruction_f.limit2 else: limitFunc = reconstruction_f.limit4 ldelta_r = xi*limitFunc(1, r, myg.qx, myg.qy, myg.ng) ldelta_u = xi*limitFunc(1, u, myg.qx, myg.qy, myg.ng) ldelta_v = xi*limitFunc(1, v, myg.qx, myg.qy, myg.ng) ldelta_p = xi*limitFunc(1, p, myg.qx, myg.qy, myg.ng) pfa.end() # left and right primitive variable states pfb = profile.timer("interfaceStates") pfb.begin() gamma = rp.get_param("eos.gamma") V_l = myg.scratch_array(vars.nvar) V_r = myg.scratch_array(vars.nvar) V_l, V_r = interface_f.states(1, myg.qx, myg.qy, myg.ng, myg.dx, dt, vars.nvar, gamma, r, u, v, p, ldelta_r, ldelta_u, ldelta_v, ldelta_p) pfb.end() # transform interface states back into conserved variables U_xl = myg.scratch_array(vars.nvar) U_xr = myg.scratch_array(vars.nvar) U_xl[:,:,vars.idens] = V_l[:,:,vars.irho] U_xl[:,:,vars.ixmom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iu] U_xl[:,:,vars.iymom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iv] U_xl[:,:,vars.iener] = eos.rhoe(V_l[:,:,vars.ip]) + \ 0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2) U_xr[:,:,vars.idens] = V_r[:,:,vars.irho] U_xr[:,:,vars.ixmom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iu] U_xr[:,:,vars.iymom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iv] U_xr[:,:,vars.iener] = eos.rhoe(V_r[:,:,vars.ip]) + \ 0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2) #========================================================================= # y-direction #========================================================================= # monotonized central differences in y-direction pfa.begin() ldelta_r = xi*limitFunc(2, r, myg.qx, myg.qy, myg.ng) ldelta_u = xi*limitFunc(2, u, myg.qx, myg.qy, myg.ng) ldelta_v = xi*limitFunc(2, v, myg.qx, myg.qy, myg.ng) ldelta_p = xi*limitFunc(2, p, myg.qx, myg.qy, myg.ng) pfa.end() # left and right primitive variable states pfb.begin() V_l, V_r = interface_f.states(2, myg.qx, myg.qy, myg.ng, myg.dy, dt, vars.nvar, gamma, r, u, v, p, ldelta_r, ldelta_u, ldelta_v, ldelta_p) pfb.end() # transform interface states back into conserved variables U_yl = myg.scratch_array(vars.nvar) U_yr = myg.scratch_array(vars.nvar) U_yl[:,:,vars.idens] = V_l[:,:,vars.irho] U_yl[:,:,vars.ixmom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iu] U_yl[:,:,vars.iymom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iv] U_yl[:,:,vars.iener] = eos.rhoe(V_l[:,:,vars.ip]) + \ 0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2) U_yr[:,:,vars.idens] = V_r[:,:,vars.irho] U_yr[:,:,vars.ixmom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iu] U_yr[:,:,vars.iymom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iv] U_yr[:,:,vars.iener] = eos.rhoe(V_r[:,:,vars.ip]) + \ 0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2) #========================================================================= # apply source terms #========================================================================= grav = rp.get_param("compressible.grav") # ymom_xl[i,j] += 0.5*dt*dens[i-1,j]*grav U_xl[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iymom] += \ 0.5*dt*dens[myg.ilo-2:myg.ihi+1,myg.jlo-1:myg.jhi+2]*grav U_xl[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iener] += \ 0.5*dt*ymom[myg.ilo-2:myg.ihi+1,myg.jlo-1:myg.jhi+2]*grav # ymom_xr[i,j] += 0.5*dt*dens[i,j]*grav U_xr[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iymom] += \ 0.5*dt*dens[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2]*grav U_xr[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iener] += \ 0.5*dt*ymom[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2]*grav # ymom_yl[i,j] += 0.5*dt*dens[i,j-1]*grav U_yl[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iymom] += \ 0.5*dt*dens[myg.ilo-1:myg.ihi+2,myg.jlo-2:myg.jhi+1]*grav U_yl[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iener] += \ 0.5*dt*ymom[myg.ilo-1:myg.ihi+2,myg.jlo-2:myg.jhi+1]*grav # ymom_yr[i,j] += 0.5*dt*dens[i,j]*grav U_yr[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iymom] += \ 0.5*dt*dens[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2]*grav U_yr[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iener] += \ 0.5*dt*ymom[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2]*grav #========================================================================= # compute transverse fluxes #========================================================================= pfc = profile.timer("riemann") pfc.begin() riemann = rp.get_param("compressible.riemann") if riemann == "HLLC": riemannFunc = interface_f.riemann_hllc elif riemann == "CGF": riemannFunc = interface_f.riemann_cgf else: msg.fail("ERROR: Riemann solver undefined") F_x = riemannFunc(1, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, gamma, U_xl, U_xr) F_y = riemannFunc(2, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, gamma, U_yl, U_yr) pfc.end() #========================================================================= # construct the interface values of U now #========================================================================= """ finally, we can construct the state perpendicular to the interface by adding the central difference part to the trasverse flux difference. The states that we represent by indices i,j are shown below (1,2,3,4): j+3/2--+----------+----------+----------+ | | | | | | | | j+1 -+ | | | | | | | | | | | 1: U_xl[i,j,:] = U j+1/2--+----------XXXXXXXXXXXX----------+ i-1/2,j,L | X X | | X X | j -+ 1 X 2 X | 2: U_xr[i,j,:] = U | X X | i-1/2,j,R | X 4 X | j-1/2--+----------XXXXXXXXXXXX----------+ | | 3 | | 3: U_yl[i,j,:] = U | | | | i,j-1/2,L j-1 -+ | | | | | | | | | | | 4: U_yr[i,j,:] = U j-3/2--+----------+----------+----------+ i,j-1/2,R | | | | | | | i-1 i i+1 i-3/2 i-1/2 i+1/2 i+3/2 remember that the fluxes are stored on the left edge, so F_x[i,j,:] = F_x i-1/2, j F_y[i,j,:] = F_y i, j-1/2 """ pfd = profile.timer("transverse flux addition") pfd.begin() # U_xl[i,j,:] = U_xl[i,j,:] - 0.5*dt/dy * (F_y[i-1,j+1,:] - F_y[i-1,j,:]) U_xl[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:] += \ - 0.5*dt/myg.dy * (F_y[myg.ilo-3:myg.ihi+1,myg.jlo-1:myg.jhi+3,:] - \ F_y[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2,:]) # U_xr[i,j,:] = U_xr[i,j,:] - 0.5*dt/dy * (F_y[i,j+1,:] - F_y[i,j,:]) U_xr[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:] += \ - 0.5*dt/myg.dy * (F_y[myg.ilo-2:myg.ihi+2,myg.jlo-1:myg.jhi+3,:] - \ F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:]) # U_yl[i,j,:] = U_yl[i,j,:] - 0.5*dt/dx * (F_x[i+1,j-1,:] - F_x[i,j-1,:]) U_yl[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:] += \ - 0.5*dt/myg.dx * (F_x[myg.ilo-1:myg.ihi+3,myg.jlo-3:myg.jhi+1,:] - \ F_x[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1,:]) # U_yr[i,j,:] = U_yr[i,j,:] - 0.5*dt/dx * (F_x[i+1,j,:] - F_x[i,j,:]) U_yr[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:] += \ - 0.5*dt/myg.dx * (F_x[myg.ilo-1:myg.ihi+3,myg.jlo-2:myg.jhi+2,:] - \ F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:]) pfd.end() #========================================================================= # construct the fluxes normal to the interfaces #========================================================================= # up until now, F_x and F_y stored the transverse fluxes, now we # overwrite with the fluxes normal to the interfaces pfc.begin() F_x = riemannFunc(1, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, gamma, U_xl, U_xr) F_y = riemannFunc(2, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, gamma, U_yl, U_yr) pfc.end() #========================================================================= # apply artificial viscosity #========================================================================= cvisc = rp.get_param("compressible.cvisc") (avisco_x, avisco_y) = interface_f.artificial_viscosity( \ myg.qx, myg.qy, myg.ng, myg.dx, myg.dy, \ cvisc, u, v) # F_x = F_x + avisco_x * (U(i-1,j) - U(i,j)) F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.idens] += \ avisco_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (dens[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2] - \ dens[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.ixmom] += \ avisco_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (xmom[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2] - \ xmom[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.iymom] += \ avisco_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (ymom[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2] - \ ymom[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.iener] += \ avisco_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (ener[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2] - \ ener[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) # F_y = F_y + avisco_y * (U(i,j-1) - U(i,j)) F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.idens] += \ avisco_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (dens[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1] - \ dens[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.ixmom] += \ avisco_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (xmom[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1] - \ xmom[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.iymom] += \ avisco_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (ymom[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1] - \ ymom[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.iener] += \ avisco_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (ener[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1] - \ ener[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) pf.end() return F_x, F_y
def fluxes(my_data, rp, vars, solid, tc): """ unsplitFluxes returns the fluxes through the x and y interfaces by doing an unsplit reconstruction of the interface values and then solving the Riemann problem through all the interfaces at once currently we assume a gamma-law EOS Parameters ---------- my_data : CellCenterData2d object The data object containing the grid and advective scalar that we are advecting. rp : RuntimeParameters object The runtime parameters for the simulation vars : Variables object The Variables object that tells us which indices refer to which variables tc : TimerCollection object The timers we are using to profile Returns ------- out : ndarray, ndarray The fluxes on the x- and y-interfaces """ tm_flux = tc.timer("unsplitFluxes") tm_flux.begin() myg = my_data.grid gamma = rp.get_param("eos.gamma") #========================================================================= # compute the primitive variables #========================================================================= # Q = (rho, u, v, p) dens = my_data.get_var("density") xmom = my_data.get_var("x-momentum") ymom = my_data.get_var("y-momentum") ener = my_data.get_var("energy") r = dens # get the velocities u = xmom / dens v = ymom / dens # get the pressure e = (ener - 0.5 * (xmom**2 + ymom**2) / dens) / dens p = eos.pres(gamma, dens, e) smallp = 1.e-10 p = p.clip(smallp) # apply a floor to the pressure #========================================================================= # compute the flattening coefficients #========================================================================= # there is a single flattening coefficient (xi) for all directions use_flattening = rp.get_param("compressible.use_flattening") if use_flattening: delta = rp.get_param("compressible.delta") z0 = rp.get_param("compressible.z0") z1 = rp.get_param("compressible.z1") xi_x = reconstruction_f.flatten(1, p, u, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi_y = reconstruction_f.flatten(2, p, v, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi = reconstruction_f.flatten_multid(xi_x, xi_y, p, myg.qx, myg.qy, myg.ng) else: xi = 1.0 # monotonized central differences in x-direction tm_limit = tc.timer("limiting") tm_limit.begin() limiter = rp.get_param("compressible.limiter") if limiter == 0: limitFunc = reconstruction_f.nolimit elif limiter == 1: limitFunc = reconstruction_f.limit2 else: limitFunc = reconstruction_f.limit4 _ldelta_rx = xi * limitFunc(1, r, myg.qx, myg.qy, myg.ng) _ldelta_ux = xi * limitFunc(1, u, myg.qx, myg.qy, myg.ng) _ldelta_vx = xi * limitFunc(1, v, myg.qx, myg.qy, myg.ng) _ldelta_px = xi * limitFunc(1, p, myg.qx, myg.qy, myg.ng) # wrap these in ArrayIndexer objects ldelta_rx = ai.ArrayIndexer(d=_ldelta_rx, grid=myg) ldelta_ux = ai.ArrayIndexer(d=_ldelta_ux, grid=myg) ldelta_vx = ai.ArrayIndexer(d=_ldelta_vx, grid=myg) ldelta_px = ai.ArrayIndexer(d=_ldelta_px, grid=myg) # monotonized central differences in y-direction _ldelta_ry = xi * limitFunc(2, r, myg.qx, myg.qy, myg.ng) _ldelta_uy = xi * limitFunc(2, u, myg.qx, myg.qy, myg.ng) _ldelta_vy = xi * limitFunc(2, v, myg.qx, myg.qy, myg.ng) _ldelta_py = xi * limitFunc(2, p, myg.qx, myg.qy, myg.ng) ldelta_ry = ai.ArrayIndexer(d=_ldelta_ry, grid=myg) ldelta_uy = ai.ArrayIndexer(d=_ldelta_uy, grid=myg) ldelta_vy = ai.ArrayIndexer(d=_ldelta_vy, grid=myg) ldelta_py = ai.ArrayIndexer(d=_ldelta_py, grid=myg) tm_limit.end() #========================================================================= # x-direction #========================================================================= # left and right primitive variable states tm_states = tc.timer("interfaceStates") tm_states.begin() V_l = myg.scratch_array(vars.nvar) V_r = myg.scratch_array(vars.nvar) V_l.ip(1, n=vars.irho, buf=2)[:, :] = r.v(buf=2) + 0.5 * ldelta_rx.v(buf=2) V_r.v(n=vars.irho, buf=2)[:, :] = r.v(buf=2) - 0.5 * ldelta_rx.v(buf=2) V_l.ip(1, n=vars.iu, buf=2)[:, :] = u.v(buf=2) + 0.5 * ldelta_ux.v(buf=2) V_r.v(n=vars.iu, buf=2)[:, :] = u.v(buf=2) - 0.5 * ldelta_ux.v(buf=2) V_l.ip(1, n=vars.iv, buf=2)[:, :] = v.v(buf=2) + 0.5 * ldelta_vx.v(buf=2) V_r.v(n=vars.iv, buf=2)[:, :] = v.v(buf=2) - 0.5 * ldelta_vx.v(buf=2) V_l.ip(1, n=vars.ip, buf=2)[:, :] = p.v(buf=2) + 0.5 * ldelta_px.v(buf=2) V_r.v(n=vars.ip, buf=2)[:, :] = p.v(buf=2) - 0.5 * ldelta_px.v(buf=2) tm_states.end() # transform interface states back into conserved variables U_xl = myg.scratch_array(vars.nvar) U_xr = myg.scratch_array(vars.nvar) U_xl[:, :, vars.idens] = V_l[:, :, vars.irho] U_xl[:, :, vars.ixmom] = V_l[:, :, vars.irho] * V_l[:, :, vars.iu] U_xl[:, :, vars.iymom] = V_l[:, :, vars.irho] * V_l[:, :, vars.iv] U_xl[:,:,vars.iener] = eos.rhoe(gamma, V_l[:,:,vars.ip]) + \ 0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2) U_xr[:, :, vars.idens] = V_r[:, :, vars.irho] U_xr[:, :, vars.ixmom] = V_r[:, :, vars.irho] * V_r[:, :, vars.iu] U_xr[:, :, vars.iymom] = V_r[:, :, vars.irho] * V_r[:, :, vars.iv] U_xr[:,:,vars.iener] = eos.rhoe(gamma, V_r[:,:,vars.ip]) + \ 0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2) #========================================================================= # y-direction #========================================================================= # left and right primitive variable states tm_states.begin() V_l.jp(1, n=vars.irho, buf=2)[:, :] = r.v(buf=2) + 0.5 * ldelta_ry.v(buf=2) V_r.v(n=vars.irho, buf=2)[:, :] = r.v(buf=2) - 0.5 * ldelta_ry.v(buf=2) V_l.jp(1, n=vars.iu, buf=2)[:, :] = u.v(buf=2) + 0.5 * ldelta_uy.v(buf=2) V_r.v(n=vars.iu, buf=2)[:, :] = u.v(buf=2) - 0.5 * ldelta_uy.v(buf=2) V_l.jp(1, n=vars.iv, buf=2)[:, :] = v.v(buf=2) + 0.5 * ldelta_vy.v(buf=2) V_r.v(n=vars.iv, buf=2)[:, :] = v.v(buf=2) - 0.5 * ldelta_vy.v(buf=2) V_l.jp(1, n=vars.ip, buf=2)[:, :] = p.v(buf=2) + 0.5 * ldelta_py.v(buf=2) V_r.v(n=vars.ip, buf=2)[:, :] = p.v(buf=2) - 0.5 * ldelta_py.v(buf=2) tm_states.end() # transform interface states back into conserved variables U_yl = myg.scratch_array(vars.nvar) U_yr = myg.scratch_array(vars.nvar) U_yl[:, :, vars.idens] = V_l[:, :, vars.irho] U_yl[:, :, vars.ixmom] = V_l[:, :, vars.irho] * V_l[:, :, vars.iu] U_yl[:, :, vars.iymom] = V_l[:, :, vars.irho] * V_l[:, :, vars.iv] U_yl[:,:,vars.iener] = eos.rhoe(gamma, V_l[:,:,vars.ip]) + \ 0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2) U_yr[:, :, vars.idens] = V_r[:, :, vars.irho] U_yr[:, :, vars.ixmom] = V_r[:, :, vars.irho] * V_r[:, :, vars.iu] U_yr[:, :, vars.iymom] = V_r[:, :, vars.irho] * V_r[:, :, vars.iv] U_yr[:,:,vars.iener] = eos.rhoe(gamma, V_r[:,:,vars.ip]) + \ 0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2) #========================================================================= # construct the fluxes normal to the interfaces #========================================================================= tm_riem = tc.timer("Riemann") tm_riem.begin() riemann = rp.get_param("compressible.riemann") if riemann == "HLLC": riemannFunc = interface_f.riemann_hllc elif riemann == "CGF": riemannFunc = interface_f.riemann_cgf else: msg.fail("ERROR: Riemann solver undefined") _fx = riemannFunc(1, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, solid.xl, solid.xr, gamma, U_xl, U_xr) _fy = riemannFunc(2, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, solid.yl, solid.yr, gamma, U_yl, U_yr) F_x = ai.ArrayIndexer(d=_fx, grid=myg) F_y = ai.ArrayIndexer(d=_fy, grid=myg) tm_riem.end() #========================================================================= # apply artificial viscosity #========================================================================= cvisc = rp.get_param("compressible.cvisc") _ax, _ay = interface_f.artificial_viscosity(myg.qx, myg.qy, myg.ng, myg.dx, myg.dy, cvisc, u, v) avisco_x = ai.ArrayIndexer(d=_ax, grid=myg) avisco_y = ai.ArrayIndexer(d=_ay, grid=myg) b = (2, 1) # F_x = F_x + avisco_x * (U(i-1,j) - U(i,j)) F_x.v(buf=b, n=vars.idens)[:,:] += \ avisco_x.v(buf=b)*(dens.ip(-1, buf=b) - dens.v(buf=b)) F_x.v(buf=b, n=vars.ixmom)[:,:] += \ avisco_x.v(buf=b)*(xmom.ip(-1, buf=b) - xmom.v(buf=b)) F_x.v(buf=b, n=vars.iymom)[:,:] += \ avisco_x.v(buf=b)*(ymom.ip(-1, buf=b) - ymom.v(buf=b)) F_x.v(buf=b, n=vars.iener)[:,:] += \ avisco_x.v(buf=b)*(ener.ip(-1, buf=b) - ener.v(buf=b)) # F_y = F_y + avisco_y * (U(i,j-1) - U(i,j)) F_y.v(buf=b, n=vars.idens)[:,:] += \ avisco_y.v(buf=b)*(dens.jp(-1, buf=b) - dens.v(buf=b)) F_y.v(buf=b, n=vars.ixmom)[:,:] += \ avisco_y.v(buf=b)*(xmom.jp(-1, buf=b) - xmom.v(buf=b)) F_y.v(buf=b, n=vars.iymom)[:,:] += \ avisco_y.v(buf=b)*(ymom.jp(-1, buf=b) - ymom.v(buf=b)) F_y.v(buf=b, n=vars.iener)[:,:] += \ avisco_y.v(buf=b)*(ener.jp(-1, buf=b) - ener.v(buf=b)) tm_flux.end() return F_x, F_y
def unsplit_fluxes(my_data, my_aux, rp, ivars, solid, tc, dt): """ unsplitFluxes returns the fluxes through the x and y interfaces by doing an unsplit reconstruction of the interface values and then solving the Riemann problem through all the interfaces at once currently we assume a gamma-law EOS The runtime parameter grav is assumed to be the gravitational acceleration in the y-direction Parameters ---------- my_data : CellCenterData2d object The data object containing the grid and advective scalar that we are advecting. rp : RuntimeParameters object The runtime parameters for the simulation vars : Variables object The Variables object that tells us which indices refer to which variables tc : TimerCollection object The timers we are using to profile dt : float The timestep we are advancing through. Returns ------- out : ndarray, ndarray The fluxes on the x- and y-interfaces """ tm_flux = tc.timer("unsplitFluxes") tm_flux.begin() myg = my_data.grid gamma = rp.get_param("eos.gamma") #========================================================================= # compute the primitive variables #========================================================================= # Q = (rho, u, v, p) dens = my_data.get_var("density") xmom = my_data.get_var("x-momentum") ymom = my_data.get_var("y-momentum") ener = my_data.get_var("energy") r, u, v, p, re = my_data.get_var("primitive") smallp = 1.e-10 p = p.clip(smallp) # apply a floor to the pressure #========================================================================= # compute the flattening coefficients #========================================================================= # there is a single flattening coefficient (xi) for all directions use_flattening = rp.get_param("compressible.use_flattening") if use_flattening: delta = rp.get_param("compressible.delta") z0 = rp.get_param("compressible.z0") z1 = rp.get_param("compressible.z1") xi_x = reconstruction_f.flatten(1, p, u, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi_y = reconstruction_f.flatten(2, p, v, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi = reconstruction_f.flatten_multid(xi_x, xi_y, p, myg.qx, myg.qy, myg.ng) else: xi = 1.0 # monotonized central differences in x-direction tm_limit = tc.timer("limiting") tm_limit.begin() limiter = rp.get_param("compressible.limiter") ldelta_rx = xi * reconstruction.limit(r, myg, 1, limiter) ldelta_ux = xi * reconstruction.limit(u, myg, 1, limiter) ldelta_vx = xi * reconstruction.limit(v, myg, 1, limiter) ldelta_px = xi * reconstruction.limit(p, myg, 1, limiter) ldelta_rex = xi * reconstruction.limit(re, myg, 1, limiter) # monotonized central differences in y-direction ldelta_ry = xi * reconstruction.limit(r, myg, 2, limiter) ldelta_uy = xi * reconstruction.limit(u, myg, 2, limiter) ldelta_vy = xi * reconstruction.limit(v, myg, 2, limiter) ldelta_py = xi * reconstruction.limit(p, myg, 2, limiter) ldelta_rey = xi * reconstruction.limit(re, myg, 2, limiter) tm_limit.end() gamcl = 1.4 * np.ones((136, 18), order='F') gamcr = gamcl #========================================================================= # x-direction #========================================================================= # left and right primitive variable states tm_states = tc.timer("interfaceStates") tm_states.begin() # r = np.array(r, order = 'F') # u = np.array(u, order = 'F') # v = np.array(v, order = 'F') # p = np.array(p, order = 'F') # re = np.array(re, order = 'F') # ldelta_rx = np.array(ldelta_rx, order = 'F') # ldelta_ux = np.array(ldelta_ux, order = 'F') # ldelta_vx = np.array(ldelta_vx, order = 'F') # ldelta_px = np.array(ldelta_px, order = 'F') # ldelta_rex = np.array(ldelta_rex, order = 'F') # myg.ng = 5 # ivars.nvar = 5 # V_l, V_r = interface_f.states(1, myg.qx, myg.qy, myg.ng, myg.dx, dt, # ivars.nvar, # gamma, # r, u, v, p, re, # ldelta_rx, ldelta_ux, ldelta_vx, ldelta_px, ldelta_rex) # myg.ng = 4 # ivars.nvar = 4 V_l, V_r = interface_f.states(1, myg.qx, myg.qy, myg.ng, myg.dx, dt, ivars.nvar, gamma, r, u, v, p, ldelta_rx, ldelta_ux, ldelta_vx, ldelta_px) # keyboard() tm_states.end() # transform interface states back into conserved variables U_xl = comp.prim_to_cons(V_l, gamma, ivars, myg) U_xr = comp.prim_to_cons(V_r, gamma, ivars, myg) #========================================================================= # y-direction #========================================================================= # left and right primitive variable states tm_states.begin() # V_l, V_r = interface_f.states(2, myg.qx, myg.qy, myg.ng, myg.dy, dt, # ivars.nvar, # gamma, # r, u, v, p, re, # ldelta_ry, ldelta_uy, ldelta_vy, ldelta_py, ldelta_rey) V_l, V_r = interface_f.states(2, myg.qx, myg.qy, myg.ng, myg.dx, dt, ivars.nvar, gamma, r, u, v, p, ldelta_rx, ldelta_ux, ldelta_vx, ldelta_px) tm_states.end() # transform interface states back into conserved variables U_yl = comp.prim_to_cons(V_l, gamma, ivars, myg) U_yr = comp.prim_to_cons(V_r, gamma, ivars, myg) #myg.ng = 4 #========================================================================= # apply source terms #========================================================================= grav = rp.get_param("compressible.grav") ymom_src = my_aux.get_var("ymom_src") ymom_src.v()[:, :] = dens.v() * grav my_aux.fill_BC("ymom_src") E_src = my_aux.get_var("E_src") E_src.v()[:, :] = ymom.v() * grav my_aux.fill_BC("E_src") # ymom_xl[i,j] += 0.5*dt*dens[i-1,j]*grav U_xl.v(buf=1, n=ivars.iymom)[:, :] += 0.5 * dt * ymom_src.ip(-1, buf=1) U_xl.v(buf=1, n=ivars.iener)[:, :] += 0.5 * dt * E_src.ip(-1, buf=1) # ymom_xr[i,j] += 0.5*dt*dens[i,j]*grav U_xr.v(buf=1, n=ivars.iymom)[:, :] += 0.5 * dt * ymom_src.v(buf=1) U_xr.v(buf=1, n=ivars.iener)[:, :] += 0.5 * dt * E_src.v(buf=1) # ymom_yl[i,j] += 0.5*dt*dens[i,j-1]*grav U_yl.v(buf=1, n=ivars.iymom)[:, :] += 0.5 * dt * ymom_src.jp(-1, buf=1) U_yl.v(buf=1, n=ivars.iener)[:, :] += 0.5 * dt * E_src.jp(-1, buf=1) # ymom_yr[i,j] += 0.5*dt*dens[i,j]*grav U_yr.v(buf=1, n=ivars.iymom)[:, :] += 0.5 * dt * ymom_src.v(buf=1) U_yr.v(buf=1, n=ivars.iener)[:, :] += 0.5 * dt * E_src.v(buf=1) #========================================================================= # compute transverse fluxes #========================================================================= tm_riem = tc.timer("riemann") tm_riem.begin() riemann = rp.get_param("compressible.riemann") riemann = "CGF" if riemann == "HLLC": riemannFunc = interface_f.riemann_hllc elif riemann == "CGF": riemannFunc = interface_f.riemann_cgf else: msg.fail("ERROR: Riemann solver undefined") #myg.ng = 5 _fx = riemannFunc(1, myg.qx, myg.qy, myg.ng, ivars.nvar, ivars.idens, ivars.ixmom, ivars.iymom, ivars.iener, solid.xl, solid.xr, gamma, U_xl, U_xr) _fy = riemannFunc(2, myg.qx, myg.qy, myg.ng, ivars.nvar, ivars.idens, ivars.ixmom, ivars.iymom, ivars.iener, solid.yl, solid.yr, gamma, U_yl, U_yr) F_x = ai.ArrayIndexer(d=_fx, grid=myg) F_y = ai.ArrayIndexer(d=_fy, grid=myg) tm_riem.end() #========================================================================= # construct the interface values of U now #========================================================================= """ finally, we can construct the state perpendicular to the interface by adding the central difference part to the trasverse flux difference. The states that we represent by indices i,j are shown below (1,2,3,4): j+3/2--+----------+----------+----------+ | | | | | | | | j+1 -+ | | | | | | | | | | | 1: U_xl[i,j,:] = U j+1/2--+----------XXXXXXXXXXXX----------+ i-1/2,j,L | X X | | X X | j -+ 1 X 2 X | 2: U_xr[i,j,:] = U | X X | i-1/2,j,R | X 4 X | j-1/2--+----------XXXXXXXXXXXX----------+ | | 3 | | 3: U_yl[i,j,:] = U | | | | i,j-1/2,L j-1 -+ | | | | | | | | | | | 4: U_yr[i,j,:] = U j-3/2--+----------+----------+----------+ i,j-1/2,R | | | | | | | i-1 i i+1 i-3/2 i-1/2 i+1/2 i+3/2 remember that the fluxes are stored on the left edge, so F_x[i,j,:] = F_x i-1/2, j F_y[i,j,:] = F_y i, j-1/2 """ tm_transverse = tc.timer("transverse flux addition") tm_transverse.begin() dtdx = dt / myg.dx dtdy = dt / myg.dy b = (2, 1) for n in range(ivars.nvar): # U_xl[i,j,:] = U_xl[i,j,:] - 0.5*dt/dy * (F_y[i-1,j+1,:] - F_y[i-1,j,:]) U_xl.v(buf=b, n=n)[:,:] += \ - 0.5*dtdy*(F_y.ip_jp(-1, 1, buf=b, n=n) - F_y.ip(-1, buf=b, n=n)) # U_xr[i,j,:] = U_xr[i,j,:] - 0.5*dt/dy * (F_y[i,j+1,:] - F_y[i,j,:]) U_xr.v(buf=b, n=n)[:,:] += \ - 0.5*dtdy*(F_y.jp(1, buf=b, n=n) - F_y.v(buf=b, n=n)) # U_yl[i,j,:] = U_yl[i,j,:] - 0.5*dt/dx * (F_x[i+1,j-1,:] - F_x[i,j-1,:]) U_yl.v(buf=b, n=n)[:,:] += \ - 0.5*dtdx*(F_x.ip_jp(1, -1, buf=b, n=n) - F_x.jp(-1, buf=b, n=n)) # U_yr[i,j,:] = U_yr[i,j,:] - 0.5*dt/dx * (F_x[i+1,j,:] - F_x[i,j,:]) U_yr.v(buf=b, n=n)[:,:] += \ - 0.5*dtdx*(F_x.ip(1, buf=b, n=n) - F_x.v(buf=b, n=n)) tm_transverse.end() #========================================================================= # construct the fluxes normal to the interfaces #========================================================================= # up until now, F_x and F_y stored the transverse fluxes, now we # overwrite with the fluxes normal to the interfaces tm_riem.begin() _fx = riemannFunc(1, myg.qx, myg.qy, myg.ng, ivars.nvar, ivars.idens, ivars.ixmom, ivars.iymom, ivars.iener, solid.xl, solid.xr, gamma, U_xl, U_xr) _fy = riemannFunc(2, myg.qx, myg.qy, myg.ng, ivars.nvar, ivars.idens, ivars.ixmom, ivars.iymom, ivars.iener, solid.yl, solid.yr, gamma, U_yl, U_yr) F_x = ai.ArrayIndexer(d=_fx, grid=myg) F_y = ai.ArrayIndexer(d=_fy, grid=myg) tm_riem.end() #========================================================================= # apply artificial viscosity #========================================================================= cvisc = rp.get_param("compressible.cvisc") # myg.ng = 4 # ivars.nvar = 4 _ax, _ay = interface_f.artificial_viscosity(myg.qx, myg.qy, myg.ng, myg.dx, myg.dy, cvisc, u, v) avisco_x = ai.ArrayIndexer(d=_ax, grid=myg) avisco_y = ai.ArrayIndexer(d=_ay, grid=myg) b = (2, 1) for n in range(ivars.nvar): # F_x = F_x + avisco_x * (U(i-1,j) - U(i,j)) var = my_data.get_var_by_index(n) F_x.v(buf=b, n=n)[:,:] += \ avisco_x.v(buf=b)*(var.ip(-1, buf=b) - var.v(buf=b)) # F_y = F_y + avisco_y * (U(i,j-1) - U(i,j)) F_y.v(buf=b, n=n)[:,:] += \ avisco_y.v(buf=b)*(var.jp(-1, buf=b) - var.v(buf=b)) tm_flux.end() return F_x, F_y
def unsplitFluxes(myData, dt): """ unsplitFluxes returns the fluxes through the x and y interfaces by doing an unsplit reconstruction of the interface values and then solving the Riemann problem through all the interfaces at once currently we assume a gamma-law EOS grav is the gravitational acceleration in the y-direction """ pf = profile.timer("unsplitFluxes") pf.begin() myg = myData.grid #========================================================================= # compute the primitive variables #========================================================================= # Q = (rho, u, v, p) dens = myData.getVarPtr("density") xmom = myData.getVarPtr("x-momentum") ymom = myData.getVarPtr("y-momentum") ener = myData.getVarPtr("energy") r = dens # get the velocities u = xmom/dens v = ymom/dens # get the pressure e = (ener - 0.5*(xmom**2 + ymom**2)/dens)/dens p = eos.pres(dens, e) smallp = 1.e-10 p = p.clip(smallp) # apply a floor to the pressure #========================================================================= # compute the flattening coefficients #========================================================================= # there is a single flattening coefficient (xi) for all directions use_flattening = runparams.getParam("compressible.use_flattening") if (use_flattening): smallp = 1.e-10 delta = runparams.getParam("compressible.delta") z0 = runparams.getParam("compressible.z0") z1 = runparams.getParam("compressible.z1") xi_x = reconstruction_f.flatten(1, p, u, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi_y = reconstruction_f.flatten(2, p, v, myg.qx, myg.qy, myg.ng, smallp, delta, z0, z1) xi = reconstruction_f.flatten_multid(xi_x, xi_y, p, myg.qx, myg.qy, myg.ng) else: xi = 1.0 #========================================================================= # x-direction #========================================================================= # monotonized central differences in x-direction pfa = profile.timer("limiting") pfa.begin() limiter = runparams.getParam("compressible.limiter") if (limiter == 0): limitFunc = reconstruction_f.nolimit elif (limiter == 1): limitFunc = reconstruction_f.limit2 else: limitFunc = reconstruction_f.limit4 ldelta_r = xi*limitFunc(1, r, myg.qx, myg.qy, myg.ng) ldelta_u = xi*limitFunc(1, u, myg.qx, myg.qy, myg.ng) ldelta_v = xi*limitFunc(1, v, myg.qx, myg.qy, myg.ng) ldelta_p = xi*limitFunc(1, p, myg.qx, myg.qy, myg.ng) pfa.end() # left and right primitive variable states pfb = profile.timer("interfaceStates") pfb.begin() gamma = runparams.getParam("eos.gamma") V_l = numpy.zeros((myg.qx, myg.qy, vars.nvar), dtype=numpy.float64) V_r = numpy.zeros((myg.qx, myg.qy, vars.nvar), dtype=numpy.float64) (V_l, V_r) = interface_f.states(1, myg.qx, myg.qy, myg.ng, myg.dx, dt, vars.nvar, gamma, r, u, v, p, ldelta_r, ldelta_u, ldelta_v, ldelta_p) pfb.end() # transform interface states back into conserved variables U_xl = numpy.zeros((myg.qx, myg.qy, myData.nvar), dtype=numpy.float64) U_xr = numpy.zeros((myg.qx, myg.qy, myData.nvar), dtype=numpy.float64) U_xl[:,:,vars.idens] = V_l[:,:,vars.irho] U_xl[:,:,vars.ixmom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iu] U_xl[:,:,vars.iymom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iv] U_xl[:,:,vars.iener] = eos.rhoe(V_l[:,:,vars.ip]) + \ 0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2) U_xr[:,:,vars.idens] = V_r[:,:,vars.irho] U_xr[:,:,vars.ixmom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iu] U_xr[:,:,vars.iymom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iv] U_xr[:,:,vars.iener] = eos.rhoe(V_r[:,:,vars.ip]) + \ 0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2) #========================================================================= # y-direction #========================================================================= # monotonized central differences in y-direction pfa.begin() ldelta_r = xi*limitFunc(2, r, myg.qx, myg.qy, myg.ng) ldelta_u = xi*limitFunc(2, u, myg.qx, myg.qy, myg.ng) ldelta_v = xi*limitFunc(2, v, myg.qx, myg.qy, myg.ng) ldelta_p = xi*limitFunc(2, p, myg.qx, myg.qy, myg.ng) pfa.end() # left and right primitive variable states pfb.begin() (V_l, V_r) = interface_f.states(2, myg.qx, myg.qy, myg.ng, myg.dy, dt, vars.nvar, gamma, r, u, v, p, ldelta_r, ldelta_u, ldelta_v, ldelta_p) pfb.end() # transform interface states back into conserved variables U_yl = numpy.zeros((myg.qx, myg.qy, myData.nvar), dtype=numpy.float64) U_yr = numpy.zeros((myg.qx, myg.qy, myData.nvar), dtype=numpy.float64) U_yl[:,:,vars.idens] = V_l[:,:,vars.irho] U_yl[:,:,vars.ixmom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iu] U_yl[:,:,vars.iymom] = V_l[:,:,vars.irho]*V_l[:,:,vars.iv] U_yl[:,:,vars.iener] = eos.rhoe(V_l[:,:,vars.ip]) + \ 0.5*V_l[:,:,vars.irho]*(V_l[:,:,vars.iu]**2 + V_l[:,:,vars.iv]**2) U_yr[:,:,vars.idens] = V_r[:,:,vars.irho] U_yr[:,:,vars.ixmom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iu] U_yr[:,:,vars.iymom] = V_r[:,:,vars.irho]*V_r[:,:,vars.iv] U_yr[:,:,vars.iener] = eos.rhoe(V_r[:,:,vars.ip]) + \ 0.5*V_r[:,:,vars.irho]*(V_r[:,:,vars.iu]**2 + V_r[:,:,vars.iv]**2) #========================================================================= # apply source terms #========================================================================= grav = runparams.getParam("compressible.grav") # ymom_xl[i,j] += 0.5*dt*dens[i-1,j]*grav U_xl[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iymom] += \ 0.5*dt*dens[myg.ilo-2:myg.ihi+1,myg.jlo-1:myg.jhi+2]*grav U_xl[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iener] += \ 0.5*dt*ymom[myg.ilo-2:myg.ihi+1,myg.jlo-1:myg.jhi+2]*grav # ymom_xr[i,j] += 0.5*dt*dens[i,j]*grav U_xr[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iymom] += \ 0.5*dt*dens[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2]*grav U_xr[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iener] += \ 0.5*dt*ymom[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2]*grav # ymom_yl[i,j] += 0.5*dt*dens[i,j-1]*grav U_yl[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iymom] += \ 0.5*dt*dens[myg.ilo-1:myg.ihi+2,myg.jlo-2:myg.jhi+1]*grav U_yl[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iener] += \ 0.5*dt*ymom[myg.ilo-1:myg.ihi+2,myg.jlo-2:myg.jhi+1]*grav # ymom_yr[i,j] += 0.5*dt*dens[i,j]*grav U_yr[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iymom] += \ 0.5*dt*dens[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2]*grav U_yr[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2,vars.iener] += \ 0.5*dt*ymom[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2]*grav #========================================================================= # compute transverse fluxes #========================================================================= pfc = profile.timer("riemann") pfc.begin() riemann = runparams.getParam("compressible.riemann") if (riemann == "HLLC"): riemannFunc = interface_f.riemann_hllc elif (riemann == "CGF"): riemannFunc = interface_f.riemann_cgf else: msg.fail("ERROR: Riemann solver undefined") F_x = riemannFunc(1, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, gamma, U_xl, U_xr) F_y = riemannFunc(2, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, gamma, U_yl, U_yr) pfc.end() #========================================================================= # construct the interface values of U now #========================================================================= """ finally, we can construct the state perpendicular to the interface by adding the central difference part to the trasverse flux difference. The states that we represent by indices i,j are shown below (1,2,3,4): j+3/2--+----------+----------+----------+ | | | | | | | | j+1 -+ | | | | | | | | | | | 1: U_xl[i,j,:] = U j+1/2--+----------XXXXXXXXXXXX----------+ i-1/2,j,L | X X | | X X | j -+ 1 X 2 X | 2: U_xr[i,j,:] = U | X X | i-1/2,j,R | X 4 X | j-1/2--+----------XXXXXXXXXXXX----------+ | | 3 | | 3: U_yl[i,j,:] = U | | | | i,j-1/2,L j-1 -+ | | | | | | | | | | | 4: U_yr[i,j,:] = U j-3/2--+----------+----------+----------+ i,j-1/2,R | | | | | | | i-1 i i+1 i-3/2 i-1/2 i+1/2 i+3/2 remember that the fluxes are stored on the left edge, so F_x[i,j,:] = F_x i-1/2, j F_y[i,j,:] = F_y i, j-1/2 """ pfd = profile.timer("transverse flux addition") pfd.begin() # U_xl[i,j,:] = U_xl[i,j,:] - 0.5*dt/dy * (F_y[i-1,j+1,:] - F_y[i-1,j,:]) U_xl[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:] += \ - 0.5*dt/myg.dy * (F_y[myg.ilo-3:myg.ihi+1,myg.jlo-1:myg.jhi+3,:] - \ F_y[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2,:]) # U_xr[i,j,:] = U_xr[i,j,:] - 0.5*dt/dy * (F_y[i,j+1,:] - F_y[i,j,:]) U_xr[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:] += \ - 0.5*dt/myg.dy * (F_y[myg.ilo-2:myg.ihi+2,myg.jlo-1:myg.jhi+3,:] - \ F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:]) # U_yl[i,j,:] = U_yl[i,j,:] - 0.5*dt/dx * (F_x[i+1,j-1,:] - F_x[i,j-1,:]) U_yl[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:] += \ - 0.5*dt/myg.dx * (F_x[myg.ilo-1:myg.ihi+3,myg.jlo-3:myg.jhi+1,:] - \ F_x[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1,:]) # U_yr[i,j,:] = U_yr[i,j,:] - 0.5*dt/dx * (F_x[i+1,j,:] - F_x[i,j,:]) U_yr[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:] += \ - 0.5*dt/myg.dx * (F_x[myg.ilo-1:myg.ihi+3,myg.jlo-2:myg.jhi+2,:] - \ F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,:]) pfd.end() #========================================================================= # construct the fluxes normal to the interfaces #========================================================================= # up until now, F_x and F_y stored the transverse fluxes, now we # overwrite with the fluxes normal to the interfaces pfc.begin() F_x = riemannFunc(1, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, gamma, U_xl, U_xr) F_y = riemannFunc(2, myg.qx, myg.qy, myg.ng, vars.nvar, vars.idens, vars.ixmom, vars.iymom, vars.iener, gamma, U_yl, U_yr) pfc.end() #========================================================================= # apply artificial viscosity #========================================================================= cvisc = runparams.getParam("compressible.cvisc") (avisco_x, avisco_y) = interface_f.artificial_viscosity( \ myg.qx, myg.qy, myg.ng, myg.dx, myg.dy, \ cvisc, u, v) # F_x = F_x + avisco_x * (U(i-1,j) - U(i,j)) F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.idens] += \ avisco_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (dens[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2] - \ dens[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.ixmom] += \ avisco_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (xmom[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2] - \ xmom[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.iymom] += \ avisco_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (ymom[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2] - \ ymom[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.iener] += \ avisco_x[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (ener[myg.ilo-3:myg.ihi+1,myg.jlo-2:myg.jhi+2] - \ ener[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) # F_y = F_y + avisco_y * (U(i,j-1) - U(i,j)) F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.idens] += \ avisco_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (dens[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1] - \ dens[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.ixmom] += \ avisco_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (xmom[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1] - \ xmom[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.iymom] += \ avisco_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (ymom[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1] - \ ymom[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) F_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2,vars.iener] += \ avisco_y[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]* \ (ener[myg.ilo-2:myg.ihi+2,myg.jlo-3:myg.jhi+1] - \ ener[myg.ilo-2:myg.ihi+2,myg.jlo-2:myg.jhi+2]) pf.end() return F_x, F_y