Exemplo n.º 1
0
    def get_stage_start(self, istage):
        """get the starting conditions (a CellCenterData2d object) for stage
        istage"""
        if istage == 0:
            ytmp = self.start
        else:
            ytmp = patch.cell_center_data_clone(self.start)
            for n in range(ytmp.nvar):
                var = ytmp.get_var_by_index(n)
                for s in range(istage):
                    var.v()[:, :] += self.dt*a[self.method][istage, s]*self.k[s].v(n=n)[:, :]

            ytmp.t = self.t + c[self.method][istage]*self.dt

        return ytmp
Exemplo n.º 2
0
    def get_stage_start(self, istage):
        """get the starting conditions (a CellCenterData2d object) for stage
        istage"""
        if istage == 0:
            ytmp = self.start
        else:
            ytmp = patch.cell_center_data_clone(self.start)
            for n in range(ytmp.nvar):
                var = ytmp.get_var_by_index(n)
                for s in range(istage):
                    var.v()[:, :] += self.dt * a[self.method][istage,
                                                              s] * self.k[s].v(
                                                                  n=n)[:, :]

            ytmp.t = self.t + c[self.method][istage] * self.dt

        return ytmp
Exemplo n.º 3
0
    def evolve(self):
        """
        Evolve the equations of compressible hydrodynamics through a
        timestep dt.
        """

        tm_evolve = self.tc.timer("evolve")
        tm_evolve.begin()

        myd = self.cc_data

        # we need the solution at 3 time points and at the old and
        # current iteration (except for m = 0 -- that doesn't change).

        # This copy will initialize the the solution at all time nodes
        # with the current (old) solution.
        U_kold = []
        U_kold.append(patch.cell_center_data_clone(self.cc_data))
        U_kold.append(patch.cell_center_data_clone(self.cc_data))
        U_kold.append(patch.cell_center_data_clone(self.cc_data))

        U_knew = []
        U_knew.append(U_kold[0])
        U_knew.append(patch.cell_center_data_clone(self.cc_data))
        U_knew.append(patch.cell_center_data_clone(self.cc_data))

        # loop over iterations
        for _ in range(1, 5):

            # we need the advective term at all time nodes at the old
            # iteration -- we'll compute this now
            A_kold = []
            for m in range(3):
                _tmp = self.substep(U_kold[m])
                A_kold.append(_tmp)

            # loop over the time nodes and update
            for m in range(2):

                # update m to m+1 for knew

                # compute A(U_m^{k+1})
                A_knew = self.substep(U_knew[m])

                # compute the integral over A at the old iteration
                I = self.sdc_integral(m, m + 1, A_kold)

                # and the final update
                for n in range(self.ivars.nvar):
                    U_knew[m+1].data.v(n=n)[:, :] = U_knew[m].data.v(n=n) + \
                        0.5*self.dt * (A_knew.v(n=n) - A_kold[m].v(n=n)) + I.v(n=n)

                # fill ghost cells
                U_knew[m + 1].fill_BC_all()

            # store the current iteration as the old iteration
            for m in range(1, 3):
                U_kold[m].data[:, :, :] = U_knew[m].data[:, :, :]

        # store the new solution
        self.cc_data.data[:, :, :] = U_knew[-1].data[:, :, :]

        if self.particles is not None:
            self.particles.update_particles(self.dt)

        # increment the time
        myd.t += self.dt
        self.n += 1

        tm_evolve.end()
