示例#1
0
def bc_setup(rp):

    # first figure out the BCs
    xlb_type = rp.get_param("mesh.xlboundary")
    xrb_type = rp.get_param("mesh.xrboundary")
    ylb_type = rp.get_param("mesh.ylboundary")
    yrb_type = rp.get_param("mesh.yrboundary")

    bc = patch.BCObject(xlb=xlb_type, xrb=xrb_type, ylb=ylb_type, yrb=yrb_type)

    # if we are reflecting, we need odd reflection in the normal
    # directions for the velocity
    bc_xodd = patch.BCObject(xlb=xlb_type,
                             xrb=xrb_type,
                             ylb=ylb_type,
                             yrb=yrb_type,
                             odd_reflect_dir="x")

    bc_yodd = patch.BCObject(xlb=xlb_type,
                             xrb=xrb_type,
                             ylb=ylb_type,
                             yrb=yrb_type,
                             odd_reflect_dir="y")

    return bc, bc_xodd, bc_yodd
示例#2
0
def initialize(rp):
    """ 
    initialize the grid and variables for diffusion
    """

    # setup the grid
    nx = rp.get_param("mesh.nx")
    ny = rp.get_param("mesh.ny")

    xmin = rp.get_param("mesh.xmin")
    xmax = rp.get_param("mesh.xmax")
    ymin = rp.get_param("mesh.ymin")
    ymax = rp.get_param("mesh.ymax")

    my_grid = patch.Grid2d(nx,
                           ny,
                           xmin=xmin,
                           xmax=xmax,
                           ymin=ymin,
                           ymax=ymax,
                           ng=1)

    # create the variables

    # first figure out the boundary conditions -- we allow periodic,
    # Dirichlet, and Neumann.

    xlb_type = rp.get_param("mesh.xlboundary")
    xrb_type = rp.get_param("mesh.xrboundary")
    ylb_type = rp.get_param("mesh.ylboundary")
    yrb_type = rp.get_param("mesh.yrboundary")

    bcparam = []
    for bc in [xlb_type, xrb_type, ylb_type, yrb_type]:
        if (bc == "periodic"): bcparam.append("periodic")
        elif (bc == "neumann"): bcparam.append("neumann")
        elif (bc == "dirichlet"): bcparam.append("dirichlet")
        else:
            msg.fail("invalid BC")

    bc = patch.BCObject(xlb=bcparam[0],
                        xrb=bcparam[1],
                        ylb=bcparam[2],
                        yrb=bcparam[3])

    my_data = patch.CellCenterData2d(my_grid, runtime_parameters=rp)

    my_data.register_var("phi", bc)

    my_data.create()

    return my_grid, my_data
示例#3
0
def initialize(rp):
    """ 
    initialize the grid and variables for advection 
    """

    # setup the grid
    nx = rp.get_param("mesh.nx")
    ny = rp.get_param("mesh.ny")

    xmin = rp.get_param("mesh.xmin")
    xmax = rp.get_param("mesh.xmax")
    ymin = rp.get_param("mesh.ymin")
    ymax = rp.get_param("mesh.ymax")

    my_grid = patch.Grid2d(nx,
                           ny,
                           xmin=xmin,
                           xmax=xmax,
                           ymin=ymin,
                           ymax=ymax,
                           ng=4)

    # create the variables

    # first figure out the boundary conditions -- we need to translate
    # between the descriptive type of the boundary specified by the
    # user and the action that will be performed by the fill_BC routine.
    # Usually the actions can vary depending on the variable, but we
    # only have one variable.
    xlb_type = rp.get_param("mesh.xlboundary")
    xrb_type = rp.get_param("mesh.xrboundary")
    ylb_type = rp.get_param("mesh.ylboundary")
    yrb_type = rp.get_param("mesh.yrboundary")

    bc = patch.BCObject(xlb=xlb_type, xrb=xrb_type, ylb=ylb_type, yrb=yrb_type)

    my_data = patch.CellCenterData2d(my_grid, runtime_parameters=rp)

    my_data.register_var("density", bc)

    my_data.create()

    return my_grid, my_data
