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
예제 #2
0
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()
예제 #3
0
def rhoe(pres):
    """ given the pressure, return (rho * e) """

    gamma = runparams.getParam("eos.gamma")

    rhoe = pres / (gamma - 1.0)

    return rhoe
예제 #4
0
def rhoe(pres):
    """ given the pressure, return (rho * e) """

    gamma = runparams.getParam("eos.gamma")

    rhoe = pres/(gamma - 1.0)

    return rhoe
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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
예제 #10
0
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
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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
예제 #14
0
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
예제 #16
0
# 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))
예제 #17
0
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 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
예제 #19
0
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
예제 #20
0
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
예제 #21
0
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
예제 #23
0
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
예제 #24
0
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