Exemplo n.º 4
0
    def preevolve(self):
        """
        preevolve is called before we being the timestepping loop.  For
        the incompressible solver, this does an initial projection on the
        velocity field and then goes through the full evolution to get the
        value of phi.  The fluid state (u, v) is then reset to values
        before this evolve.
        """

        self.in_preevolve = True

        myg = self.cc_data.grid

        u = self.cc_data.get_var("x-velocity")
        v = self.cc_data.get_var("y-velocity")

        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")

        # 1. do the initial projection.  This makes sure that our original
        # velocity field satisties div U = 0

        # next create the multigrid object.  We want Neumann BCs on phi
        # at solid walls and periodic on phi for periodic BCs
        mg = MG.CellCenterMG2d(myg.nx,
                               myg.ny,
                               xl_BC_type="periodic",
                               xr_BC_type="periodic",
                               yl_BC_type="periodic",
                               yr_BC_type="periodic",
                               xmin=myg.xmin,
                               xmax=myg.xmax,
                               ymin=myg.ymin,
                               ymax=myg.ymax,
                               verbose=0)

        # first compute divU
        divU = mg.soln_grid.scratch_array()

        divU.v()[:, :] = \
            0.5*(u.ip(1) - u.ip(-1))/myg.dx + 0.5*(v.jp(1) - v.jp(-1))/myg.dy

        # solve L phi = DU

        # initialize our guess to the solution, set the RHS to divU and
        # solve
        mg.init_zeros()
        mg.init_RHS(divU)
        mg.solve(rtol=1.e-10)

        # store the solution in our self.cc_data object -- include a single
        # ghostcell
        phi = self.cc_data.get_var("phi")
        phi[:, :] = mg.get_solution(grid=myg)

        # compute the cell-centered gradient of phi and update the
        # velocities
        gradp_x, gradp_y = mg.get_solution_gradient(grid=myg)

        u[:, :] -= gradp_x
        v[:, :] -= gradp_y

        # fill the ghostcells
        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")

        # 2. now get an approximation to gradp at n-1/2 by going through the
        # evolution.

        # store the current solution -- we'll restore it in a bit
        orig_data = patch.cell_center_data_clone(self.cc_data)

        # get the timestep
        self.method_compute_timestep()

        # evolve
        self.evolve()

        # update gradp_x and gradp_y in our main data object
        new_gp_x = self.cc_data.get_var("gradp_x")
        new_gp_y = self.cc_data.get_var("gradp_y")

        orig_gp_x = orig_data.get_var("gradp_x")
        orig_gp_y = orig_data.get_var("gradp_y")

        orig_gp_x[:, :] = new_gp_x[:, :]
        orig_gp_y[:, :] = new_gp_y[:, :]

        self.cc_data = orig_data

        if self.verbose > 0:
            print("done with the pre-evolution")

        self.in_preevolve = False
Exemplo n.º 5
0
    def evolve(self):

        """
        Evolve the equations of compressible hydrodynamics through a
        timestep dt.
        """

        tm_evolve = self.tc.timer("evolve")
        tm_evolve.begin()

        myd = self.cc_data

        # we need the solution at 3 time points and at the old and
        # current iteration (except for m = 0 -- that doesn't change).

        # This copy will initialize the the solution at all time nodes
        # with the current (old) solution.
        U_kold = []
        U_kold.append(patch.cell_center_data_clone(self.cc_data))
        U_kold.append(patch.cell_center_data_clone(self.cc_data))
        U_kold.append(patch.cell_center_data_clone(self.cc_data))

        U_knew = []
        U_knew.append(U_kold[0])
        U_knew.append(patch.cell_center_data_clone(self.cc_data))
        U_knew.append(patch.cell_center_data_clone(self.cc_data))

        # loop over iterations
        for _ in range(1, 5):

            # we need the advective term at all time nodes at the old
            # iteration -- we'll compute this now
            A_kold = []
            for m in range(3):
                _tmp = self.substep(U_kold[m])
                A_kold.append(_tmp)

            # loop over the time nodes and update
            for m in range(2):

                # update m to m+1 for knew

                # compute A(U_m^{k+1})
                A_knew = self.substep(U_knew[m])

                # compute the integral over A at the old iteration
                integral = self.sdc_integral(m, m+1, A_kold)

                # and the final update
                for n in range(self.ivars.nvar):
                    U_knew[m+1].data.v(n=n)[:, :] = U_knew[m].data.v(n=n) + \
                        0.5*self.dt * (A_knew.v(n=n) - A_kold[m].v(n=n)) + integral.v(n=n)

                # fill ghost cells
                U_knew[m+1].fill_BC_all()

            # store the current iteration as the old iteration
            for m in range(1, 3):
                U_kold[m].data[:, :, :] = U_knew[m].data[:, :, :]

        # store the new solution
        self.cc_data.data[:, :, :] = U_knew[-1].data[:, :, :]

        if self.particles is not None:
            self.particles.update_particles(self.dt)

        # increment the time
        myd.t += self.dt
        self.n += 1

        tm_evolve.end()