示例#4
0
    def initialize(self):
        """
        Initialize the grid and variables for diffusion and set the initial
        conditions for the chosen problem.
        """

        # setup the grid
        my_grid = grid_setup(self.rp, ng=1)

        # create the variables

        # first figure out the boundary conditions -- we allow periodic,
        # Dirichlet, and Neumann.

        xlb_type = self.rp.get_param("mesh.xlboundary")
        xrb_type = self.rp.get_param("mesh.xrboundary")
        ylb_type = self.rp.get_param("mesh.ylboundary")
        yrb_type = self.rp.get_param("mesh.yrboundary")

        bcparam = []
        for bc in [xlb_type, xrb_type, ylb_type, yrb_type]:
            if bc == "periodic": bcparam.append("periodic")
            elif bc == "neumann": bcparam.append("neumann")
            elif bc == "dirichlet": bcparam.append("dirichlet")
            else:
                msg.fail("invalid BC")

        bc = patch.BCObject(xlb=bcparam[0],
                            xrb=bcparam[1],
                            ylb=bcparam[2],
                            yrb=bcparam[3])

        my_data = patch.CellCenterData2d(my_grid)
        my_data.register_var("phi", bc)
        my_data.create()

        self.cc_data = my_data

        # now set the initial conditions for the problem
        exec(self.problem_name + '.init_data(self.cc_data, self.rp)')
示例#5
0
def test_vc_poisson_dirichlet(N,
                              store_bench=False,
                              comp_bench=False,
                              make_plot=False,
                              verbose=1):
    """
    test the variable-coefficient MG solver.  The return value
    here is the error compared to the exact solution, UNLESS
    comp_bench=True, in which case the return value is the
    error compared to the stored benchmark
    """

    # test the multigrid solver
    nx = N
    ny = nx

    # create the coefficient variable
    g = patch.Grid2d(nx, ny, ng=1)
    d = patch.CellCenterData2d(g)
    bc_c = patch.BCObject(xlb="neumann",
                          xrb="neumann",
                          ylb="neumann",
                          yrb="neumann")
    d.register_var("c", bc_c)
    d.create()

    c = d.get_var("c")
    c.d[:, :] = alpha(g.x2d, g.y2d)

    # create the multigrid object
    a = MG.VarCoeffCCMG2d(nx,
                          ny,
                          xl_BC_type="dirichlet",
                          yl_BC_type="dirichlet",
                          xr_BC_type="dirichlet",
                          yr_BC_type="dirichlet",
                          coeffs=c,
                          coeffs_bc=bc_c,
                          verbose=verbose,
                          vis=0,
                          true_function=true)

    # initialize the solution to 0
    a.init_zeros()

    # initialize the RHS using the function f
    rhs = f(a.x2d, a.y2d)
    a.init_RHS(rhs)

    # solve to a relative tolerance of 1.e-11
    a.solve(rtol=1.e-11)

    # alternately, we can just use smoothing by uncommenting the following
    #a.smooth(a.nlevels-1,50000)

    # get the solution
    v = a.get_solution()

    # compute the error from the analytic solution
    b = true(a.x2d, a.y2d)
    e = v - b

    enorm = e.norm()
    print(" L2 error from true solution = %g\n rel. err from previous cycle = %g\n num. cycles = %d" % \
          (enorm, a.relative_error, a.num_cycles))

    # plot the solution
    if make_plot:
        plt.clf()

        plt.figure(figsize=(10.0, 4.0), dpi=100, facecolor='w')

        plt.subplot(121)

        plt.imshow(np.transpose(v.v()),
                   interpolation="nearest",
                   origin="lower",
                   extent=[a.xmin, a.xmax, a.ymin, a.ymax])

        plt.xlabel("x")
        plt.ylabel("y")
        plt.title("nx = {}".format(nx))

        plt.colorbar()

        plt.subplot(122)

        plt.imshow(np.transpose(e.v()),
                   interpolation="nearest",
                   origin="lower",
                   extent=[a.xmin, a.xmax, a.ymin, a.ymax])

        plt.xlabel("x")
        plt.ylabel("y")
        plt.title("error")

        plt.colorbar()

        plt.tight_layout()

        plt.savefig("mg_vc_dirichlet_test.png")

    # store the output for later comparison
    bench = "mg_vc_poisson_dirichlet"
    bench_dir = os.environ["PYRO_HOME"] + "/multigrid/tests/"

    my_data = a.get_solution_object()

    if store_bench:
        my_data.write("{}/{}".format(bench_dir, bench))

    # do we do a comparison?
    if comp_bench:
        compare_file = "{}/{}".format(bench_dir, bench)
        msg.warning("comparing to: %s " % (compare_file))
        bench_grid, bench_data = patch.read(compare_file)

        result = compare.compare(my_data.grid, my_data, bench_grid, bench_data)

        if result == 0:
            msg.success("results match benchmark\n")
        else:
            msg.warning("ERROR: " + compare.errors[result] + "\n")

        return result

    # normal return -- error wrt true solution
    return enorm
示例#6
0
# test the prolongation and restriction operations from the patch stuff

import mesh.patch as patch
import numpy

# create our base grid and initialize it with sequential data
myg = patch.Grid2d(4,8,ng=1)
myd = patch.CellCenterData2d(myg)
bc = patch.BCObject()
myd.register_var("a", bc)
myd.create()

a = myd.get_var("a")

