def evolve(nx, C, tmax, xmax=None): xmin = 0.0 if xmax == None: xmax = 1.0 # create a dummy patch to store some info in the same way the MG # solver will myGrid = patch1d.grid1d(nx, ng=1, xmin=xmin, xmax=xmax) # initialize the data phi = myGrid.scratchArray() # initial solution -- this fills the GC too phi[:] = phi_a(myGrid, 0.0) # time info dt = C * 0.5 * myGrid.dx**2 / k t = 0.0 # evolve while (t < tmax): if (t + dt > tmax): dt = tmax - t # create the multigrid object a = multigrid.ccMG1d(nx, xmin=xmin, xmax=xmax, alpha=1.0, beta=0.5 * dt * k, xlBCtype="neumann", xrBCtype="neumann", verbose=0) # initialize the RHS a.initRHS(phi + 0.5 * dt * k * lap(a.solnGrid, phi)) # initialize the solution to 0 a.initZeros() # solve to a relative tolerance of 1.e-11 a.solve(rtol=1.e-11) # get the solution v = a.getSolution() # store the new solution phi[:] = v[:] t += dt return a.solnGrid, phi
def evolve(nx, C, tmax, xmax=None): xmin = 0.0 if xmax == None: xmax = 1.0 # create a dummy patch to store some info in the same way the MG # solver will myGrid = patch1d.grid1d(nx, ng=1, xmin=xmin, xmax=xmax) # initialize the data phi = myGrid.scratchArray() # initial solution -- this fills the GC too phi[:] = phi_a(myGrid, 0.0) # time info dt = C*0.5*myGrid.dx**2/k t = 0.0 # evolve while (t < tmax): if (t + dt > tmax): dt = tmax - t # create the multigrid object a = multigrid.ccMG1d(nx, xmin=xmin, xmax=xmax, alpha = 1.0, beta = 0.5*dt*k, xlBCtype="neumann", xrBCtype="neumann", verbose=0) # initialize the RHS a.initRHS(phi + 0.5*dt*k*lap(a.solnGrid, phi)) # initialize the solution to 0 a.initZeros() # solve to a relative tolerance of 1.e-11 a.solve(rtol=1.e-11) # get the solution v = a.getSolution() # store the new solution phi[:] = v[:] t += dt return a.solnGrid, phi
def __init__(self, nx, xmin=0.0, xmax=1.0, xlBCtype="dirichlet", xrBCtype="dirichlet", alpha=0.0, beta=-1.0, verbose=0): self.nx = nx self.ng = 1 self.xmin = xmin self.xmax = xmax self.alpha = alpha self.beta = beta self.nsmooth = 10 self.nbottomSmooth = 50 self.maxCycles = 100 self.verbose = verbose # 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 solution self.initializedSolution = 0 self.initializedRHS = 0 # assume that self.nx = 2^(nlevels-1) # this defines nlevels such that we end exactly on a 2 zone 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. i = 0 nx_t = 2 if (self.verbose): print "alpha = ", self.alpha print "beta = ", self.beta while (i < self.nlevels): # create the grid myGrid = patch1d.grid1d(nx_t, ng=self.ng, xmin=xmin, xmax=xmax) # add a ccData2d object for this level to our list self.grids.append(patch1d.ccData1d(myGrid, dtype=numpy.float64)) # create the boundary condition object bcObj = patch1d.bcObject(xlb=xlBCtype, xrb=xrBCtype) self.grids[i].registerVar("v", bcObj) self.grids[i].registerVar("f", bcObj) self.grids[i].registerVar("r", bcObj) self.grids[i].create() if self.verbose: print self.grids[i] nx_t = nx_t * 2 i += 1 # provide coordinate and indexing information for the solution mesh solnGrid = self.grids[self.nlevels - 1].grid self.ilo = solnGrid.ilo self.ihi = solnGrid.ihi self.x = solnGrid.x self.dx = solnGrid.dx self.solnGrid = solnGrid # store the source norm self.sourceNorm = 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.numCycles = 0 self.residualError = 1.e33 self.relativeError = 1.e33