Exemplo n.º 6
0
    def preevolve(self):
        """
        preevolve is called before we being the timestepping loop.  For
        the low Mach solver, this does an initial projection on the
        velocity field and then goes through the full evolution to get the
        value of phi.  The fluid state (rho, u, v) is then reset to values
        before this evolve.
        """

        myg = self.cc_data.grid

        rho = self.cc_data.get_var("density")
        u = self.cc_data.get_var("x-velocity")
        v = self.cc_data.get_var("y-velocity")

        self.cc_data.fill_BC("density")        
        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")


        # 1. do the initial projection.  This makes sure that our original
        # velocity field satisties div U = 0

        # the coefficent for the elliptic equation is beta_0^2/rho
        coeff = 1.0/rho[myg.ilo-1:myg.ihi+2,myg.jlo-1:myg.jhi+2]
        beta0 = self.base["beta0"]
        coeff = coeff*beta0[np.newaxis,myg.jlo-1:myg.jhi+2]**2

        # next create the multigrid object.  We defined phi with
        # the right BCs previously
        mg = vcMG.VarCoeffCCMG2d(myg.nx, myg.ny,
                                 xl_BC_type=self.cc_data.BCs["phi"].xlb,
                                 xr_BC_type=self.cc_data.BCs["phi"].xrb,
                                 yl_BC_type=self.cc_data.BCs["phi"].ylb,
                                 yr_BC_type=self.cc_data.BCs["phi"].yrb,
                                 xmin=myg.xmin, xmax=myg.xmax,
                                 ymin=myg.ymin, ymax=myg.ymax,
                                 coeffs=coeff,
                                 coeffs_bc=self.cc_data.BCs["density"],
                                 verbose=0)

        # first compute div{beta_0 U}
        div_beta_U = mg.soln_grid.scratch_array()

        # u/v are cell-centered, divU is cell-centered
        div_beta_U[mg.ilo:mg.ihi+1,mg.jlo:mg.jhi+1] = \
            0.5*beta0[np.newaxis,mg.jlo:mg.jhi+1]* \
                (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*(beta0[np.newaxis,myg.jlo+1:myg.jhi+2]* \
                 v[myg.ilo:myg.ihi+1,myg.jlo+1:myg.jhi+2] -
                 beta0[np.newaxis,myg.jlo-1:myg.jhi  ]*
                 v[myg.ilo:myg.ihi+1,myg.jlo-1:myg.jhi  ])/myg.dy

        # solve D (beta_0^2/rho) G (phi/beta_0) = D( beta_0 U )

        # set the RHS to divU and solve
        mg.init_RHS(div_beta_U)
        mg.solve(rtol=1.e-10)

        # store the solution in our self.cc_data object -- include a single
        # ghostcell
        phi = self.cc_data.get_var("phi")
        phi[:,:] = mg.get_solution(grid=myg)

        # get the cell-centered gradient of phi and update the
        # velocities
        # FIXME: this update only needs to be done on the interior
        # cells -- not ghost cells
        gradp_x, gradp_y = mg.get_solution_gradient(grid=myg)

        coeff = 1.0/rho[:,:]
        coeff = coeff*beta0[np.newaxis,:]

        u[:,:] -= coeff*gradp_x
        v[:,:] -= coeff*gradp_y

        # fill the ghostcells
        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")


        # 2. now get an approximation to gradp at n-1/2 by going through the
        # evolution.

        # store the current solution -- we'll restore it in a bit
        orig_data = patch.cell_center_data_clone(self.cc_data)

        # get the timestep
        dt = self.timestep()

        # evolve
        self.evolve(dt)

        # update gradp_x and gradp_y in our main data object
        new_gp_x = self.cc_data.get_var("gradp_x")
        new_gp_y = self.cc_data.get_var("gradp_y")

        orig_gp_x = orig_data.get_var("gradp_x")
        orig_gp_y = orig_data.get_var("gradp_y")

        orig_gp_x[:,:] = new_gp_x[:,:]
        orig_gp_y[:,:] = new_gp_y[:,:]

        self.cc_data = orig_data

        if self.verbose > 0: print("done with the pre-evolution")
Exemplo n.º 7
0
def preevolve(my_data):
    """ 
    preevolve is called before we being the timestepping loop.  For
    the incompressible solver, this does an initial projection on the
    velocity field and then goes through the full evolution to get the
    value of phi.  The fluid state (u, v) is then reset to values
    before this evolve.
    """

    myg = my_data.grid

    u = my_data.get_var("x-velocity")
    v = my_data.get_var("y-velocity")

    my_data.fill_BC("x-velocity")
    my_data.fill_BC("y-velocity")

    # 1. do the initial projection.  This makes sure that our original
    # velocity field satisties div U = 0

    # next create the multigrid object.  We want Neumann BCs on phi
    # at solid walls and periodic on phi for periodic BCs
    MG = multigrid.CellCenterMG2d(myg.nx,
                                  myg.ny,
                                  xl_BC_type="periodic",
                                  xr_BC_type="periodic",
                                  yl_BC_type="periodic",
                                  yr_BC_type="periodic",
                                  xmin=myg.xmin,
                                  xmax=myg.xmax,
                                  ymin=myg.ymin,
                                  ymax=myg.ymax,
                                  verbose=0)

    # first compute divU
    divU = MG.soln_grid.scratch_array()

    divU[MG.ilo:MG.ihi+1,MG.jlo:MG.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

    # solve L phi = DU

    # initialize our guess to the solution
    MG.init_zeros()

    # setup the RHS of our Poisson equation
    MG.init_RHS(divU)

    # solve
    MG.solve(rtol=1.e-10)

    # store the solution in our my_data object -- include a single
    # ghostcell
    phi = my_data.get_var("phi")
    solution = MG.get_solution()

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

    # compute the cell-centered gradient of phi and update the
    # velocities
    gradp_x = myg.scratch_array()
    gradp_y = myg.scratch_array()

    gradp_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

    gradp_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

    u[:, :] -= gradp_x
    v[:, :] -= gradp_y

    # fill the ghostcells
    my_data.fill_BC("x-velocity")
    my_data.fill_BC("y-velocity")

    # 2. now get an approximation to gradp at n-1/2 by going through the
    # evolution.

    # store the current solution
    copyData = patch.cell_center_data_clone(my_data)

    # get the timestep
    dt = timestep.timestep(copyData)

    # evolve
    evolve.evolve(copyData, dt)

    # update gradp_x and gradp_y in our main data object
    gp_x = my_data.get_var("gradp_x")
    gp_y = my_data.get_var("gradp_y")

    new_gp_x = copyData.get_var("gradp_x")
    new_gp_y = copyData.get_var("gradp_y")

    gp_x[:, :] = new_gp_x[:, :]
    gp_y[:, :] = new_gp_y[:, :]

    print "done with the pre-evolution"
Exemplo n.º 8
0
    def preevolve(self):
        """
        preevolve is called before we being the timestepping loop.  For
        the incompressible solver, this does an initial projection on the
        velocity field and then goes through the full evolution to get the
        value of phi.  The fluid state (u, v) is then reset to values
        before this evolve.
        """

        self.in_preevolve = True

        myg = self.cc_data.grid

        u = self.cc_data.get_var("x-velocity")
        v = self.cc_data.get_var("y-velocity")

        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")

        # 1. do the initial projection.  This makes sure that our original
        # velocity field satisties div U = 0

        # next create the multigrid object.  We want Neumann BCs on phi
        # at solid walls and periodic on phi for periodic BCs
        mg = MG.CellCenterMG2d(myg.nx, myg.ny,
                               xl_BC_type="periodic",
                               xr_BC_type="periodic",
                               yl_BC_type="periodic",
                               yr_BC_type="periodic",
                               xmin=myg.xmin, xmax=myg.xmax,
                               ymin=myg.ymin, ymax=myg.ymax,
                               verbose=0)

        # first compute divU
        divU = mg.soln_grid.scratch_array()

        divU.v()[:, :] = \
            0.5*(u.ip(1) - u.ip(-1))/myg.dx + 0.5*(v.jp(1) - v.jp(-1))/myg.dy

        # solve L phi = DU

        # initialize our guess to the solution, set the RHS to divU and
        # solve
        mg.init_zeros()
        mg.init_RHS(divU)
        mg.solve(rtol=1.e-10)

        # store the solution in our self.cc_data object -- include a single
        # ghostcell
        phi = self.cc_data.get_var("phi")
        phi[:, :] = mg.get_solution(grid=myg)

        # compute the cell-centered gradient of phi and update the
        # velocities
        gradp_x, gradp_y = mg.get_solution_gradient(grid=myg)

        u[:, :] -= gradp_x
        v[:, :] -= gradp_y

        # fill the ghostcells
        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")

        # 2. now get an approximation to gradp at n-1/2 by going through the
        # evolution.

        # store the current solution -- we'll restore it in a bit
        orig_data = patch.cell_center_data_clone(self.cc_data)

        # get the timestep
        self.method_compute_timestep()

        # evolve
        self.evolve()

        # update gradp_x and gradp_y in our main data object
        new_gp_x = self.cc_data.get_var("gradp_x")
        new_gp_y = self.cc_data.get_var("gradp_y")

        orig_gp_x = orig_data.get_var("gradp_x")
        orig_gp_y = orig_data.get_var("gradp_y")

        orig_gp_x[:, :] = new_gp_x[:, :]
        orig_gp_y[:, :] = new_gp_y[:, :]

        self.cc_data = orig_data

        if self.verbose > 0:
            print("done with the pre-evolution")

        self.in_preevolve = False
Exemplo n.º 9
0
    def evolve(self):
        """
        Evolve the linear advection equation through one timestep.  We only
        consider the "density" variable in the CellCenterData2d object that
        is part of the Simulation.
        """

        tm_evolve = self.tc.timer("evolve")
        tm_evolve.begin()

        myg = self.cc_data.grid
        myd = self.cc_data

        order = self.rp.get_param("advection.temporal_order")

        if order == 2:

            # time-integration -- RK2
            myd_nhalf = patch.cell_center_data_clone(myd)

            # initial slopes and n+1/2 state
            k1 = self.substep(myd)
            var = myd_nhalf.get_var("density")
            var.v()[:,:] += 0.5*self.dt*k1.v()[:,:]

            myd_nhalf.fill_BC_all()

            # updated slopes, starting with the n+1/2 state
            k2 = self.substep(myd_nhalf)

            # final update
            var = myd.get_var("density")
            var.v()[:,:] += self.dt*k2.v()[:,:]

        elif order == 4:

            # time-integration -- RK4

            # first slope (k1) is f(U^n)
            k1 = self.substep(myd)

            # second slope (k2) is f(U^n + 0.5*dt*k1)            
            myd1 = patch.cell_center_data_clone(myd)
            var = myd1.get_var("density")
            var.v()[:,:] += 0.5*self.dt*k1.v()[:,:]

            myd1.fill_BC_all()
            k2 = self.substep(myd1)

            # third slope (k3) is f(U^n + 0.5*dt*k2)
            myd2 = patch.cell_center_data_clone(myd)
            var = myd2.get_var("density")
            var.v()[:,:] += 0.5*self.dt*k2.v()[:,:]

            myd2.fill_BC_all()
            k3 = self.substep(myd2)

            # last slope (k4) is f(U^n + dt*k3)
            myd3 = patch.cell_center_data_clone(myd)
            var = myd3.get_var("density")
            var.v()[:,:] += self.dt*k3.v()[:,:]

            myd3.fill_BC_all()
            k4 = self.substep(myd3)

            # final update
            var = myd.get_var("density")
            var.v()[:,:] += (self.dt/6.0)*(k1.v()[:,:] + 2.0*k2.v()[:,:] + 2.0*k3.v()[:,:] + k4.v()[:,:])

        elif order == 103:

            # time-integration -- SSP RK3 (from Shu & Osher 1989)

            # compute u^1 = u^n + dt * L(u^n)
            k0 = self.substep(myd)
            u1 = patch.cell_center_data_clone(myd)
            var1 = u1.get_var("density")
            var1.v()[:,:] += self.dt*k0.v()[:,:]

            u1.fill_BC_all()

            # compute u^2 = (3/4) u^n + (1/4) u^1 + (1/4) dt * L(u^1)
            k1 = self.substep(u1)
            u2 = patch.cell_center_data_clone(myd)
            varn = myd.get_var("density")
            var1 = u1.get_var("density")
            var2 = u2.get_var("density")
            var2.v()[:,:] = 0.75*varn.v()[:,:] + 0.25*var1.v()[:,:] + 0.25*self.dt*k1.v()[:,:]

            u2.fill_BC_all()

            # compute u^new = (1/3) u^n + (2/3) u^2 + (2/3) dt L(u^2)
            k2 = self.substep(u2)
            var = myd.get_var("density")
            var2 = u2.get_var("density")
            var.v()[:,:] = (1.0/3.0)*var.v()[:,:] + (2.0/3.0)*var2.v()[:,:] + (2.0/3.0)*self.dt*k2.v()[:,:]



        # increment the time
        myd.t += self.dt
        self.n += 1

        tm_evolve.end()
Exemplo n.º 10
0
    def preevolve(self):
        """
        preevolve is called before we being the timestepping loop.  For
        the low Mach solver, this does an initial projection on the
        velocity field and then goes through the full evolution to get the
        value of phi.  The fluid state (rho, u, v) is then reset to values
        before this evolve.
        """

        self.in_preevolve = True

        myg = self.cc_data.grid

        rho = self.cc_data.get_var("density")
        u = self.cc_data.get_var("x-velocity")
        v = self.cc_data.get_var("y-velocity")

        self.cc_data.fill_BC("density")        
        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")

        # 1. do the initial projection.  This makes sure that our original
        # velocity field satisties div U = 0

        # the coefficent for the elliptic equation is beta_0^2/rho
        coeff = 1/rho
        beta0 = self.base["beta0"]
        coeff.v()[:,:] = coeff.v()*beta0.v2d()**2

        # next create the multigrid object.  We defined phi with
        # the right BCs previously
        mg = vcMG.VarCoeffCCMG2d(myg.nx, myg.ny,
                                 xl_BC_type=self.cc_data.BCs["phi"].xlb,
                                 xr_BC_type=self.cc_data.BCs["phi"].xrb,
                                 yl_BC_type=self.cc_data.BCs["phi"].ylb,
                                 yr_BC_type=self.cc_data.BCs["phi"].yrb,
                                 xmin=myg.xmin, xmax=myg.xmax,
                                 ymin=myg.ymin, ymax=myg.ymax,
                                 coeffs=coeff,
                                 coeffs_bc=self.cc_data.BCs["density"],
                                 verbose=0)

        # first compute div{beta_0 U}
        div_beta_U = mg.soln_grid.scratch_array()

        # u/v are cell-centered, divU is cell-centered
        div_beta_U.v()[:,:] = \
            0.5*beta0.v2d()*(u.ip(1) - u.ip(-1))/myg.dx + \
            0.5*(beta0.v2dp(1)*v.jp(1) - beta0.v2dp(-1)*v.jp(-1))/myg.dy

        # solve D (beta_0^2/rho) G (phi/beta_0) = D( beta_0 U )

        # set the RHS to divU and solve
        mg.init_RHS(div_beta_U.d)
        mg.solve(rtol=1.e-10)
        
        
        # store the solution in our self.cc_data object -- include a single
        # ghostcell
        phi = self.cc_data.get_var("phi")
        phi.d[:,:] = mg.get_solution(grid=myg).d

        # get the cell-centered gradient of phi and update the
        # velocities
        # FIXME: this update only needs to be done on the interior
        # cells -- not ghost cells
        gradp_x, gradp_y = mg.get_solution_gradient(grid=myg)


        coeff = 1.0/rho
        coeff.v()[:,:] = coeff.v()*beta0.v2d()

        u.v()[:,:] -= coeff.v()*gradp_x.v()
        v.v()[:,:] -= coeff.v()*gradp_y.v()

        # fill the ghostcells
        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")


        # 2. now get an approximation to gradp at n-1/2 by going through the
        # evolution.

        # store the current solution -- we'll restore it in a bit
        orig_data = patch.cell_center_data_clone(self.cc_data)

        # get the timestep
        self.compute_timestep()

        # evolve
        self.evolve()

        # update gradp_x and gradp_y in our main data object
        new_gp_x = self.cc_data.get_var("gradp_x")
        new_gp_y = self.cc_data.get_var("gradp_y")

        orig_gp_x = orig_data.get_var("gradp_x")
        orig_gp_y = orig_data.get_var("gradp_y")

        orig_gp_x.d[:,:] = new_gp_x.d[:,:]
        orig_gp_y.d[:,:] = new_gp_y.d[:,:]

        self.cc_data = orig_data

        if self.verbose > 0: print("done with the pre-evolution")

        self.in_preevolve = False
Exemplo n.º 11
0
    def preevolve(self):
        """ 
        preevolve is called before we being the timestepping loop.  For
        the incompressible solver, this does an initial projection on the
        velocity field and then goes through the full evolution to get the
        value of phi.  The fluid state (u, v) is then reset to values
        before this evolve.
        """

        myg = self.cc_data.grid

        u = self.cc_data.get_var("x-velocity")
        v = self.cc_data.get_var("y-velocity")

        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")

        # 1. do the initial projection.  This makes sure that our original
        # velocity field satisties div U = 0

        # next create the multigrid object.  We defined phi with
        # the right BCs previously
        mg = MG.CellCenterMG2d(myg.nx,
                               myg.ny,
                               xl_BC_type=self.cc_data.BCs["phi"].xlb,
                               xr_BC_type=self.cc_data.BCs["phi"].xrb,
                               yl_BC_type=self.cc_data.BCs["phi"].ylb,
                               yr_BC_type=self.cc_data.BCs["phi"].yrb,
                               xmin=myg.xmin,
                               xmax=myg.xmax,
                               ymin=myg.ymin,
                               ymax=myg.ymax,
                               verbose=0)

        # first compute divU
        divU = mg.soln_grid.scratch_array()

        divU[mg.ilo:mg.ihi+1,mg.jlo:mg.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

        # solve L phi = DU

        # initialize our guess to the solution, set the RHS to divU and
        # solve
        mg.init_zeros()
        mg.init_RHS(divU)
        mg.solve(rtol=1.e-10)

        # store the solution in our self.cc_data object -- include a single
        # ghostcell
        phi = self.cc_data.get_var("phi")
        solution = mg.get_solution()

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

        # compute the cell-centered gradient of phi and update the
        # velocities
        gradp_x = myg.scratch_array()
        gradp_y = myg.scratch_array()

        gradp_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

        gradp_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

        u[:, :] -= gradp_x
        v[:, :] -= gradp_y

        # fill the ghostcells
        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")

        # 2. now get an approximation to gradp at n-1/2 by going through the
        # evolution.

        # store the current solution -- we'll restore it in a bit
        orig_data = patch.cell_center_data_clone(self.cc_data)

        # get the timestep
        dt = self.timestep()

        # evolve
        self.evolve(dt)

        # update gradp_x and gradp_y in our main data object
        new_gp_x = self.cc_data.get_var("gradp_x")
        new_gp_y = self.cc_data.get_var("gradp_y")

        orig_gp_x = orig_data.get_var("gradp_x")
        orig_gp_y = orig_data.get_var("gradp_y")

        orig_gp_x[:, :] = new_gp_x[:, :]
        orig_gp_y[:, :] = new_gp_y[:, :]

        self.cc_data = orig_data

        print("done with the pre-evolution")
Exemplo n.º 12
0
def preevolve(my_data):
    """ 
    preevolve is called before we being the timestepping loop.  For
    the incompressible solver, this does an initial projection on the
    velocity field and then goes through the full evolution to get the
    value of phi.  The fluid state (u, v) is then reset to values
    before this evolve.
    """

    myg = my_data.grid

    u = my_data.get_var("x-velocity")
    v = my_data.get_var("y-velocity")

    my_data.fill_BC("x-velocity")
    my_data.fill_BC("y-velocity")


    # 1. do the initial projection.  This makes sure that our original
    # velocity field satisties div U = 0

    # next create the multigrid object.  We want Neumann BCs on phi
    # at solid walls and periodic on phi for periodic BCs
    MG = multigrid.CellCenterMG2d(myg.nx, myg.ny,
                                  xl_BC_type="periodic", xr_BC_type="periodic",
                                  yl_BC_type="periodic", yr_BC_type="periodic",
                                  xmin=myg.xmin, xmax=myg.xmax,
                                  ymin=myg.ymin, ymax=myg.ymax,
                                  verbose=0)

    # first compute divU
    divU = MG.soln_grid.scratch_array()

    divU[MG.ilo:MG.ihi+1,MG.jlo:MG.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


    # solve L phi = DU

    # initialize our guess to the solution
    MG.init_zeros()

    # setup the RHS of our Poisson equation
    MG.init_RHS(divU)

    # solve
    MG.solve(rtol=1.e-10)

    # store the solution in our my_data object -- include a single
    # ghostcell
    phi = my_data.get_var("phi")
    solution = MG.get_solution()

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

    # compute the cell-centered gradient of phi and update the 
    # velocities
    gradp_x = myg.scratch_array()
    gradp_y = myg.scratch_array()

    gradp_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

    gradp_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

    u[:,:] -= gradp_x
    v[:,:] -= gradp_y

    # fill the ghostcells
    my_data.fill_BC("x-velocity")
    my_data.fill_BC("y-velocity")


    # 2. now get an approximation to gradp at n-1/2 by going through the
    # evolution.

    # store the current solution
    copyData = patch.cell_center_data_clone(my_data)

    # get the timestep
    dt = timestep.timestep(copyData)

    # evolve
    evolve.evolve(copyData, dt)

    # update gradp_x and gradp_y in our main data object
    gp_x = my_data.get_var("gradp_x")
    gp_y = my_data.get_var("gradp_y")

    new_gp_x = copyData.get_var("gradp_x")
    new_gp_y = copyData.get_var("gradp_y")

    gp_x[:,:] = new_gp_x[:,:]
    gp_y[:,:] = new_gp_y[:,:]


    print "done with the pre-evolution"
Exemplo n.º 13
0
    def evolve(self):
        """
        Evolve the equations of compressible hydrodynamics through a
        timestep dt.
        """

        tm_evolve = self.tc.timer("evolve")
        tm_evolve.begin()

        myg = self.cc_data.grid

        myd = self.cc_data

        order = self.rp.get_param("compressible.temporal_order")

        if order == 2:
            # time-integration -- RK2
            myd_nhalf = patch.cell_center_data_clone(myd)

            # initial slopes and n+1/2 state
            k1 = self.substep(myd)
            for n in range(self.vars.nvar):
                var = myd_nhalf.get_var_by_index(n)
                var.v()[:, :] += 0.5 * self.dt * k1.v(n=n)[:, :]

            myd_nhalf.fill_BC_all()

            # updated slopes, starting with the n+1/2 state
            k2 = self.substep(myd_nhalf)

            # final update
            for n in range(self.vars.nvar):
                var = myd.get_var_by_index(n)
                var.v()[:, :] += self.dt * k2.v(n=n)[:, :]

        elif order == 4:

            # time-integration -- RK4

            # first slope (k1) is f(U^n)
            k1 = self.substep(myd)

            # second slope (k2) is f(U^n + 0.5*dt*k1)
            myd1 = patch.cell_center_data_clone(myd)
            for n in range(self.vars.nvar):
                var = myd1.get_var_by_index(n)
                var.v()[:, :] += 0.5 * self.dt * k1.v(n=n)[:, :]

            myd1.fill_BC_all()
            k2 = self.substep(myd1)

            # third slope (k3) is f(U^n + 0.5*dt*k2)
            myd2 = patch.cell_center_data_clone(myd)
            for n in range(self.vars.nvar):
                var = myd2.get_var_by_index(n)
                var.v()[:, :] += 0.5 * self.dt * k2.v(n=n)[:, :]

            myd2.fill_BC_all()
            k3 = self.substep(myd2)

            # last slope (k4) is f(U^n + dt*k3)
            myd3 = patch.cell_center_data_clone(myd)
            for n in range(self.vars.nvar):
                var = myd3.get_var_by_index(n)
                var.v()[:, :] += self.dt * k3.v(n=n)[:, :]

            myd3.fill_BC_all()
            k4 = self.substep(myd3)

            # final update
            for n in range(self.vars.nvar):
                var = myd.get_var_by_index(n)
                var.v()[:, :] += (
                    self.dt / 6.0) * (k1.v(n=n)[:, :] + 2.0 * k2.v(n=n)[:, :] +
                                      2.0 * k3.v(n=n)[:, :] + k4.v(n=n)[:, :])

        # increment the time
        myd.t += self.dt
        self.n += 1

        tm_evolve.end()
Exemplo n.º 14
0
    def preevolve(self):
        """ 
        preevolve is called before we being the timestepping loop.  For
        the incompressible solver, this does an initial projection on the
        velocity field and then goes through the full evolution to get the
        value of phi.  The fluid state (u, v) is then reset to values
        before this evolve.
        """
        
        myg = self.cc_data.grid

        u = self.cc_data.get_var("x-velocity")
        v = self.cc_data.get_var("y-velocity")

        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")


        # 1. do the initial projection.  This makes sure that our original
        # velocity field satisties div U = 0

        # next create the multigrid object.  We defined phi with
        # the right BCs previously
        mg = MG.CellCenterMG2d(myg.nx, myg.ny,
                               xl_BC_type=self.cc_data.BCs["phi"].xlb, 
                               xr_BC_type=self.cc_data.BCs["phi"].xrb,
                               yl_BC_type=self.cc_data.BCs["phi"].ylb, 
                               yr_BC_type=self.cc_data.BCs["phi"].yrb,
                               xmin=myg.xmin, xmax=myg.xmax,
                               ymin=myg.ymin, ymax=myg.ymax,
                               verbose=0)

        # first compute divU
        divU = mg.soln_grid.scratch_array()

        divU[mg.ilo:mg.ihi+1,mg.jlo:mg.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

        # solve L phi = DU

        # initialize our guess to the solution, set the RHS to divU and
        # solve
        mg.init_zeros()
        mg.init_RHS(divU)
        mg.solve(rtol=1.e-10)

        # store the solution in our self.cc_data object -- include a single
        # ghostcell
        phi = self.cc_data.get_var("phi")
        solution = mg.get_solution()

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

        # compute the cell-centered gradient of phi and update the 
        # velocities
        gradp_x = myg.scratch_array()
        gradp_y = myg.scratch_array()

        gradp_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

        gradp_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

        u[:,:] -= gradp_x
        v[:,:] -= gradp_y

        # fill the ghostcells
        self.cc_data.fill_BC("x-velocity")
        self.cc_data.fill_BC("y-velocity")


        # 2. now get an approximation to gradp at n-1/2 by going through the
        # evolution.

        # store the current solution -- we'll restore it in a bit
        orig_data = patch.cell_center_data_clone(self.cc_data)

        # get the timestep
        dt = self.timestep()

        # evolve
        self.evolve(dt)

        # update gradp_x and gradp_y in our main data object
        new_gp_x = self.cc_data.get_var("gradp_x")
        new_gp_y = self.cc_data.get_var("gradp_y")

        orig_gp_x = orig_data.get_var("gradp_x")
        orig_gp_y = orig_data.get_var("gradp_y")

        orig_gp_x[:,:] = new_gp_x[:,:]
        orig_gp_y[:,:] = new_gp_y[:,:]

        self.cc_data = orig_data

        print("done with the pre-evolution")