a[myg.ilo:myg.ihi+1,myg.jlo:myg.jhi+1].flat = numpy.arange(myg.nx*myg.ny)

print "restriction test"
print "original (fine) array"
myd.pretty_print("a")


# create a coarse grid and fill the variable in it with restricted data
print " "
print "restricted array"

cg = patch.Grid2d(2,4,ng=1)
cd = patch.CellCenterData2d(cg)
cd.register_var("a", bc)
cd.create()

a_coarse = cd.get_var("a")
示例#7
0
    def initialize(self):
        """
        Initialize the grid and variables for compressible flow and set
        the initial conditions for the chosen problem.
        """

        # setup the grid
        nx = self.rp.get_param("mesh.nx")
        ny = self.rp.get_param("mesh.ny")

        xmin = self.rp.get_param("mesh.xmin")
        xmax = self.rp.get_param("mesh.xmax")
        ymin = self.rp.get_param("mesh.ymin")
        ymax = self.rp.get_param("mesh.ymax")

        verbose = self.rp.get_param("driver.verbose")

        my_grid = patch.Grid2d(nx,
                               ny,
                               xmin=xmin,
                               xmax=xmax,
                               ymin=ymin,
                               ymax=ymax,
                               ng=4)

        # create the variables
        my_data = patch.CellCenterData2d(my_grid)

        # define solver specific boundary condition routines
        patch.define_bc("hse", BC.user)

        # first figure out the boundary conditions.  Note: the action
        # can depend on the variable (for reflecting BCs)
        xlb_type = self.rp.get_param("mesh.xlboundary")
        xrb_type = self.rp.get_param("mesh.xrboundary")
        ylb_type = self.rp.get_param("mesh.ylboundary")
        yrb_type = self.rp.get_param("mesh.yrboundary")

        bc = patch.BCObject(xlb=xlb_type,
                            xrb=xrb_type,
                            ylb=ylb_type,
                            yrb=yrb_type)

        # density and energy
        my_data.register_var("density", bc)
        my_data.register_var("energy", bc)
        my_data.register_var("erad", bc)

        # 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
        bc_xodd = patch.BCObject(xlb=xlb_type,
                                 xrb=xrb_type,
                                 ylb=ylb_type,
                                 yrb=yrb_type,
                                 odd_reflect_dir="x")

        my_data.register_var("x-momentum", bc_xodd)

        # y-momentum -- if we are reflecting in y, then we need to
        # reflect odd
        bc_yodd = patch.BCObject(xlb=xlb_type,
                                 xrb=xrb_type,
                                 ylb=ylb_type,
                                 yrb=yrb_type,
                                 odd_reflect_dir="y")

        my_data.register_var("y-momentum", bc_yodd)

        # store grav because we'll need that in some BCs
        my_data.set_aux("grav", self.rp.get_param("compressible.grav"))

        my_data.create()

        self.cc_data = my_data

        self.vars = Variables(idens=my_data.vars.index("density"),
                              ixmom=my_data.vars.index("x-momentum"),
                              iymom=my_data.vars.index("y-momentum"),
                              iener=my_data.vars.index("energy"),
                              ierad=my_data.vars.index("erad"))

        # initial conditions for the problem
        exec(self.problem_name + '.init_data(self.cc_data, self.rp)')

        if verbose > 0: print(my_data)
