"""compressible-specific boundary conditions. Here, in particular, weimplement an HSE BC in the vertical direction.Note: the pyro BC routines operate on a single variable at a time, sosome work will necessarily be repeated.Also note: we may come in here with the aux_data (source terms), sowe'll do a special case for them"""importmathimportnumpyasnpfrompyro.compressibleimporteosfrompyro.utilimportmsg
[docs]defuser(bc_name,bc_edge,variable,ccdata):""" A hydrostatic boundary. This integrates the equation of HSE into the ghost cells to get the pressure and density under the assumption that the specific internal energy is constant. Upon exit, the ghost cells for the input variable will be set Parameters ---------- bc_name : {'hse'} The descriptive name for the boundary condition -- this allows for pyro to have multiple types of user-supplied boundary conditions. For this module, it needs to be 'hse'. bc_edge : {'ylb', 'yrb'} The boundary to update: ylb = lower y boundary; yrb = upper y boundary. variable : {'density', 'x-momentum', 'y-momentum', 'energy'} The variable whose ghost cells we are filling ccdata : CellCenterData2d object The data object """# pylint: disable=too-many-nested-blocksmyg=ccdata.gridifbc_name=="hse":ifbc_edge=="ylb":# lower y boundary# we will take the density to be constant, the velocity to# be outflow, and the pressure to be in HSEifvariablein["density","x-momentum","y-momentum","dens_src","xmom_src","ymom_src","E_src","fuel","ash"]:v=ccdata.get_var(variable)j=myg.jlo-1whilej>=0:v[:,j]=v[:,myg.jlo]j-=1elifvariable=="energy":dens=ccdata.get_var("density")xmom=ccdata.get_var("x-momentum")ymom=ccdata.get_var("y-momentum")ener=ccdata.get_var("energy")grav=ccdata.get_aux("grav")gamma=ccdata.get_aux("gamma")dens_base=dens[:,myg.jlo]ke_base=0.5*(xmom[:,myg.jlo]**2+ymom[:,myg.jlo]**2)/ \
dens[:,myg.jlo]eint_base=(ener[:,myg.jlo]-ke_base)/dens[:,myg.jlo]pres_base=eos.pres(gamma,dens_base,eint_base)# we are assuming that the density is constant in this# formulation of HSE, so the pressure comes simply from# differencing the HSE equationj=myg.jlo-1whilej>=0:pres_below=pres_base-grav*dens_base*myg.dyrhoe=eos.rhoe(gamma,pres_below)ener[:,j]=rhoe+ke_basepres_base=pres_below.copy()j-=1else:raiseNotImplementedError("variable not defined")elifbc_edge=="yrb":# upper y boundary# we will take the density to be constant, the velocity to# be outflow, and the pressure to be in HSEifvariablein["density","x-momentum","y-momentum","dens_src","xmom_src","ymom_src","E_src","fuel","ash"]:v=ccdata.get_var(variable)forjinrange(myg.jhi+1,myg.jhi+myg.ng+1):v[:,j]=v[:,myg.jhi]elifvariable=="energy":dens=ccdata.get_var("density")xmom=ccdata.get_var("x-momentum")ymom=ccdata.get_var("y-momentum")ener=ccdata.get_var("energy")grav=ccdata.get_aux("grav")gamma=ccdata.get_aux("gamma")dens_base=dens[:,myg.jhi]ke_base=0.5*(xmom[:,myg.jhi]**2+ymom[:,myg.jhi]**2)/ \
dens[:,myg.jhi]eint_base=(ener[:,myg.jhi]-ke_base)/dens[:,myg.jhi]pres_base=eos.pres(gamma,dens_base,eint_base)# we are assuming that the density is constant in this# formulation of HSE, so the pressure comes simply from# differencing the HSE equationforjinrange(myg.jhi+1,myg.jhi+myg.ng+1):pres_above=pres_base+grav*dens_base*myg.dyrhoe=eos.rhoe(gamma,pres_above)ener[:,j]=rhoe+ke_basepres_base=pres_above.copy()else:raiseNotImplementedError("variable not defined")else:msg.fail("error: hse BC not supported for xlb or xrb")elifbc_name=="ambient":# we'll assume that the problem setup defines these# they will not be available for source termsambient_rho=ccdata.get_aux("ambient_rho")ambient_u=ccdata.get_aux("ambient_u")ambient_v=ccdata.get_aux("ambient_v")ambient_p=ccdata.get_aux("ambient_p")ifbc_edge=="yrb":# upper y boundary# by default, use a zero gradientv=ccdata.get_var(variable)forjinrange(myg.jhi+1,myg.jhi+myg.ng+1):v[:,j]=v[:,myg.jhi]# overwrite with ambient conditionsifvariable=="density":v[:,myg.jhi+1:myg.jhi+myg.ng+1]=ambient_rhoelifvariable=="x-momentum":rhou=ambient_rho*ambient_uv[:,myg.jhi+1:myg.jhi+myg.ng+1]=rhouelifvariable=="y-momentum":rhov=ambient_rho*ambient_vv[:,myg.jhi+1:myg.jhi+myg.ng+1]=rhovelifvariable=="energy":gamma=ccdata.get_aux("gamma")ke=0.5*ambient_rho*(ambient_u**2+ambient_v**2)rhoE=ambient_p/(gamma-1.0)+kev[:,myg.jhi+1:myg.jhi+myg.ng+1]=rhoEelse:msg.fail("error: ambient BC not supported for xlb, xrb, or ylb")elifbc_name=="ramp":# Boundary conditions for double Mach reflection problemgamma=ccdata.get_aux("gamma")ifbc_edge=="xlb":# lower x boundary# inflow condition with post shock setupv=ccdata.get_var(variable)i=myg.ilo-1ifvariablein["density","x-momentum","y-momentum","energy"]:val=inflow_post_bc(variable,gamma)whilei>=0:v[i,:]=vali=i-1else:v[:,:]=0.0# no source termelifbc_edge=="ylb":# lower y boundary# for x > 1./6., reflective boundary# for x < 1./6., inflow with post shock setupifvariablein["density","x-momentum","y-momentum","energy"]:v=ccdata.get_var(variable)j=myg.jlo-1jj=0whilej>=0:xcen_l=myg.x<1.0/6.0xcen_r=myg.x>=1.0/6.0v[xcen_l,j]=inflow_post_bc(variable,gamma)ifvariable=="y-momentum":v[xcen_r,j]=-1.0*v[xcen_r,myg.jlo+jj]else:v[xcen_r,j]=v[xcen_r,myg.jlo+jj]j=j-1jj=jj+1else:v=ccdata.get_var(variable)v[:,:]=0.0# no source termelifbc_edge=="yrb":# upper y boundary# time-dependent boundary, the shockfront moves with a 10 mach velocity forming an angle# to the x-axis of 30 degrees clockwise.# x coordinate of the grid is used to judge whether the cell belongs to pure post shock area,# the pure pre shock area or the mixed area.ifvariablein["density","x-momentum","y-momentum","energy"]:v=ccdata.get_var(variable)forjinrange(myg.jhi+1,myg.jhi+myg.ng+1):shockfront_up=1.0/6.0+(myg.y[j]+0.5*myg.dy*math.sqrt(3))/math.tan(math.pi/3.0) \
+(10.0/math.sin(math.pi/3.0))*ccdata.tshockfront_down=1.0/6.0+(myg.y[j]-0.5*myg.dy*math.sqrt(3))/math.tan(math.pi/3.0) \
+(10.0/math.sin(math.pi/3.0))*ccdata.tshockfront=np.array([shockfront_down,shockfront_up])foriinrange(myg.ihi+myg.ng+1):v[i,j]=0.0cx_down=myg.x[i]-0.5*myg.dx*math.sqrt(3)cx_up=myg.x[i]+0.5*myg.dx*math.sqrt(3)cx=np.array([cx_down,cx_up])forsfinshockfront:forxincx:ifx<sf:v[i,j]=v[i,j]+0.25*inflow_post_bc(variable,gamma)else:v[i,j]=v[i,j]+0.25*inflow_pre_bc(variable,gamma)else:v=ccdata.get_var(variable)v[:,:]=0.0# no source termelse:msg.fail(f"error: bc type {bc_name} not supported")
[docs]definflow_post_bc(var,g):# inflow boundary condition with post shock setupr_l=8.0u_l=7.1447096v_l=-4.125p_l=116.5ifvar=="density":vl=r_lelifvar=="x-momentum":vl=r_l*u_lelifvar=="y-momentum":vl=r_l*v_lelifvar=="energy":vl=p_l/(g-1.0)+0.5*r_l*(u_l*u_l+v_l*v_l)else:vl=0.0returnvl
[docs]definflow_pre_bc(var,g):# pre shock setupr_r=1.4u_r=0.0v_r=0.0p_r=1.0ifvar=="density":vl=r_relifvar=="x-momentum":vl=r_r*u_relifvar=="y-momentum":vl=r_r*v_relifvar=="energy":vl=p_r/(g-1.0)+0.5*r_r*(u_r*u_r+v_r*v_r)else:vl=0.0returnvl