def timestep(myData): """ compute the CFL timestep for the current patch. """ cfl = runparams.getParam("driver.cfl") # get the variables we need dens = myData.getVarPtr("density") xmom = myData.getVarPtr("x-momentum") ymom = myData.getVarPtr("y-momentum") ener = myData.getVarPtr("energy") # we need to compute the pressure u = xmom / dens v = ymom / dens e = (ener - 0.5 * dens * (u * u + v * v)) / dens p = eos.pres(dens, e) # compute the sounds speed gamma = runparams.getParam("eos.gamma") cs = numpy.sqrt(gamma * p / dens) # the timestep is min(dx/(|u| + cs), dy/(|v| + cs)) xtmp = myData.grid.dx / (abs(u) + cs) ytmp = myData.grid.dy / (abs(v) + cs) dt = cfl * min(xtmp.min(), ytmp.min()) return dt
def evolve(myData, dt): pf = profile.timer("evolve") pf.begin() dens = myData.getVarPtr("density") xmom = myData.getVarPtr("x-momentum") ymom = myData.getVarPtr("y-momentum") ener = myData.getVarPtr("energy") grav = runparams.getParam("compressible.grav") myg = myData.grid (Flux_x, Flux_y) = unsplitFluxes(myData, dt) #Flux_x = numpy.zeros((myg.qx, myg.qy, myData.nvar), dtype=numpy.float64) #Flux_y = numpy.zeros((myg.qx, myg.qy, myData.nvar), dtype=numpy.float64) old_dens = dens.copy() old_ymom = ymom.copy() # conservative update dtdx = dt/myg.dx dtdy = dt/myg.dy dens[myg.ilo:myg.ihi+1,myg.jlo:myg.jhi+1] += \ dtdx*(Flux_x[myg.ilo :myg.ihi+1,myg.jlo :myg.jhi+1,vars.idens] - \ Flux_x[myg.ilo+1:myg.ihi+2,myg.jlo :myg.jhi+1,vars.idens]) + \ dtdy*(Flux_y[myg.ilo :myg.ihi+1,myg.jlo :myg.jhi+1,vars.idens] - \ Flux_y[myg.ilo :myg.ihi+1,myg.jlo+1:myg.jhi+2,vars.idens]) xmom[myg.ilo:myg.ihi+1,myg.jlo:myg.jhi+1] += \ dtdx*(Flux_x[myg.ilo :myg.ihi+1,myg.jlo :myg.jhi+1,vars.ixmom] - \ Flux_x[myg.ilo+1:myg.ihi+2,myg.jlo :myg.jhi+1,vars.ixmom]) + \ dtdy*(Flux_y[myg.ilo :myg.ihi+1,myg.jlo :myg.jhi+1,vars.ixmom] - \ Flux_y[myg.ilo :myg.ihi+1,myg.jlo+1:myg.jhi+2,vars.ixmom]) ymom[myg.ilo:myg.ihi+1,myg.jlo:myg.jhi+1] += \ dtdx*(Flux_x[myg.ilo :myg.ihi+1,myg.jlo :myg.jhi+1,vars.iymom] - \ Flux_x[myg.ilo+1:myg.ihi+2,myg.jlo :myg.jhi+1,vars.iymom]) + \ dtdy*(Flux_y[myg.ilo :myg.ihi+1,myg.jlo :myg.jhi+1,vars.iymom] - \ Flux_y[myg.ilo :myg.ihi+1,myg.jlo+1:myg.jhi+2,vars.iymom]) ener[myg.ilo:myg.ihi+1,myg.jlo:myg.jhi+1] += \ dtdx*(Flux_x[myg.ilo :myg.ihi+1,myg.jlo :myg.jhi+1,vars.iener] - \ Flux_x[myg.ilo+1:myg.ihi+2,myg.jlo :myg.jhi+1,vars.iener]) + \ dtdy*(Flux_y[myg.ilo :myg.ihi+1,myg.jlo :myg.jhi+1,vars.iener] - \ Flux_y[myg.ilo :myg.ihi+1,myg.jlo+1:myg.jhi+2,vars.iener]) # gravitational source terms ymom += 0.5*dt*(dens + old_dens)*grav ener += 0.5*dt*(ymom + old_ymom)*grav pf.end()
def rhoe(pres): """ given the pressure, return (rho * e) """ gamma = runparams.getParam("eos.gamma") rhoe = pres / (gamma - 1.0) return rhoe
def rhoe(pres): """ given the pressure, return (rho * e) """ gamma = runparams.getParam("eos.gamma") rhoe = pres/(gamma - 1.0) return rhoe
def pres(dens, eint): """ given the density and the specific internal energy, return the pressure """ gamma = runparams.getParam("eos.gamma") p = dens*eint*(gamma - 1.0) return p
def dens(pres, eint): """ given the pressure and the specific internal energy, return the density """ gamma = runparams.getParam("eos.gamma") dens = pres/(eint*(gamma - 1.0)) return dens
def pres(dens, eint): """ given the density and the specific internal energy, return the pressure """ gamma = runparams.getParam("eos.gamma") p = dens * eint * (gamma - 1.0) return p
def dens(pres, eint): """ given the pressure and the specific internal energy, return the density """ gamma = runparams.getParam("eos.gamma") dens = pres / (eint * (gamma - 1.0)) return dens
def timestep(myData): """ compute the CFL timestep for the current patch. """ cfl = runparams.getParam("driver.cfl") # get the variables we need dens = myData.getVarPtr("density") xmom = myData.getVarPtr("x-momentum") ymom = myData.getVarPtr("y-momentum") ener = myData.getVarPtr("energy") # we need to compute the pressure u = xmom/dens v = ymom/dens e = (ener - 0.5*dens*(u*u + v*v))/dens p = eos.pres(dens, e) # compute the sounds speed gamma = runparams.getParam("eos.gamma") cs = numpy.sqrt(gamma*p/dens) # the timestep is min(dx/(|u| + cs), dy/(|v| + cs)) xtmp = myData.grid.dx/(abs(u) + cs) ytmp = myData.grid.dy/(abs(v) + cs) dt = cfl*min(xtmp.min(), ytmp.min()) return dt
def initData(myPatch): """ initialize the sod problem """ msg.bold("initializing the sod problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in sod.py" print myPatch.__class__ sys.exit() # get the sod parameters dens_left = runparams.getParam("sod.dens_left") dens_right = runparams.getParam("sod.dens_right") u_left = runparams.getParam("sod.u_left") u_right = runparams.getParam("sod.u_right") p_left = runparams.getParam("sod.p_left") p_right = runparams.getParam("sod.p_right") # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") # initialize the components, remember, that ener here is rho*eint # + 0.5*rho*v**2, where eint is the specific internal energy # (erg/g) xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") gamma = runparams.getParam("eos.gamma") direction = runparams.getParam("sod.direction") xctr = 0.5*(xmin + xmax) yctr = 0.5*(ymin + ymax) myg = myPatch.grid # there is probably an easier way to do this, but for now, we # will just do an explicit loop. Also, we really want to set # the pressue and get the internal energy from that, and then # compute the total energy (which is what we store). For now # we will just fake this. if direction == "x": i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: if myg.x[i] <= xctr: dens[i,j] = dens_left xmom[i,j] = dens_left*u_left ymom[i,j] = 0.0 ener[i,j] = p_left/(gamma - 1.0) + 0.5*xmom[i,j]*u_left else: dens[i,j] = dens_right xmom[i,j] = dens_right*u_right ymom[i,j] = 0.0 ener[i,j] = p_right/(gamma - 1.0) + 0.5*xmom[i,j]*u_right j += 1 i += 1 else: i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: if myg.y[j] <= yctr: dens[i,j] = dens_left xmom[i,j] = 0.0 ymom[i,j] = dens_left*u_left ener[i,j] = p_left/(gamma - 1.0) + 0.5*ymom[i,j]*u_left else: dens[i,j] = dens_right xmom[i,j] = 0.0 ymom[i,j] = dens_right*u_right ener[i,j] = p_right/(gamma - 1.0) + 0.5*ymom[i,j]*u_right j += 1 i += 1
def initData(myPatch): """ initialize the Rayleigh-Taylor instability problem """ msg.bold("initializing the Rayleigh-Taylor instability problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in raytay.py" print myPatch.__class__ sys.exit() # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") # get the other input parameters for the problem gamma = runparams.getParam("eos.gamma") grav = runparams.getParam("compressible.grav") dens_up = runparams.getParam("raytay.dens_up") dens_down = runparams.getParam("raytay.dens_down") A = runparams.getParam("raytay.pert_amplitude_factor") p0 = runparams.getParam("raytay.pressure_bottom") sigma = runparams.getParam("raytay.sigma") # get the grid parameters xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") yctr = 0.5*(ymin + ymax) # initialize the components, remember, that ener here is # rho*eint + 0.5*rho*v**2, where eint is the specific # internal energy (erg/g) xmom[:,:] = 0.0 ymom[:,:] = 0.0 dens[:,:] = 0.0 Lx = xmax - xmin # set the density and energy to be stratified in the y-direction myg = myPatch.grid j = myg.jlo while j <= myg.jhi: if myg.y[j] < yctr : dens[:,j] = dens_down pres = dens_down*grav*myg.y[j] + p0 ener[:,j] = pres/(gamma - 1.0) #+ 0.5*(xmom[:,j]**2 + ymom[:,j]**2)/dens_down else: dens[:,j] = dens_up pres = p0 + dens_down*grav*yctr + dens_up*grav*(myg.y[j] - yctr) ener[:,j] = pres/(gamma - 1.0) #+ 0.5*(xmom[:,j]**2 + ymom[:,j]**2)/dens_up j += 1 i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: v_pert = A*numpy.sin(2.0*numpy.pi*myg.x[i]/Lx)*numpy.exp( - (( myg.y[j]-yctr)/sigma)**2 ) # momentum ymom[i,j] = dens[i,j]*v_pert # internal energy ener[i,j] += 0.5*(xmom[i,j]**2 - ymom[i,j]**2)/dens[i,j] j += 1 i += 1
def initData(myPatch): """ initialize the quadrant problem """ msg.bold("initializing the quadrant problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in quad.py" print myPatch.__class__ sys.exit() # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") # initialize the components, remember, that ener here is # rho*eint + 0.5*rho*v**2, where eint is the specific # internal energy (erg/g) r1 = runparams.getParam("quadrant.rho1") u1 = runparams.getParam("quadrant.u1") v1 = runparams.getParam("quadrant.v1") p1 = runparams.getParam("quadrant.p1") r2 = runparams.getParam("quadrant.rho2") u2 = runparams.getParam("quadrant.u2") v2 = runparams.getParam("quadrant.v2") p2 = runparams.getParam("quadrant.p2") r3 = runparams.getParam("quadrant.rho3") u3 = runparams.getParam("quadrant.u3") v3 = runparams.getParam("quadrant.v3") p3 = runparams.getParam("quadrant.p3") r4 = runparams.getParam("quadrant.rho4") u4 = runparams.getParam("quadrant.u4") v4 = runparams.getParam("quadrant.v4") p4 = runparams.getParam("quadrant.p4") cx = runparams.getParam("quadrant.cx") cy = runparams.getParam("quadrant.cy") gamma = runparams.getParam("eos.gamma") xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") # there is probably an easier way to do this, but for now, we # will just do an explicit loop. Also, we really want to set # the pressue and get the internal energy from that, and then # compute the total energy (which is what we store). For now # we will just fake this myg = myPatch.grid i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: if (myg.x[i] >= cx and myg.y[j] >= cy): # quadrant 1 dens[i, j] = r1 xmom[i, j] = r1 * u1 ymom[i, j] = r1 * v1 ener[i, j] = p1 / (gamma - 1.0) + 0.5 * r1 * (u1 * u1 + v1 * v1) elif (myg.x[i] < cx and myg.y[j] >= cy): # quadrant 2 dens[i, j] = r2 xmom[i, j] = r2 * u2 ymom[i, j] = r2 * v2 ener[i, j] = p2 / (gamma - 1.0) + 0.5 * r2 * (u2 * u2 + v2 * v2) elif (myg.x[i] < cx and myg.y[j] < cy): # quadrant 3 dens[i, j] = r3 xmom[i, j] = r3 * u3 ymom[i, j] = r3 * v3 ener[i, j] = p3 / (gamma - 1.0) + 0.5 * r3 * (u3 * u3 + v3 * v3) elif (myg.x[i] >= cx and myg.y[j] < cy): # quadrant 4 dens[i, j] = r4 xmom[i, j] = r4 * u4 ymom[i, j] = r4 * v4 ener[i, j] = p4 / (gamma - 1.0) + 0.5 * r4 * (u4 * u4 + v4 * v4) j += 1 i += 1
def initData(myPatch): """ initialize the sod problem """ msg.bold("initializing the sod problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in sod.py" print myPatch.__class__ sys.exit() # get the sod parameters dens_left = runparams.getParam("sod.dens_left") dens_right = runparams.getParam("sod.dens_right") u_left = runparams.getParam("sod.u_left") u_right = runparams.getParam("sod.u_right") p_left = runparams.getParam("sod.p_left") p_right = runparams.getParam("sod.p_right") # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") # initialize the components, remember, that ener here is rho*eint # + 0.5*rho*v**2, where eint is the specific internal energy # (erg/g) xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") gamma = runparams.getParam("eos.gamma") direction = runparams.getParam("sod.direction") xctr = 0.5 * (xmin + xmax) yctr = 0.5 * (ymin + ymax) myg = myPatch.grid # there is probably an easier way to do this, but for now, we # will just do an explicit loop. Also, we really want to set # the pressue and get the internal energy from that, and then # compute the total energy (which is what we store). For now # we will just fake this. if direction == "x": i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: if myg.x[i] <= xctr: dens[i, j] = dens_left xmom[i, j] = dens_left * u_left ymom[i, j] = 0.0 ener[ i, j] = p_left / (gamma - 1.0) + 0.5 * xmom[i, j] * u_left else: dens[i, j] = dens_right xmom[i, j] = dens_right * u_right ymom[i, j] = 0.0 ener[i, j] = p_right / (gamma - 1.0) + 0.5 * xmom[i, j] * u_right j += 1 i += 1 else: i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: if myg.y[j] <= yctr: dens[i, j] = dens_left xmom[i, j] = 0.0 ymom[i, j] = dens_left * u_left ener[ i, j] = p_left / (gamma - 1.0) + 0.5 * ymom[i, j] * u_left else: dens[i, j] = dens_right xmom[i, j] = 0.0 ymom[i, j] = dens_right * u_right ener[i, j] = p_right / (gamma - 1.0) + 0.5 * ymom[i, j] * u_right j += 1 i += 1
def initData(myPatch): """ initialize the bubble problem """ msg.bold("initializing the bubble problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in bubble.py" print myPatch.__class__ sys.exit() # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") gamma = runparams.getParam("eos.gamma") grav = runparams.getParam("compressible.grav") scale_height = runparams.getParam("bubble.scale_height") dens_base = runparams.getParam("bubble.dens_base") dens_cutoff = runparams.getParam("bubble.dens_cutoff") x_pert = runparams.getParam("bubble.x_pert") y_pert = runparams.getParam("bubble.y_pert") r_pert = runparams.getParam("bubble.r_pert") pert_amplitude_factor = runparams.getParam("bubble.pert_amplitude_factor") # initialize the components, remember, that ener here is # rho*eint + 0.5*rho*v**2, where eint is the specific # internal energy (erg/g) xmom[:,:] = 0.0 ymom[:,:] = 0.0 dens[:,:] = dens_cutoff # set the density to be stratified in the y-direction myg = myPatch.grid j = myg.jlo while j <= myg.jhi: dens[:,j] = max(dens_base*numpy.exp(-myg.y[j]/scale_height), dens_cutoff) j += 1 cs2 = scale_height*abs(grav) # set the energy (P = cs2*dens) ener[:,:] = cs2*dens[:,:]/(gamma - 1.0) + \ 0.5*(xmom[:,:]**2 + ymom[:,:]**2)/dens[:,:] i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: r = numpy.sqrt((myg.x[i] - x_pert)**2 + (myg.y[j] - y_pert)**2) if (r <= r_pert): # boost the specific internal energy, keeping the pressure # constant, by dropping the density eint = (ener[i,j] - 0.5*(xmom[i,j]**2 - ymom[i,j]**2)/dens[i,j])/dens[i,j] pres = dens[i,j]*eint*(gamma - 1.0) eint = eint*pert_amplitude_factor dens[i,j] = pres/(eint*(gamma - 1.0)) ener[i,j] = dens[i,j]*eint + \ 0.5*(xmom[i,j]**2 + ymom[i,j]**2)/dens[i,j] j += 1 i += 1
def initialize(): """ initialize the grid and variables for compressible flow """ import vars # setup the grid nx = runparams.getParam("mesh.nx") ny = runparams.getParam("mesh.ny") xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") myGrid = patch.grid2d(nx, ny, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, ng=4) # create the variables myData = patch.ccData2d(myGrid) # first figure out the boundary conditions. Note: the action # can depend on the variable (for reflecting BCs) xlb_type = runparams.getParam("mesh.xlboundary") xrb_type = runparams.getParam("mesh.xrboundary") ylb_type = runparams.getParam("mesh.ylboundary") yrb_type = runparams.getParam("mesh.yrboundary") bcObj = patch.bcObject(xlb=xlb_type, xrb=xrb_type, ylb=ylb_type, yrb=yrb_type) # density and energy myData.registerVar("density", bcObj) myData.registerVar("energy", bcObj) # for velocity, if we are reflecting, we need odd reflection # in the normal direction. # x-momentum -- if we are reflecting in x, then we need to # reflect odd bcObj_xodd = patch.bcObject(xlb=xlb_type, xrb=xrb_type, ylb=ylb_type, yrb=yrb_type, oddReflectDir="x") myData.registerVar("x-momentum", bcObj_xodd) # y-momentum -- if we are reflecting in y, then we need to # reflect odd bcObj_yodd = patch.bcObject(xlb=xlb_type, xrb=xrb_type, ylb=ylb_type, yrb=yrb_type, oddReflectDir="y") myData.registerVar("y-momentum", bcObj_yodd) # store the EOS gamma as an auxillary quantity so we can have a # self-contained object stored in output files to make plots gamma = runparams.getParam("eos.gamma") myData.setAux("gamma", gamma) myData.create() vars.idens = myData.vars.index("density") vars.ixmom = myData.vars.index("x-momentum") vars.iymom = myData.vars.index("y-momentum") vars.iener = myData.vars.index("energy") print myData return myGrid, myData
# initialize the data exec 'from ' + solverName + '.problems import *' exec problemName + '.initData(myData)' #----------------------------------------------------------------------------- # pre-evolve #----------------------------------------------------------------------------- solver.preevolve(myData) #----------------------------------------------------------------------------- # evolve #----------------------------------------------------------------------------- tmax = runparams.getParam("driver.tmax") max_steps = runparams.getParam("driver.max_steps") init_tstep_factor = runparams.getParam("driver.init_tstep_factor") max_dt_change = runparams.getParam("driver.max_dt_change") fix_dt = runparams.getParam("driver.fix_dt") pylab.ion() n = 0 myData.t = 0.0 # output the 0th data basename = runparams.getParam("io.basename") myData.write(basename + "%4.4d" % (n))
def initData(myPatch): """ initialize the sedov problem """ msg.bold("initializing the sedov problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in sedov.py" print myPatch.__class__ sys.exit() # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") # initialize the components, remember, that ener here is rho*eint # + 0.5*rho*v**2, where eint is the specific internal energy # (erg/g) dens[:,:] = 1.0 xmom[:,:] = 0.0 ymom[:,:] = 0.0 E_sedov = 1.0 r_init = runparams.getParam("sedov.r_init") gamma = runparams.getParam("eos.gamma") pi = 3.14159 xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") xctr = 0.5*(xmin + xmax) yctr = 0.5*(ymin + ymax) # initialize the pressure by putting the explosion energy into a # volume of constant pressure. Then compute the energy in a zone # from this. nsub = 4 i = myPatch.grid.ilo while i <= myPatch.grid.ihi: j = myPatch.grid.jlo while j <= myPatch.grid.jhi: dist = numpy.sqrt((myPatch.grid.x[i] - xctr)**2 + (myPatch.grid.y[j] - yctr)**2) if (dist < 2.0*r_init): pzone = 0.0 ii = 0 while ii < nsub: jj = 0 while jj < nsub: xsub = myPatch.grid.xl[i] + (myPatch.grid.dx/nsub)*(ii + 0.5) ysub = myPatch.grid.yl[j] + (myPatch.grid.dy/nsub)*(jj + 0.5) dist = numpy.sqrt((xsub - xctr)**2 + \ (ysub - yctr)**2) if dist <= r_init: p = (gamma - 1.0)*E_sedov/(pi*r_init*r_init) else: p = 1.e-5 pzone += p jj += 1 ii += 1 p = pzone/(nsub*nsub) else: p = 1.e-5 ener[i,j] = p/(gamma - 1.0) j += 1 i += 1
def initData(myPatch): """ initialize the sedov problem """ msg.bold("initializing the sedov problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in sedov.py" print myPatch.__class__ sys.exit() # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") # initialize the components, remember, that ener here is rho*eint # + 0.5*rho*v**2, where eint is the specific internal energy # (erg/g) dens[:, :] = 1.0 xmom[:, :] = 0.0 ymom[:, :] = 0.0 E_sedov = 1.0 r_init = runparams.getParam("sedov.r_init") gamma = runparams.getParam("eos.gamma") pi = 3.14159 xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") xctr = 0.5 * (xmin + xmax) yctr = 0.5 * (ymin + ymax) # initialize the pressure by putting the explosion energy into a # volume of constant pressure. Then compute the energy in a zone # from this. nsub = 4 i = myPatch.grid.ilo while i <= myPatch.grid.ihi: j = myPatch.grid.jlo while j <= myPatch.grid.jhi: dist = numpy.sqrt((myPatch.grid.x[i] - xctr)**2 + (myPatch.grid.y[j] - yctr)**2) if (dist < 2.0 * r_init): pzone = 0.0 ii = 0 while ii < nsub: jj = 0 while jj < nsub: xsub = myPatch.grid.xl[i] + (myPatch.grid.dx / nsub) * (ii + 0.5) ysub = myPatch.grid.yl[j] + (myPatch.grid.dy / nsub) * (jj + 0.5) dist = numpy.sqrt((xsub - xctr)**2 + \ (ysub - yctr)**2) if dist <= r_init: p = (gamma - 1.0) * E_sedov / (pi * r_init * r_init) else: p = 1.e-5 pzone += p jj += 1 ii += 1 p = pzone / (nsub * nsub) else: p = 1.e-5 ener[i, j] = p / (gamma - 1.0) j += 1 i += 1
def initData(myPatch): """ initialize the quadrant problem """ msg.bold("initializing the quadrant problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in quad.py" print myPatch.__class__ sys.exit() # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") # initialize the components, remember, that ener here is # rho*eint + 0.5*rho*v**2, where eint is the specific # internal energy (erg/g) r1 = runparams.getParam("quadrant.rho1") u1 = runparams.getParam("quadrant.u1") v1 = runparams.getParam("quadrant.v1") p1 = runparams.getParam("quadrant.p1") r2 = runparams.getParam("quadrant.rho2") u2 = runparams.getParam("quadrant.u2") v2 = runparams.getParam("quadrant.v2") p2 = runparams.getParam("quadrant.p2") r3 = runparams.getParam("quadrant.rho3") u3 = runparams.getParam("quadrant.u3") v3 = runparams.getParam("quadrant.v3") p3 = runparams.getParam("quadrant.p3") r4 = runparams.getParam("quadrant.rho4") u4 = runparams.getParam("quadrant.u4") v4 = runparams.getParam("quadrant.v4") p4 = runparams.getParam("quadrant.p4") cx = runparams.getParam("quadrant.cx") cy = runparams.getParam("quadrant.cy") gamma = runparams.getParam("eos.gamma") xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") # there is probably an easier way to do this, but for now, we # will just do an explicit loop. Also, we really want to set # the pressue and get the internal energy from that, and then # compute the total energy (which is what we store). For now # we will just fake this myg = myPatch.grid i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: if (myg.x[i] >= cx and myg.y[j] >= cy): # quadrant 1 dens[i,j] = r1 xmom[i,j] = r1*u1 ymom[i,j] = r1*v1 ener[i,j] = p1/(gamma - 1.0) + 0.5*r1*(u1*u1 + v1*v1) elif (myg.x[i] < cx and myg.y[j] >= cy): # quadrant 2 dens[i,j] = r2 xmom[i,j] = r2*u2 ymom[i,j] = r2*v2 ener[i,j] = p2/(gamma - 1.0) + 0.5*r2*(u2*u2 + v2*v2) elif (myg.x[i] < cx and myg.y[j] < cy): # quadrant 3 dens[i,j] = r3 xmom[i,j] = r3*u3 ymom[i,j] = r3*v3 ener[i,j] = p3/(gamma - 1.0) + 0.5*r3*(u3*u3 + v3*v3) elif (myg.x[i] >= cx and myg.y[j] < cy): # quadrant 4 dens[i,j] = r4 xmom[i,j] = r4*u4 ymom[i,j] = r4*v4 ener[i,j] = p4/(gamma - 1.0) + 0.5*r4*(u4*u4 + v4*v4) j += 1 i += 1
def initData(myPatch): """ initialize the bubble problem """ msg.bold("initializing the bubble problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in bubble.py" print myPatch.__class__ sys.exit() # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") gamma = runparams.getParam("eos.gamma") grav = runparams.getParam("compressible.grav") scale_height = runparams.getParam("bubble.scale_height") dens_base = runparams.getParam("bubble.dens_base") dens_cutoff = runparams.getParam("bubble.dens_cutoff") x_pert = runparams.getParam("bubble.x_pert") y_pert = runparams.getParam("bubble.y_pert") r_pert = runparams.getParam("bubble.r_pert") pert_amplitude_factor = runparams.getParam("bubble.pert_amplitude_factor") # initialize the components, remember, that ener here is # rho*eint + 0.5*rho*v**2, where eint is the specific # internal energy (erg/g) xmom[:, :] = 0.0 ymom[:, :] = 0.0 dens[:, :] = dens_cutoff # set the density to be stratified in the y-direction myg = myPatch.grid j = myg.jlo while j <= myg.jhi: dens[:, j] = max(dens_base * numpy.exp(-myg.y[j] / scale_height), dens_cutoff) j += 1 cs2 = scale_height * abs(grav) # set the energy (P = cs2*dens) ener[:,:] = cs2*dens[:,:]/(gamma - 1.0) + \ 0.5*(xmom[:,:]**2 + ymom[:,:]**2)/dens[:,:] i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: r = numpy.sqrt((myg.x[i] - x_pert)**2 + (myg.y[j] - y_pert)**2) if (r <= r_pert): # boost the specific internal energy, keeping the pressure # constant, by dropping the density eint = (ener[i, j] - 0.5 * (xmom[i, j]**2 - ymom[i, j]**2) / dens[i, j]) / dens[i, j] pres = dens[i, j] * eint * (gamma - 1.0) eint = eint * pert_amplitude_factor dens[i, j] = pres / (eint * (gamma - 1.0)) ener[i,j] = dens[i,j]*eint + \ 0.5*(xmom[i,j]**2 + ymom[i,j]**2)/dens[i,j] j += 1 i += 1
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
def initData(myPatch): """ initialize the Rayleigh-Taylor instability problem """ msg.bold("initializing the Rayleigh-Taylor instability problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print "ERROR: patch invalid in raytay.py" print myPatch.__class__ sys.exit() # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") # get the other input parameters for the problem gamma = runparams.getParam("eos.gamma") grav = runparams.getParam("compressible.grav") dens_up = runparams.getParam("raytay.dens_up") dens_down = runparams.getParam("raytay.dens_down") A = runparams.getParam("raytay.pert_amplitude_factor") p0 = runparams.getParam("raytay.pressure_bottom") sigma = runparams.getParam("raytay.sigma") # get the grid parameters xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") yctr = 0.5 * (ymin + ymax) # initialize the components, remember, that ener here is # rho*eint + 0.5*rho*v**2, where eint is the specific # internal energy (erg/g) xmom[:, :] = 0.0 ymom[:, :] = 0.0 dens[:, :] = 0.0 Lx = xmax - xmin # set the density and energy to be stratified in the y-direction myg = myPatch.grid j = myg.jlo while j <= myg.jhi: if myg.y[j] < yctr: dens[:, j] = dens_down pres = dens_down * grav * myg.y[j] + p0 ener[:, j] = pres / ( gamma - 1.0) #+ 0.5*(xmom[:,j]**2 + ymom[:,j]**2)/dens_down else: dens[:, j] = dens_up pres = p0 + dens_down * grav * yctr + dens_up * grav * (myg.y[j] - yctr) ener[:, j] = pres / ( gamma - 1.0) #+ 0.5*(xmom[:,j]**2 + ymom[:,j]**2)/dens_up j += 1 i = myg.ilo while i <= myg.ihi: j = myg.jlo while j <= myg.jhi: v_pert = A * numpy.sin( 2.0 * numpy.pi * myg.x[i] / Lx) * numpy.exp(-( (myg.y[j] - yctr) / sigma)**2) # momentum ymom[i, j] = dens[i, j] * v_pert # internal energy ener[i, j] += 0.5 * (xmom[i, j]**2 - ymom[i, j]**2) / dens[i, j] j += 1 i += 1
def initData(myPatch): """ initialize the Kelvin-Helmholtz problem """ msg.bold("initializing the sedov problem...") # make sure that we are passed a valid patch object if not isinstance(myPatch, patch.ccData2d): print myPatch.__class__ msg.fail("ERROR: patch invalid in sedov.py") # get the density, momenta, and energy as separate variables dens = myPatch.getVarPtr("density") xmom = myPatch.getVarPtr("x-momentum") ymom = myPatch.getVarPtr("y-momentum") ener = myPatch.getVarPtr("energy") # initialize the components, remember, that ener here is rho*eint # + 0.5*rho*v**2, where eint is the specific internal energy # (erg/g) dens[:,:] = 1.0 xmom[:,:] = 0.0 ymom[:,:] = 0.0 E_sedov = 1.0 rho_1 = runparams.getParam("kh.rho_1") v_1 = runparams.getParam("kh.v_1") rho_2 = runparams.getParam("kh.rho_2") v_2 = runparams.getParam("kh.v_2") gamma = runparams.getParam("eos.gamma") xmin = runparams.getParam("mesh.xmin") xmax = runparams.getParam("mesh.xmax") ymin = runparams.getParam("mesh.ymin") ymax = runparams.getParam("mesh.ymax") xctr = 0.5*(xmin + xmax) yctr = 0.5*(ymin + ymax) L_x = xmax - xmin # initialize the pressure by putting the explosion energy into a # volume of constant pressure. Then compute the energy in a zone # from this. nsub = 4 i = myPatch.grid.ilo while i <= myPatch.grid.ihi: j = myPatch.grid.jlo while j <= myPatch.grid.jhi: if myPatch.grid.y[j] < yctr + 0.01*math.sin(10.0*math.pi*myPatch.grid.x[i]/L_x): # lower half dens[i,j] = rho_1 xmom[i,j] = rho_1*v_1 ymom[i,j] = 0.0 else: # upper half dens[i,j] = rho_2 xmom[i,j] = rho_2*v_2 ymom[i,j] = 0.0 p = 1.0 ener[i,j] = p/(gamma - 1.0) + 0.5*(xmom[i,j]**2 + ymom[i,j]**2)/dens[i,j] j += 1 i += 1