示例#8
0
def test_bcs():

    myg = patch.Grid2d(4, 4, ng=2, xmax=1.0, ymax=1.0)
    myd = patch.CellCenterData2d(myg, dtype=np.int)

    bco = patch.BCObject(xlb="outflow",
                         xrb="outflow",
                         ylb="outflow",
                         yrb="outflow")
    myd.register_var("outflow", bco)

    bcp = patch.BCObject(xlb="periodic",
                         xrb="periodic",
                         ylb="periodic",
                         yrb="periodic")
    myd.register_var("periodic", bcp)

    bcre = patch.BCObject(xlb="reflect-even",
                          xrb="reflect-even",
                          ylb="reflect-even",
                          yrb="reflect-even")
    myd.register_var("reflect-even", bcre)

    bcro = patch.BCObject(xlb="reflect-odd",
                          xrb="reflect-odd",
                          ylb="reflect-odd",
                          yrb="reflect-odd")
    myd.register_var("reflect-odd", bcro)

    myd.create()

    a = myd.get_var("outflow")
    a.v()[:, :] = np.fromfunction(lambda i, j: i + 10 * j + 1, (4, 4),
                                  dtype=int)

    b = myd.get_var("periodic")
    c = myd.get_var("reflect-even")
    d = myd.get_var("reflect-odd")

    b.d[:, :] = a.d[:, :]
    c.d[:, :] = a.d[:, :]
    d.d[:, :] = a.d[:, :]

    myd.fill_BC("outflow")
    # left ghost
    assert_array_equal(a.d[myg.ilo - 1, myg.jlo:myg.jhi + 1],
                       np.array([1, 11, 21, 31]))
    # right ghost
    assert_array_equal(a.d[myg.ihi + 1, myg.jlo:myg.jhi + 1],
                       np.array([4, 14, 24, 34]))
    # bottom ghost
    assert_array_equal(a.d[myg.ilo:myg.ihi + 1, myg.jlo - 1],
                       np.array([1, 2, 3, 4]))
    # top ghost
    assert_array_equal(a.d[myg.ilo:myg.ihi + 1, myg.jhi + 1],
                       np.array([31, 32, 33, 34]))

    myd.fill_BC("periodic")
    # x-boundaries
    assert_array_equal(b.d[myg.ilo - 1, myg.jlo:myg.jhi + 1],
                       b.d[myg.ihi, myg.jlo:myg.jhi + 1])
    assert_array_equal(b.d[myg.ilo, myg.jlo:myg.jhi + 1],
                       b.d[myg.ihi + 1, myg.jlo:myg.jhi + 1])
    # y-boundaries
    assert_array_equal(b.d[myg.ilo:myg.ihi + 1, myg.jlo - 1],
                       b.d[myg.ilo:myg.ihi + 1, myg.jhi])
    assert_array_equal(b.d[myg.ilo:myg.ihi + 1, myg.jlo],
                       b.d[myg.ilo:myg.ihi + 1, myg.jhi + 1])

    myd.fill_BC("reflect-even")
    # left -- we'll check 2 ghost cells here -- now we use flipud here
    # because our 'x' is the row index
    # left
    assert_array_equal(
        c.d[myg.ilo:myg.ilo + 2, myg.jlo:myg.ihi + 1],
        np.flipud(c.d[myg.ilo - 2:myg.ilo, myg.jlo:myg.jhi + 1]))
    # right
    assert_array_equal(
        c.d[myg.ihi - 1:myg.ihi + 1, myg.jlo:myg.jhi + 1],
        np.flipud(c.d[myg.ihi + 1:myg.ihi + 3, myg.jlo:myg.jhi + 1]))

    # bottom
    assert_array_equal(
        c.d[myg.ilo:myg.ihi + 1, myg.jlo:myg.jlo + 2],
        np.fliplr(c.d[myg.ilo:myg.ihi + 1, myg.jlo - 2:myg.jlo]))
    # top
    assert_array_equal(
        c.d[myg.ilo:myg.ihi + 1, myg.jhi - 1:myg.jhi + 1],
        np.fliplr(c.d[myg.ilo:myg.ihi + 1, myg.jhi + 1:myg.jhi + 3]))

    myd.fill_BC("reflect-odd")
    # left -- we'll check 2 ghost cells here -- now we use flipud here
    # because our 'x' is the row index
    # left
    assert_array_equal(
        d.d[myg.ilo:myg.ilo + 2, myg.jlo:myg.ihi + 1],
        -np.flipud(d.d[myg.ilo - 2:myg.ilo, myg.jlo:myg.jhi + 1]))
    # right
    assert_array_equal(
        d.d[myg.ihi - 1:myg.ihi + 1, myg.jlo:myg.jhi + 1],
        -np.flipud(d.d[myg.ihi + 1:myg.ihi + 3, myg.jlo:myg.jhi + 1]))

    # bottom
    assert_array_equal(
        d.d[myg.ilo:myg.ihi + 1, myg.jlo:myg.jlo + 2],
        -np.fliplr(d.d[myg.ilo:myg.ihi + 1, myg.jlo - 2:myg.jlo]))
    # top
    assert_array_equal(
        d.d[myg.ilo:myg.ihi + 1, myg.jhi - 1:myg.jhi + 1],
        -np.fliplr(d.d[myg.ilo:myg.ihi + 1, myg.jhi + 1:myg.jhi + 3]))
