Example #1
0
def doit():

    myg = mesh.patch.Grid2d(4, 4, ng=2, xmax=1.0, ymax=1.0)

    mydata = mesh.patch.CellCenterData2d(myg, dtype=np.int)

    bco = bnd.BC(xlb="outflow", xrb="outflow",
                 ylb="outflow", yrb="outflow")
    mydata.register_var("outflow", bco)

    bcp = bnd.BC(xlb="periodic", xrb="periodic",
                 ylb="periodic", yrb="periodic")
    mydata.register_var("periodic", bcp)

    bcre = bnd.BC(xlb="reflect-even", xrb="reflect-even",
                  ylb="reflect-even", yrb="reflect-even")
    mydata.register_var("reflect-even", bcre)

    bcro = bnd.BC(xlb="reflect-odd", xrb="reflect-odd",
                  ylb="reflect-odd", yrb="reflect-odd")
    mydata.register_var("reflect-odd", bcro)

    mydata.create()


    a = mydata.get_var("outflow")

    for i in range(myg.ilo, myg.ihi+1):
        for j in range(myg.jlo, myg.jhi+1):
            a[i,j] = (i-myg.ilo) + 10*(j-myg.jlo) + 1


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

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

    mydata.fill_BC("outflow")
    mydata.fill_BC("periodic")
    mydata.fill_BC("reflect-even")
    mydata.fill_BC("reflect-odd")


    print("outflow")
    mydata.pretty_print("outflow")

    print(" ")
    print("periodic")
    mydata.pretty_print("periodic")

    print(" ")
    print("reflect-even")
    mydata.pretty_print("reflect-even")

    print(" ")
    print("reflect-odd")
    mydata.pretty_print("reflect-odd")
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 = bnd.BC(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 = bnd.BC(xlb=xlb_type,
                     xrb=xrb_type,
                     ylb=ylb_type,
                     yrb=yrb_type,
                     odd_reflect_dir="x")

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

    return bc, bc_xodd, bc_yodd
Example #3
0
def test_bcs_1d():

    myg = patch.Grid1d(4, ng=2, xmax=1.0)
    myd = patch.CellCenterData1d(myg, dtype=np.int)

    bco = bnd.BC(xlb="outflow", xrb="outflow")
    myd.register_var("outflow", bco)

    bcp = bnd.BC(xlb="periodic", xrb="periodic")
    myd.register_var("periodic", bcp)

    bcre = bnd.BC(xlb="reflect-even", xrb="reflect-even")
    myd.register_var("reflect-even", bcre)

    bcro = bnd.BC(xlb="reflect-odd", xrb="reflect-odd")
    myd.register_var("reflect-odd", bcro)

    myd.create()

    a = myd.get_var("outflow")
    a.v()[:] = np.array([1, 2, 3, 4], dtype=int)

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

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

    myd.fill_BC("outflow")
    # left ghost
    assert a[myg.ilo - 1] == 1
    # right ghost
    assert a[myg.ihi + 1] == 4

    myd.fill_BC("periodic")
    # x-boundaries
    assert b[myg.ilo - 1] == b[myg.ihi]
    assert b[myg.ilo] == b[myg.ihi + 1]

    myd.fill_BC("reflect-even")
    # left -- we'll check 2 ghost cells here
    # left
    assert_array_equal(c[myg.ilo:myg.ilo + 2], c[myg.ilo - 2:myg.ilo][::-1])
    # right
    assert_array_equal(c[myg.ihi - 1:myg.ihi + 1],
                       c[myg.ihi + 1:myg.ihi + 3][::-1])

    myd.fill_BC("reflect-odd")
    # left -- we'll check 2 ghost cells here
    # left
    assert_array_equal(d[myg.ilo:myg.ilo + 2],
                       -1.0 * d[myg.ilo - 2:myg.ilo][::-1])
    # right
    assert_array_equal(d[myg.ihi - 1:myg.ihi + 1],
                       -1.0 * d[myg.ihi + 1:myg.ihi + 3][::-1])
Example #4
0
def do_demo():
    """ show examples of the patch methods / classes """

    import util.io as io

    # illustrate basic mesh operations

    myg = Grid2d(8, 16, xmax=1.0, ymax=2.0)

    mydata = CellCenterData2d(myg)

    bc = bnd.BC()

    mydata.register_var("a", bc)
    mydata.create()

    a = mydata.get_var("a")
    a[:, :] = np.exp(-(myg.x2d - 0.5)**2 - (myg.y2d - 1.0)**2)

    print(mydata)

    # output
    print("writing\n")
    mydata.write("mesh_test")

    print("reading\n")
    myd2 = io.read("mesh_test")
    print(myd2)

    mydata.pretty_print("a")
Example #5
0
def do_demo():


    # illustrate basic mesh operations

    myg = Grid2d(8, 16, xmax=1.0, ymax=2.0)

    mydata = CellCenterData2d(myg)

    bc = bnd.BC()

    mydata.register_var("a", bc)
    mydata.create()


    a = mydata.get_var("a")
    a[:,:] = np.exp(-(myg.x2d - 0.5)**2 - (myg.y2d - 1.0)**2)

    print(mydata)

    # output
    print("writing\n")
    mydata.write("mesh_test")

    print("reading\n")
    _, myd2 = read("mesh_test")
    print(myd2)


    mydata.pretty_print("a")
Example #6
0
def bc_setup(rp):

    # first figure out the BCs
    try:
        xlb_type = rp.get_param("mesh.xlboundary")
    except KeyError:
        xlb_type = "periodic"
        msg.warning("mesh.xlboundary is not set, defaulting to periodic")

    try:
        xrb_type = rp.get_param("mesh.xrboundary")
    except KeyError:
        xrb_type = "periodic"
        msg.warning("mesh.xrboundary is not set, defaulting to periodic")

    try:
        ylb_type = rp.get_param("mesh.ylboundary")
    except KeyError:
        ylb_type = "periodic"
        msg.warning("mesh.ylboundary is not set, defaulting to periodic")

    try:
        yrb_type = rp.get_param("mesh.yrboundary")
    except KeyError:
        yrb_type = "periodic"
        msg.warning("mesh.yrboundary is not set, defaulting to periodic")

    bc = bnd.BC(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 = bnd.BC(xlb=xlb_type,
                     xrb=xrb_type,
                     ylb=ylb_type,
                     yrb=yrb_type,
                     odd_reflect_dir="x")

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

    return bc, bc_xodd, bc_yodd
Example #7
0
def doit():

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

    a = myd.get_var("a")

    a[myg.ilo:myg.ihi + 1,
      myg.jlo:myg.jhi + 1].flat = np.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")
    a_coarse[:, :] = myd.restrict("a")[:, :]

    cd.pretty_print("a")

    print(" ")
    print("prolongation test")
    print("original (coarse) array w/ ghost cells")
    a_coarse[:, :].flat = np.arange(cg.qx * cg.qy)
    cd.pretty_print("a")

    # create a new fine (base) grid and fill the variable in it prolonged data
    # from the coarsened grid
    print(" ")
    print("prolonged array")

    fg = patch.Grid2d(4, 8, ng=1)
    fd = patch.CellCenterData2d(fg)
    fd.register_var("a", bc)
    fd.create()

    a_fine = fd.get_var("a")
    a_fine[:, :] = cd.prolong("a")[:, :]

    fd.pretty_print("a")
Example #8
0
    def setup_method(self):
        """ this is run before each test """
        nx = 8
        ny = 8
        self.g = patch.Grid2d(nx, ny, ng=2, xmax=1.0, ymax=1.0)
        self.d = patch.CellCenterData2d(self.g, dtype=np.int)

        bco = bnd.BC(xlb="outflow",
                     xrb="outflow",
                     ylb="outflow",
                     yrb="outflow")
        self.d.register_var("a", bco)
        self.d.register_var("b", bco)
        self.d.create()
Example #9
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)

        # for MG, we need to be a power of two
        if my_grid.nx != my_grid.ny:
            msg.fail("need nx = ny for diffusion problems")

        n = int(math.log(my_grid.nx) / math.log(2.0))
        if 2**n != my_grid.nx:
            msg.fail("grid needs to be a power of 2")

        # 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 = bnd.BC(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
        problem = importlib.import_module("diffusion.problems.{}".format(
            self.problem_name))
        problem.init_data(self.cc_data, self.rp)
Example #10
0
    def setup_method(self):
        """ this is run before each test """
        self.rp = runparams.RuntimeParameters()
        self.rp.params["driver.tmax"] = 1.0
        self.rp.params["driver.max_steps"] = 100
        self.rp.params["driver.init_tstep_factor"] = 0.5
        self.rp.params["driver.max_dt_change"] = 1.2
        self.rp.params["driver.fix_dt"] = -1.0

        self.sim = sn.NullSimulation("test", "test", self.rp)

        myg = patch.Grid2d(8, 16)
        myd = patch.CellCenterData2d(myg)
        bc = bnd.BC()
        myd.register_var("a", bc)
        myd.create()

        self.sim.cc_data = myd
Example #11
0
def test_write_read():

    myg = patch.Grid2d(8, 6, ng=2, xmax=1.0, ymax=1.0)
    myd = patch.CellCenterData2d(myg)

    bco = bnd.BC(xlb="outflow", xrb="outflow", ylb="outflow", yrb="outflow")
    myd.register_var("a", bco)

    myd.create()

    a = myd.get_var("a")
    a.v()[:, :] = np.arange(48).reshape(8, 6)

    myd.write("io_test")

    # now read it in
    nd = io.read("io_test")

    anew = nd.get_var("a")

    assert_array_equal(anew.v(), a.v())
Example #12
0
File: io.py Project: grmath/pyro2
def read(filename):
    """read an HDF5 file and recreate the simulation object that holds the
    data and state of the simulation.

    """
    if not filename.endswith(".h5"):
        filename += ".h5"

    with h5py.File(filename, "r") as f:

        # read the simulation information -- this only exists if the
        # file was created as a simulation object
        try:
            solver_name = f.attrs["solver"]
            problem_name = f.attrs["problem"]
            t = f.attrs["time"]
            n = f.attrs["nsteps"]
        except KeyError:
            # this was just a patch written out
            solver_name = None

        # read in the grid info and create our grid
        grid = f["grid"].attrs

        myg = patch.Grid2d(grid["nx"],
                           grid["ny"],
                           ng=grid["ng"],
                           xmin=grid["xmin"],
                           xmax=grid["xmax"],
                           ymin=grid["ymin"],
                           ymax=grid["ymax"])

        # sometimes problems define custom BCs -- at the moment, we
        # are going to assume that these always map to BC.user.  We
        # need to read these in now, since the variable creation
        # requires it.
        custom_bcs = read_bcs(f)
        if custom_bcs is not None:
            if solver_name in [
                    "compressible_fv4", "compressible_rk", "compressible_sdc"
            ]:
                bc_solver = "compressible"
            else:
                bc_solver = solver_name
            bcmod = importlib.import_module("{}.{}".format(bc_solver, "BC"))
            for name in custom_bcs:
                bnd.define_bc(name, bcmod.user, is_solid=custom_bcs[name])

        # read in the variable info -- start by getting the names
        gs = f["state"]
        names = []
        for n in gs:
            names.append(n)

        # create the CellCenterData2d object
        myd = patch.CellCenterData2d(myg)

        for n in names:
            grp = gs[n]
            bc = bnd.BC(xlb=grp.attrs["xlb"],
                        xrb=grp.attrs["xrb"],
                        ylb=grp.attrs["ylb"],
                        yrb=grp.attrs["yrb"])
            myd.register_var(n, bc)

        myd.create()

        # auxillary data
        for k in f["aux"].attrs:
            myd.set_aux(k, f["aux"].attrs[k])

        # restore the variable data
        for n in names:
            grp = gs[n]
            data = grp["data"]

            v = myd.get_var(n)
            v.v()[:, :] = data[:, :]

        # restore the particle data
        try:
            gparticles = f["particles"]
            particle_data = gparticles["particle_positions"]
            init_data = gparticles["init_particle_positions"]

            my_particles = particles.Particles(myd, None, len(particle_data),
                                               "array", particle_data,
                                               init_data)
        except KeyError:
            my_particles = None

        if solver_name is not None:
            solver = importlib.import_module(solver_name)

            sim = solver.Simulation(solver_name, problem_name, None)
            sim.n = n
            sim.cc_data = myd
            sim.cc_data.t = t
            sim.particles = my_particles

            sim.read_extras(f)

    if solver_name is not None:
        return sim

    return myd
Example #13
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 = bnd.BC(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 = bnd.BC(xlb=xlb_type, xrb=xrb_type, 
                         ylb=ylb_type, yrb=yrb_type,
                         odd_reflect_dir="x")

        bc_yodd = bnd.BC(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 
        problem = importlib.import_module("lm_combustion.problems.{}".format(self.problem_name))
        problem.init_data(self.cc_data, self.rp)
Example #14
0
def test_vc_constant(N):

    # test the multigrid solver
    nx = N
    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 = bnd.BC(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])

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

    plt.colorbar()

    plt.savefig("mg_alpha.png")

    # check whether the RHS sums to zero (necessary for periodic data)
    rhs = f(g.x2d, g.y2d)
    print("rhs sum: {}".format(np.sum(rhs[g.ilo:g.ihi + 1, g.jlo:g.jhi + 1])))

    # 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=1)

    # 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

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

    # plot it
    plt.clf()

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

    plt.subplot(121)

    plt.imshow(np.transpose(v[a.ilo:a.ihi + 1, a.jlo:a.jhi + 1]),
               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[a.ilo:a.ihi + 1, a.jlo:a.jhi + 1]),
               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_test.png")

    # store the output for later comparison
    my_data = a.get_solution_object()
    my_data.write("mg_test")
Example #15
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 = bnd.BC(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
        problem = importlib.import_module("lm_atm.problems.{}".format(
            self.problem_name))
        problem.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]
Example #16
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 = bnd.BC(xlb="outflow", xrb="outflow", ylb="outflow", yrb="outflow")
    myd.register_var("outflow", bco)

    bcp = bnd.BC(xlb="periodic",
                 xrb="periodic",
                 ylb="periodic",
                 yrb="periodic")
    myd.register_var("periodic", bcp)

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

    bcro = bnd.BC(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[:, :] = a[:, :]
    c[:, :] = a[:, :]
    d[:, :] = a[:, :]

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

    myd.fill_BC("periodic")
    # x-boundaries
    assert_array_equal(b[myg.ilo - 1, myg.jlo:myg.jhi + 1],
                       b[myg.ihi, myg.jlo:myg.jhi + 1])
    assert_array_equal(b[myg.ilo, myg.jlo:myg.jhi + 1], b[myg.ihi + 1,
                                                          myg.jlo:myg.jhi + 1])
    # y-boundaries
    assert_array_equal(b[myg.ilo:myg.ihi + 1, myg.jlo - 1],
                       b[myg.ilo:myg.ihi + 1, myg.jhi])
    assert_array_equal(b[myg.ilo:myg.ihi + 1, myg.jlo], b[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[myg.ilo:myg.ilo + 2, myg.jlo:myg.ihi + 1],
                       np.flipud(c[myg.ilo - 2:myg.ilo, myg.jlo:myg.jhi + 1]))
    # right
    assert_array_equal(
        c[myg.ihi - 1:myg.ihi + 1, myg.jlo:myg.jhi + 1],
        np.flipud(c[myg.ihi + 1:myg.ihi + 3, myg.jlo:myg.jhi + 1]))

    # bottom
    assert_array_equal(c[myg.ilo:myg.ihi + 1, myg.jlo:myg.jlo + 2],
                       np.fliplr(c[myg.ilo:myg.ihi + 1, myg.jlo - 2:myg.jlo]))
    # top
    assert_array_equal(
        c[myg.ilo:myg.ihi + 1, myg.jhi - 1:myg.jhi + 1],
        np.fliplr(c[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[myg.ilo:myg.ilo + 2, myg.jlo:myg.ihi + 1],
                       -np.flipud(d[myg.ilo - 2:myg.ilo, myg.jlo:myg.jhi + 1]))
    # right
    assert_array_equal(
        d[myg.ihi - 1:myg.ihi + 1, myg.jlo:myg.jhi + 1],
        -np.flipud(d[myg.ihi + 1:myg.ihi + 3, myg.jlo:myg.jhi + 1]))

    # bottom
    assert_array_equal(d[myg.ilo:myg.ihi + 1, myg.jlo:myg.jlo + 2],
                       -np.fliplr(d[myg.ilo:myg.ihi + 1, myg.jlo - 2:myg.jlo]))
    # top
    assert_array_equal(
        d[myg.ilo:myg.ihi + 1, myg.jhi - 1:myg.jhi + 1],
        -np.fliplr(d[myg.ilo:myg.ihi + 1, myg.jhi + 1:myg.jhi + 3]))
Example #17
0
# test the boundary fill routine

from __future__ import print_function

import numpy as np
import mesh.patch
import mesh.boundary as bnd

myg = mesh.patch.Grid2d(4, 4, ng=2, xmax=1.0, ymax=1.0)

mydata = mesh.patch.CellCenterData2d(myg, dtype=np.int)

bco = bnd.BC(xlb="outflow", xrb="outflow", ylb="outflow", yrb="outflow")
mydata.register_var("outflow", bco)

bcp = bnd.BC(xlb="periodic", xrb="periodic", ylb="periodic", yrb="periodic")
mydata.register_var("periodic", bcp)

bcre = bnd.BC(xlb="reflect-even",
              xrb="reflect-even",
              ylb="reflect-even",
              yrb="reflect-even")
mydata.register_var("reflect-even", bcre)

bcro = bnd.BC(xlb="reflect-odd",
              xrb="reflect-odd",
              ylb="reflect-odd",
              yrb="reflect-odd")
mydata.register_var("reflect-odd", bcro)

mydata.create()
Example #18
0
def test_vc_poisson_periodic(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 = bnd.BC(xlb="periodic",
                  xrb="periodic",
                  ylb="periodic",
                  yrb="periodic")
    d.register_var("c", bc_c)
    d.create()

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

    # check whether the RHS sums to zero (necessary for periodic data)
    rhs = f(g.x2d, g.y2d)
    print("rhs sum: {}".format(np.sum(rhs[g.ilo:g.ihi + 1, g.jlo:g.jhi + 1])))

    # create the multigrid object
    a = MG.VarCoeffCCMG2d(nx,
                          ny,
                          xl_BC_type="periodic",
                          yl_BC_type="periodic",
                          xr_BC_type="periodic",
                          yr_BC_type="periodic",
                          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,10000)

    # get the solution
    v = a.get_solution()

    # get the true solution
    b = true(a.x2d, a.y2d)

    # compute the error from the analytic solution -- note that with
    # periodic BCs all around, there is nothing to normalize the
    # solution.  We subtract off the average of phi from the MG
    # solution (we do the same for the true solution to put them on
    # the same footing)
    e = v - np.sum(v.v()) / (nx * ny) - (
        b - np.sum(b[a.ilo:a.ihi + 1, a.jlo:a.jhi + 1]) / (nx * ny))

    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_periodic_test.png")

    # store the output for later comparison
    bench = "mg_vc_poisson_periodic"
    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 {}".format(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: {}\n".format(compare.errors[result]))

        return result

    # normal return -- error wrt true solution
    return enorm
Example #19
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 = bnd.BC(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 = bnd.BC(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 = bnd.BC(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.ivars = Variables(idens=my_data.names.index("density"),
                               ixmom=my_data.names.index("x-momentum"),
                               iymom=my_data.names.index("y-momentum"),
                               iener=my_data.names.index("energy"),
                               ierad=my_data.names.index("erad"))

        # initial conditions for the problem
        problem = importlib.import_module("radhydro.problems.{}".format(
            self.problem_name))
        problem.init_data(self.cc_data, self.rp)

        if verbose > 0: print(my_data)
Example #20
0
def read(filename):

    if not filename.endswith(".h5"):
        filename += ".h5"

    with h5py.File(filename, "r") as f:
        
        # read the simulation information -- this only exists if the 
        # file was created as a simulation object
        try:
            solver_name = f.attrs["solver"]
            problem_name = f.attrs["problem"]
            t = f.attrs["time"]
            n = f.attrs["nsteps"]
        except KeyError:
            # this was just a patch written out
            solver_name = None

        # read in the grid info and create our grid
        grid = f["grid"].attrs

        myg = patch.Grid2d(grid["nx"], grid["ny"], ng=grid["ng"], 
                           xmin=grid["xmin"], xmax=grid["xmax"], 
                           ymin=grid["ymin"], ymax=grid["ymax"])


        # read in the variable info -- start by getting the names
        gs = f["state"]
        names = []
        for n in gs:
            names.append(n)

        # create the CellCenterData2d object
        myd = patch.CellCenterData2d(myg)

        for n in names:
            grp = gs[n]
            bc = bnd.BC(xlb=grp.attrs["xlb"], xrb=grp.attrs["xrb"],
                        ylb=grp.attrs["ylb"], yrb=grp.attrs["yrb"])
            myd.register_var(n, bc)

        myd.create()

        # auxillary data
        for k in f["aux"].attrs:
            myd.set_aux(k, f["aux"].attrs[k])

        # restore the variable data
        for n in names:
            grp = gs[n]
            data = grp["data"]
            
            v = myd.get_var(n)
            v.v()[:,:] = data[:,:]

        if solver_name is not None:
            solver = importlib.import_module(solver_name)

            sim = solver.Simulation(solver_name, problem_name, None)
            sim.n = n
            sim.cc_data = myd
            sim.cc_data.t = t

            sim.read_extras(f)

    if solver_name is not None:
        return sim
    else:
        return myd

            
Example #21
0
import numpy

import MG
import mesh.boundary as bnd
import mesh.patch as patch

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 = bnd.BC(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)
U.register_var('dphi', bc)
Example #22
0
def test_general_poisson_dirichlet(N,
                                   store_bench=False,
                                   comp_bench=False,
                                   make_plot=False,
                                   verbose=1):
    """
    test the general 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 = bnd.BC(xlb="neumann", xrb="neumann", ylb="neumann", yrb="neumann")
    d.register_var("alpha", bc_c)
    d.register_var("beta", bc_c)
    d.register_var("gamma_x", bc_c)
    d.register_var("gamma_y", bc_c)
    d.create()

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

    b = d.get_var("beta")
    b[:, :] = beta(g.x2d, g.y2d)

    gx = d.get_var("gamma_x")
    gx[:, :] = gamma_x(g.x2d, g.y2d)

    gy = d.get_var("gamma_y")
    gy[:, :] = gamma_y(g.x2d, g.y2d)

    # create the multigrid object
    a = MG.GeneralMG2d(nx,
                       ny,
                       xl_BC_type="dirichlet",
                       yl_BC_type="dirichlet",
                       xr_BC_type="dirichlet",
                       yr_BC_type="dirichlet",
                       coeffs=d,
                       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_general_dirichlet_test.png")

    # store the output for later comparison
    bench = "mg_general_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 = io.read(compare_file)

        result = compare.compare(my_data, bench)

        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
# test the prolongation and restriction operations from the patch stuff

from __future__ import print_function

import mesh.boundary as bnd
import mesh.patch as patch
import numpy as np

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

a = myd.get_var("a")

a[myg.ilo:myg.ihi+1,myg.jlo:myg.jhi+1].flat = np.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)
Example #24
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 BC objects, 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:
            raise ValueError("ERROR: multigrid currently requires nx = ny")

        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):
            raise ValueError("ERROR: multigrid currently requires a square domain")

        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 true_function is not 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 = bnd.BC(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 = bnd.BC(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 aux_field is not 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
Example #25
0
def doit(nx, ny):

    nproj = 2

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

    bc = bnd.BC(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)
    U.register_var('dphi', bc)

    U.register_var('gradphi_x-old', bc)
    U.register_var('gradphi_y-old', bc)
    U.register_var('gradphi_x', bc)
    U.register_var('gradphi_y', bc)

    U.create()

    # initialize a divergence free velocity field,
    # u = -sin^2(pi x) sin(2 pi y), v = sin^2(pi y) sin(2 pi x)
    u = U.get_var('u')
    v = U.get_var('v')

    u[:, :] = -(np.sin(np.pi * myg.x2d)**2) * np.sin(2.0 * np.pi * myg.y2d)
    v[:, :] = (np.sin(np.pi * myg.y2d)**2) * np.sin(2.0 * np.pi * myg.x2d)

    # store the original, divergence free velocity field for comparison later
    uold = U.get_var('u-old')
    vold = U.get_var('v-old')

    uold[:, :] = u.copy()
    vold[:, :] = v.copy()

    # the projection routine should decompose U into a divergence free
    # part, U_d, plus the gradient of a scalar.  Add on the gradient
    # of a scalar that satisfies gradphi.n = 0.  After the projection,
    # we should recover the divergence free field above.  Take phi to
    # be a gaussian, exp(-((x-x0)^2 + (y-y0)^2)/R)
    R = 0.1
    x0 = 0.5
    y0 = 0.5

    phi = U.get_var('phi-old')
    gradphi_x = U.get_var('gradphi_x-old')
    gradphi_y = U.get_var('gradphi_y-old')

    phi[:, :] = np.exp(-((myg.x2d - x0)**2 + (myg.y2d - y0)**2) / R**2)

    gradphi_x[:, :] = phi * (-2.0 * (myg.x2d - x0) / R**2)
    gradphi_y[:, :] = phi * (-2.0 * (myg.y2d - y0) / R**2)

    u += gradphi_x
    v += gradphi_y

    u_plus_gradphi = U.get_var('u+gphi')
    v_plus_gradphi = U.get_var('v+gphi')

    u_plus_gradphi[:, :] = u[:, :]
    v_plus_gradphi[:, :] = v[:, :]

    # use the mesh class to enforce the periodic BCs on the velocity field
    U.fill_BC_all()

    # now compute the cell-centered, centered-difference divergence
    divU = U.get_var('divU')

    divU[myg.ilo:myg.ihi+1, myg.jlo:myg.jhi+1] = \
          0.5*(u[myg.ilo+1:myg.ihi+2, myg.jlo:myg.jhi+1] -
               u[myg.ilo-1:myg.ihi, myg.jlo:myg.jhi+1])/myg.dx + \
          0.5*(v[myg.ilo:myg.ihi+1, myg.jlo+1:myg.jhi+2] -
               v[myg.ilo:myg.ihi+1, myg.jlo-1:myg.jhi])/myg.dy

    # create the multigrid object with Neumann BCs
    a = MG.CellCenterMG2d(nx,
                          ny,
                          xl_BC_type="periodic",
                          xr_BC_type="periodic",
                          yl_BC_type="periodic",
                          yr_BC_type="periodic",
                          verbose=1)

    #--------------------------------------------------------------------------
    # projections
    #--------------------------------------------------------------------------
    for iproj in range(nproj):

        a.init_zeros()
        a.init_RHS(divU)
        a.solve(rtol=1.e-12)

        phi = U.get_var('phi')
        solution = a.get_solution()

        phi[myg.ilo-1:myg.ihi+2, myg.jlo-1:myg.jhi+2] = \
            solution[a.ilo-1:a.ihi+2, a.jlo-1:a.jhi+2]

        dphi = U.get_var('dphi')
        dphi[:, :] = phi - U.get_var('phi-old')

        # compute the gradient of phi using centered differences
        gradphi_x = U.get_var('gradphi_x')
        gradphi_y = U.get_var('gradphi_y')

        gradphi_x[myg.ilo:myg.ihi+1, myg.jlo:myg.jhi+1] = \
            0.5*(phi[myg.ilo+1:myg.ihi+2, myg.jlo:myg.jhi+1] -
                 phi[myg.ilo-1:myg.ihi, myg.jlo:myg.jhi+1])/myg.dx

        gradphi_y[myg.ilo:myg.ihi+1, myg.jlo:myg.jhi+1] = \
            0.5*(phi[myg.ilo:myg.ihi+1, myg.jlo+1:myg.jhi+2] -
                 phi[myg.ilo:myg.ihi+1, myg.jlo-1:myg.jhi])/myg.dy

        # update the velocity field
        u -= gradphi_x
        v -= gradphi_y

        U.fill_BC_all()

        # recompute the divergence diagnostic
        divU[myg.ilo:myg.ihi+1, myg.jlo:myg.jhi+1] = \
             0.5*(u[myg.ilo+1:myg.ihi+2, myg.jlo:myg.jhi+1] -
                  u[myg.ilo-1:myg.ihi, myg.jlo:myg.jhi+1])/myg.dx + \
             0.5*(v[myg.ilo:myg.ihi+1, myg.jlo+1:myg.jhi+2] -
                  v[myg.ilo:myg.ihi+1, myg.jlo-1:myg.jhi])/myg.dy

        U.write("proj-periodic.after" + ("%d" % iproj))