示例#9
0
    def initialize(self):
        """
        Initialize the grid and variables for low Mach atmospheric flow
        and set the initial conditions for the chosen problem.
        """

        myg = grid_setup(self.rp, ng=4)

        bc_dens, bc_xodd, bc_yodd = bc_setup(self.rp)

        my_data = patch.CellCenterData2d(myg)

        my_data.register_var("density", bc_dens)
        my_data.register_var("x-velocity", bc_xodd)
        my_data.register_var("y-velocity", bc_yodd)

        # we'll keep the internal energy around just as a diagnostic
        my_data.register_var("eint", bc_dens)

        # phi -- used for the projections.  The boundary conditions
        # here depend on velocity.  At a wall or inflow, we already
        # have the velocity we want on the boundary, so we want
        # Neumann (dphi/dn = 0).  For outflow, we want Dirichlet (phi
        # = 0) -- this ensures that we do not introduce any tangental
        # acceleration.
        bcs = []
        for bc in [self.rp.get_param("mesh.xlboundary"),
                   self.rp.get_param("mesh.xrboundary"),
                   self.rp.get_param("mesh.ylboundary"),
                   self.rp.get_param("mesh.yrboundary")]:
            if bc == "periodic":
                bctype = "periodic"
            elif bc in ["reflect", "slipwall"]:
                bctype = "neumann"
            elif bc in ["outflow"]:
                bctype = "dirichlet"
            bcs.append(bctype)

        bc_phi = patch.BCObject(xlb=bcs[0], xrb=bcs[1], ylb=bcs[2], yrb=bcs[3])

        my_data.register_var("phi-MAC", bc_phi)
        my_data.register_var("phi", bc_phi)


        # gradp -- used in the projection and interface states.  We'll do the
        # same BCs as density
        my_data.register_var("gradp_x", bc_dens)
        my_data.register_var("gradp_y", bc_dens)

        my_data.create()

        self.cc_data = my_data


        # some auxillary data that we'll need to fill GC in, but isn't
        # really part of the main solution
        aux_data = patch.CellCenterData2d(myg)

        aux_data.register_var("coeff", bc_dens)
        aux_data.register_var("source_y", bc_yodd)

        aux_data.create()
        self.aux_data = aux_data


        # we also need storage for the 1-d base state -- we'll store this
        # in the main class directly.
        self.base["rho0"] = Basestate(myg.ny, ng=myg.ng)
        self.base["p0"] = Basestate(myg.ny, ng=myg.ng)

        # now set the initial conditions for the problem
        exec(self.problem_name + '.init_data(self.cc_data, self.base, self.rp)')

        # Construct beta_0
        gamma = self.rp.get_param("eos.gamma")
        self.base["beta0"] = Basestate(myg.ny, ng=myg.ng)
        self.base["beta0"].d[:] = self.base["p0"].d**(1.0/gamma)

        # we'll also need beta_0 on vertical edges -- on the domain edges,
        # just do piecewise constant
        self.base["beta0-edges"] = Basestate(myg.ny, ng=myg.ng)
        self.base["beta0-edges"].jp(1)[:] = \
            0.5*(self.base["beta0"].v() + self.base["beta0"].jp(1))
        self.base["beta0-edges"].d[myg.jlo] = self.base["beta0"].d[myg.jlo]
        self.base["beta0-edges"].d[myg.jhi+1] = self.base["beta0"].d[myg.jhi]
示例#10
0
    def initialize(self):
        """ 
        Initialize the grid and variables for incompressible flow and
        set the initial conditions for the chosen problem.
        """

        # setup the grid
        nx = self.rp.get_param("mesh.nx")
        ny = self.rp.get_param("mesh.ny")

        xmin = self.rp.get_param("mesh.xmin")
        xmax = self.rp.get_param("mesh.xmax")
        ymin = self.rp.get_param("mesh.ymin")
        ymax = self.rp.get_param("mesh.ymax")

        my_grid = patch.Grid2d(nx,
                               ny,
                               xmin=xmin,
                               xmax=xmax,
                               ymin=ymin,
                               ymax=ymax,
                               ng=4)

        # create the variables

        # first figure out the BCs
        xlb_type = self.rp.get_param("mesh.xlboundary")
        xrb_type = self.rp.get_param("mesh.xrboundary")
        ylb_type = self.rp.get_param("mesh.ylboundary")
        yrb_type = self.rp.get_param("mesh.yrboundary")

        bc = patch.BCObject(xlb=xlb_type,
                            xrb=xrb_type,
                            ylb=ylb_type,
                            yrb=yrb_type)

        # if we are reflecting, we need odd reflection in the normal
        # directions for the velocity
        bc_xodd = patch.BCObject(xlb=xlb_type,
                                 xrb=xrb_type,
                                 ylb=ylb_type,
                                 yrb=yrb_type,
                                 odd_reflect_dir="x")

        bc_yodd = patch.BCObject(xlb=xlb_type,
                                 xrb=xrb_type,
                                 ylb=ylb_type,
                                 yrb=yrb_type,
                                 odd_reflect_dir="y")

        my_data = patch.CellCenterData2d(my_grid)

        # velocities
        my_data.register_var("x-velocity", bc_xodd)
        my_data.register_var("y-velocity", bc_yodd)

        # density
        my_data.register_var("density", bc)

        # phi -- used for the projections
        my_data.register_var("phi-MAC", bc)
        my_data.register_var("phi", bc)

        # gradp -- used in the projection and interface states.  The BCs here
        # are tricky.  If we are periodic, then it is periodic.  Otherwise,
        # we just want to do first-order extrapolation (homogeneous Neumann)
        my_data.register_var("gradp_x", bc)
        my_data.register_var("gradp_y", bc)

        my_data.create()

        self.cc_data = my_data

        # now set the initial conditions for the problem
        exec(self.problem_name + '.init_data(self.cc_data, self.rp)')
示例#11
0
def initialize(rp):
    """ 
    initialize the grid and variables for incompressible flow
    """

    # setup the grid
    nx = rp.get_param("mesh.nx")
    ny = rp.get_param("mesh.ny")

    xmin = rp.get_param("mesh.xmin")
    xmax = rp.get_param("mesh.xmax")
    ymin = rp.get_param("mesh.ymin")
    ymax = rp.get_param("mesh.ymax")

    my_grid = patch.Grid2d(nx,
                           ny,
                           xmin=xmin,
                           xmax=xmax,
                           ymin=ymin,
                           ymax=ymax,
                           ng=4)

    # create the variables

    # first figure out the BCs
    xlb_type = rp.get_param("mesh.xlboundary")
    xrb_type = rp.get_param("mesh.xrboundary")
    ylb_type = rp.get_param("mesh.ylboundary")
    yrb_type = rp.get_param("mesh.yrboundary")

    bc = patch.BCObject(xlb=xlb_type, xrb=xrb_type, ylb=ylb_type, yrb=yrb_type)

    # if we are reflecting, we need odd reflection in the normal
    # directions for the velocity
    bc_xodd = patch.BCObject(xlb=xlb_type,
                             xrb=xrb_type,
                             ylb=ylb_type,
                             yrb=yrb_type,
                             odd_reflect_dir="x")

    bc_yodd = patch.BCObject(xlb=xlb_type,
                             xrb=xrb_type,
                             ylb=ylb_type,
                             yrb=yrb_type,
                             odd_reflect_dir="y")

    my_data = patch.CellCenterData2d(my_grid, runtime_parameters=rp)

    # velocities
    my_data.register_var("x-velocity", bc_xodd)
    my_data.register_var("y-velocity", bc_yodd)

    # phi -- used for the projections
    my_data.register_var("phi-MAC", bc)
    my_data.register_var("phi", bc)
    my_data.register_var("gradp_x", bc)
    my_data.register_var("gradp_y", bc)

    my_data.create()

    return my_grid, my_data
示例#12
0
    def __init__(self,
                 nx,
                 ny,
                 ng=1,
                 xmin=0.0,
                 xmax=1.0,
                 ymin=0.0,
                 ymax=1.0,
                 xl_BC_type="dirichlet",
                 xr_BC_type="dirichlet",
                 yl_BC_type="dirichlet",
                 yr_BC_type="dirichlet",
                 xl_BC=None,
                 xr_BC=None,
                 yl_BC=None,
                 yr_BC=None,
                 alpha=0.0,
                 beta=-1.0,
                 nsmooth=10,
                 nsmooth_bottom=50,
                 verbose=0,
                 aux_field=None,
                 aux_bc=None,
                 true_function=None,
                 vis=0,
                 vis_title=""):
        """
        Create the CellCenterMG2d object.  Note that this requires a
        grid to be a power of 2 in size and square.

        Parameters
        ----------
        nx : int
            number of cells in x-direction
        ny : int
            number of cells in y-direction.
        xmin : float, optional
            minimum physical coordinate in x-direction
        xmax : float, optional
            maximum physical coordinate in x-direction
        ymin : float, optional
            minimum physical coordinate in y-direction
        ymax : float, optional
            maximum physical coordinate in y-direction
        xl_BC_type : {'neumann', 'dirichlet', 'periodic'}, optional
            boundary condition to enforce on lower x face
        xr_BC_type : {'neumann', 'dirichlet', 'periodic'}, optional
            boundary condition to enforce on upper x face
        yl_BC_type : {'neumann', 'dirichlet', 'periodic'}, optional
            boundary condition to enforce on lower y face
        yr_BC_type : {'neumann', 'dirichlet', 'periodic'}, optional
            boundary condition to enforce on upper y face
        xl_BC : function, optional
            function (of y) to call to get -x boundary values
            (homogeneous assumed otherwise)
        xr_BC : function, optional
            function (of y) to call to get +x boundary values
            (homogeneous assumed otherwise)
        yl_BC : function, optional
            function (of x) to call to get -y boundary values
            (homogeneous assumed otherwise)
        yr_BC : function, optional
            function (of x) to call to get +y boundary values
            (homogeneous assumed otherwise)
        alpha : float, optional
            coefficient in Helmholtz equation (alpha - beta L) phi = f
        beta : float, optional
            coefficient in Helmholtz equation (alpha - beta L) phi = f
        nsmooth : int, optional
            number of smoothing iterations to be done at each intermediate
            level in the V-cycle (up and down)
        nsmooth_bottom : int, optional
            number of smoothing iterations to be done during the bottom
            solve
        verbose : int, optional
            increase verbosity during the solve (for verbose=1)
        aux_field : list of str, optional
            extra fields to define and carry at each level.
            Useful for subclassing.
        aux_bc : list of BCObject, optional
            the boundary conditions corresponding to the aux fields
        true_function : function, optional
            a function (of x,y) that provides the exact solution to
            the elliptic problem we are solving.  This is used only
            for visualization purposes
        vis : int, optional
            output a detailed visualization of every smoothing step
            all throughout the V-cycle (if vis=1)
        vis_title : string, optional
            a descriptive title to write on the visualization plots

        Returns
        -------
        out: CellCenterMG2d object

        """

        if nx != ny:
            print("ERROR: multigrid currently requires nx = ny")
            return -1

        self.nx = nx
        self.ny = ny

        self.ng = ng

        self.xmin = xmin
        self.xmax = xmax

        self.ymin = ymin
        self.ymax = ymax

        if (xmax - xmin) != (ymax - ymin):
            print("ERROR: multigrid currently requires a square domain")
            return -1

        self.alpha = alpha
        self.beta = beta

        self.nsmooth = nsmooth
        self.nsmooth_bottom = nsmooth_bottom

        self.max_cycles = 100

        self.verbose = verbose

        # for visualization purposes, we can set a function name that
        # provides the true solution to our elliptic problem.
        if not true_function == None:
            self.true_function = true_function

        # a small number used in computing the error, so we don't divide by 0
        self.small = 1.e-16

        # keep track of whether we've initialized the RHS
        self.initialized_RHS = 0

        # assume that self.nx = 2^(nlevels-1) and that nx = ny
        # this defines nlevels such that we end exactly on a 2x2 grid
        self.nlevels = int(math.log(self.nx) / math.log(2.0))

        # a multigrid object will be a list of grids
        self.grids = []

        # create the grids.  Here, self.grids[0] will be the coarsest
        # grid and self.grids[nlevel-1] will be the finest grid
        # we store the solution, v, the rhs, f.

        # create the boundary condition object
        bc = patch.BCObject(xlb=xl_BC_type,
                            xrb=xr_BC_type,
                            ylb=yl_BC_type,
                            yrb=yr_BC_type)

        nx_t = ny_t = 2

        for i in range(self.nlevels):

            # create the grid
            my_grid = patch.Grid2d(nx_t,
                                   ny_t,
                                   ng=self.ng,
                                   xmin=xmin,
                                   xmax=xmax,
                                   ymin=ymin,
                                   ymax=ymax)

            # add a CellCenterData2d object for this level to our list
            self.grids.append(patch.CellCenterData2d(my_grid,
                                                     dtype=np.float64))

            # create the phi BC object -- this only applies for the finest
            # level.  On the coarser levels, phi represents the residual,
            # which has homogeneous BCs
            bc_p = patch.BCObject(xlb=xl_BC_type,
                                  xrb=xr_BC_type,
                                  ylb=yl_BC_type,
                                  yrb=yr_BC_type,
                                  xl_func=xl_BC,
                                  xr_func=xr_BC,
                                  yl_func=yl_BC,
                                  yr_func=yr_BC,
                                  grid=my_grid)

            if i == self.nlevels - 1:
                self.grids[i].register_var("v", bc_p)
            else:
                self.grids[i].register_var("v", bc)

            self.grids[i].register_var("f", bc)
            self.grids[i].register_var("r", bc)

            if not aux_field == None:
                for f, b in zip(aux_field, aux_bc):
                    self.grids[i].register_var(f, b)

            self.grids[i].create()

            if self.verbose: print(self.grids[i])

            nx_t = nx_t * 2
            ny_t = ny_t * 2

        # provide coordinate and indexing information for the solution mesh
        soln_grid = self.grids[self.nlevels - 1].grid

        self.ilo = soln_grid.ilo
        self.ihi = soln_grid.ihi
        self.jlo = soln_grid.jlo
        self.jhi = soln_grid.jhi

        self.x = soln_grid.x
        self.dx = soln_grid.dx
        self.x2d = soln_grid.x2d

        self.y = soln_grid.y
        self.dy = soln_grid.dy  # note, dy = dx is assumed
        self.y2d = soln_grid.y2d

        self.soln_grid = soln_grid

        # store the source norm
        self.source_norm = 0.0

        # after solving, keep track of the number of cycles taken, the
        # relative error from the previous cycle, and the residual error
        # (normalized to the source norm)
        self.num_cycles = 0
        self.residual_error = 1.e33
        self.relative_error = 1.e33

        # keep track of where we are in the V
        self.current_cycle = -1
        self.current_level = -1
        self.up_or_down = ""

        # for visualization -- what frame are we outputting?
        self.vis = vis
        self.vis_title = vis_title
        self.frame = 0
示例#13
0
    # normalize
    return numpy.sqrt(myg.dx * myg.dy * numpy.sum(
        (r[myg.ilo:myg.ihi + 1, myg.jlo:myg.jhi + 1]**2).flat))


nx = 128
ny = 128

nproj = 2

# create a mesh containing the x- and y-velocities, and periodic boundary
# conditions
myg = patch.Grid2d(nx, ny, ng=1)

bc = patch.BCObject(xlb="periodic",
                    xrb="periodic",
                    ylb="periodic",
                    yrb="periodic")

U = patch.CellCenterData2d(myg)

U.register_var('u-old', bc)
U.register_var('v-old', bc)
U.register_var('u+gphi', bc)
U.register_var('v+gphi', bc)
U.register_var('u', bc)
U.register_var('v', bc)

U.register_var('divU', bc)

U.register_var('phi-old', bc)
U.register_var('phi', bc)
示例#14
0
def initialize(rp):
    """ 
    initialize the grid and variables for compressible flow
    """
    import vars

    # setup the grid
    nx = rp.get_param("mesh.nx")
    ny = rp.get_param("mesh.ny")

    xmin = rp.get_param("mesh.xmin")
    xmax = rp.get_param("mesh.xmax")
    ymin = rp.get_param("mesh.ymin")
    ymax = rp.get_param("mesh.ymax")

    my_grid = patch.Grid2d(nx,
                           ny,
                           xmin=xmin,
                           xmax=xmax,
                           ymin=ymin,
                           ymax=ymax,
                           ng=4)

    # create the variables
    my_data = patch.CellCenterData2d(my_grid, runtime_parameters=rp)

    # define solver specific boundary condition routines
    patch.define_bc("hse", BC.user)

    # first figure out the boundary conditions.  Note: the action
    # can depend on the variable (for reflecting BCs)
    xlb_type = rp.get_param("mesh.xlboundary")
    xrb_type = rp.get_param("mesh.xrboundary")
    ylb_type = rp.get_param("mesh.ylboundary")
    yrb_type = rp.get_param("mesh.yrboundary")

    bc = patch.BCObject(xlb=xlb_type, xrb=xrb_type, ylb=ylb_type, yrb=yrb_type)

    # density and energy
    my_data.register_var("density", bc)
    my_data.register_var("energy", bc)

    # 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
    bc_xodd = patch.BCObject(xlb=xlb_type,
                             xrb=xrb_type,
                             ylb=ylb_type,
                             yrb=yrb_type,
                             odd_reflect_dir="x")

    my_data.register_var("x-momentum", bc_xodd)

    # y-momentum -- if we are reflecting in y, then we need to
    # reflect odd
    bc_yodd = patch.BCObject(xlb=xlb_type,
                             xrb=xrb_type,
                             ylb=ylb_type,
                             yrb=yrb_type,
                             odd_reflect_dir="y")

    my_data.register_var("y-momentum", bc_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 = rp.get_param("eos.gamma")
    my_data.set_aux("gamma", gamma)

    # initialize the EOS gamma
    eos.init(gamma)

    my_data.create()

    vars.idens = my_data.vars.index("density")
    vars.ixmom = my_data.vars.index("x-momentum")
    vars.iymom = my_data.vars.index("y-momentum")
    vars.iener = my_data.vars.index("energy")

    print my_data

    return my_grid, my_data
示例#15
0
def f(x, y):
    return -2.0 * ((1.0 - 6.0 * x**2) * y**2 * (1.0 - y**2) +
                   (1.0 - 6.0 * y**2) * x**2 * (1.0 - x**2))


# test the multigrid solver
nx = 256
ny = nx

# create the coefficient variable -- note we don't want Dirichlet here,
# because that will try to make alpha = 0 on the interface.  alpha can
# have different BCs than phi
g = patch.Grid2d(nx, ny, ng=1)
d = patch.CellCenterData2d(g)
bc_c = patch.BCObject(xlb="neumann",
                      xrb="neumann",
                      ylb="neumann",
                      yrb="neumann")
d.register_var("c", bc_c)
d.create()

c = d.get_var("c")
c[:, :] = alpha(g.x2d, g.y2d)

plt.clf()

plt.figure(num=1, figsize=(5.0, 5.0), dpi=100, facecolor='w')

plt.imshow(np.transpose(c[g.ilo:g.ihi + 1, g.jlo:g.jhi + 1]),
           interpolation="nearest",
           origin="lower",
           extent=[g.xmin, g.xmax, g.ymin, g.ymax])