def main(gui): # Constants l = 10 # domain length a = 3. # advection velocity n = 3 # number of elements p = 4 # order of discretization v = ['u', 'v'] # physical variables cfl = 1 / (2*p+1) # max. Courant-Friedrichs-Levy for stability # Functions def initial(x, t): return 0.0 def funa(x, t): return np.sin(2*np.pi*(x-a*t)/l*2) def funb(x, t): return np.sin(2*np.pi*(x+a*t)/l*2) funs = [funa, funb] if gui: gui.vars = v gui.frefs = funs # Parameters dx = l / n # cell length dt = cfl * dx / a # time step tmax = round(l / a, 5) # simulation time (l/a) # Generate mesh msh = lmsh.run(l, n) fld = msh.groups[0] # field inl = msh.groups[1] # inlet oul = msh.groups[2] # outlet # Generate formulation pflx = pfl.Advection2(a, -a) # physical transport flux ic = numc.Initial(fld, [initial, initial]) # initial condition inlet = numc.Boundary(inl, [numc.Dirichlet(funa), numc.Neumann()]) # inlet bc outlet = numc.Boundary(oul, [numc.Neumann(), numc.Dirichlet(funb)]) # outlet bc formul = numf.Formulation(msh, fld, len(v), pflx, ic, [inlet, outlet]) # Generate discretization nflx = nfl.LaxFried(pflx, 0.) # Lax–Friedrichs flux (0: full-upwind, 1: central) disc = numd.Discretization(formul, p, nflx) # Define time integration method wrt = wrtr.Writer('sol', 1, v, disc) tint = numt.SspRk4(disc, wrt, gui) tint.run(dt, tmax) # Test uexact = [[] for _ in range(len(v))] # exact solution at element eval point ucomp = [[] for _ in range(len(v))] # computed solution at element eval point for c,e in disc.elements.items(): xe = e.evalx() for j in range(len(v)): for i in range(len(xe)): uexact[j].append(funs[j](xe[i], tint.t)) ucomp[j].append(tint.u[e.rows[j][i]]) maxdiff = [] # infinite norm nrmdiff = [] # Frobenius norm for j in range(len(v)): maxdiff.append(np.max(np.abs(np.array(ucomp[j]) - np.array(uexact[j])))) nrmdiff.append(np.linalg.norm(np.array(ucomp[j]) - np.array(uexact[j]))) tests = tst.Tests() tests.add(tst.Test('Max(u-u_exact)', maxdiff[0], 0., 3e-1)) tests.add(tst.Test('Norm(u-u_exact)', nrmdiff[0], 0., 3e-1)) tests.add(tst.Test('Max(v-v_exact)', maxdiff[1], 0., 3e-1)) tests.add(tst.Test('Norm(v-v_exact)', nrmdiff[1], 0., 3e-1)) tests.run()
def main(gui): # Constants l = 400 # domain length g = 9.81 # acceleration due to gravity h = [1.0, 0.01] # steady state water height w = [0.1, 20] # height and width of initial wave z = [20, 100] # bed slope initial and final position n = 50 # number of elements p = 6 # order of discretization v = ['h', 'u'] # physical variables cfl = 1 / (2*p+1) # half of max. Courant-Friedrichs-Levy for stability # Functions # bed def zb(x): if x < l/2 + z[0]: return 0. elif x < l/2 + z[1]: return 0.5 * (h[0]-h[1]) * (1 - np.cos(np.pi/(z[1]-z[0]) * (x-l/2-z[0]))) else: return h[0] - h[1] # source term function (bed slope * g) def gdzb(x): if x >= l/2 + z[0] and x < l/2 + z[1]: return g * 0.5 * np.pi * (h[0]-h[1])/(z[1]-z[0]) * np.sin(np.pi/(z[1]-z[0])*(x-l/2-z[0])) else: return 0. # initial and boundary conditions def h0(x, t): return h[0] + w[0] * np.cos(0.5*np.pi/w[1]*(x-l/2)) - zb(x) if abs(x-l/2) < w[1] else h[0] - zb(x) def u0(x, t): return 0.0 def hl(x, t): return h[0] - zb(x) def ul(x, t): return 0.0 # reference solutions def rfunh(x, t): if x < 116: return h[0] elif x < 160: return -0.0001*x*x + 0.0272*x - 0.7985 elif x < 220: return h[0] elif x < 272: return -0.000192559021192277*x*x + 0.0810028508376352*x - 7.48640208379703 elif x < 300: return 0.000308903323667424*x*x - 0.186483075379383*x + 28.1505055888591 else: return h[1] def rfunu(x, t): if x < 116: return 0. elif x < 156: return 0.000353056759525554*x*x - 0.0955691190357186*x + 6.32071941182482 elif x < 245: return -1.12067281188971e-06*x*x + 0.000289440705269957*x - 0.0167770084481066 elif x < 264: return -3.37962520178778e-05*x*x + 0.0300418744173713*x - 5.31085043131794 elif x < 272: return -0.00755364567412781*x*x + 4.01701626023094*x - 533.785818827200 else: return 0. funs = [rfunh, rfunu] if gui: gui.vars = v gui.frefs = funs # Parameters dx = l / n # cell length dt = cfl * dx / (0.5 + np.sqrt(g*h[0])) # time step tmax = 20 # simulation time (l/a) # Generate mesh msh = lmsh.run(l, n) fld = msh.groups[0] # field inl = msh.groups[1] # inlet oul = msh.groups[2] # outlet # Generate formulation pflx = pfl.ShallowWater(g) # physical transport flux ic = numc.Initial(fld, [h0, u0]) # initial condition left = numc.Boundary(inl, [numc.Dirichlet(hl), numc.Dirichlet(ul)]) # left bc right = numc.Boundary(oul, [numc.Dirichlet(hl), numc.Dirichlet(ul)]) # right bc formul = numf.Formulation(msh, fld, len(v), pflx, ic, [left, right], nsrc.Source([lambda x: 0., gdzb])) # Generate discretization nflx = nfl.LaxFried(pflx, 0.) # Lax–Friedrichs flux (0: full-upwind, 1: central) disc = numd.Discretization(formul, p, nflx) # Define time integration method wrt = wrtr.Writer('sol', 1, v, disc) tint = numt.SspRk4(disc, wrt, gui) tint.run(dt, tmax) # Test uexact = [[] for _ in range(len(v))] # exact solution at element eval point ucomp = [[] for _ in range(len(v))] # computed solution at element eval point for c,e in disc.elements.items(): xe = e.evalx() for j in range(len(v)): for i in range(len(xe)): uexact[j].append(funs[j](xe[i], tint.t)) ucomp[j].append(tint.u[e.rows[j][i]]) maxdiff = [] # infinite norm nrmdiff = [] # Frobenius norm for j in range(len(v)): maxdiff.append(np.max(np.abs(np.array(ucomp[j]) - np.array(uexact[j])))) nrmdiff.append(np.linalg.norm(np.array(ucomp[j]) - np.array(uexact[j]))) tests = tst.Tests() tests.add(tst.Test('Max(h-h_exact)', maxdiff[0], 0., 1e-1)) tests.add(tst.Test('Norm(h-h_exact)', nrmdiff[0], 0., 1e-1)) tests.add(tst.Test('Max(u-u_exact)', maxdiff[1], 0., 1e-1)) tests.add(tst.Test('Norm(u-u_exact)', nrmdiff[1], 0., 1e-1)) tests.run()
def main(gui): # Constants l = 1 # domain length n = 75 # number of elements p = 2 # order of discretization gamma = 1.4 # heat capacity ratio v = ['rho', 'rhou', 'E'] # physical variables cfl = 1 / (2 * p + 1) # max. Courant-Friedrichs-Levy for stability # Functions def fun0(x, t): return 1. if x < l / 2 else 0.125 def fun1(x, t): return 0. def fun2(x, t): return 1. / (gamma - 1) if x < l / 2 else 0.1 / (gamma - 1) def rfun0(x, t): if x < 0.381 * l: return 1. elif x < 0.489 * l: return 15.5391 * x * x - 18.7087 * x + 5.8748 elif x < 0.587 * l: return 0.442 elif x < 0.665 * l: return 0.274 else: return 0.125 def rfun1(x, t): if x < 0.381 * l: return 0. elif x < 0.489 * l: return -36.1960 * x * x + 35.0524 * x - 8.0979 elif x < 0.587 * l: return 0.394 elif x < 0.665 * l: return 0.244 else: return 0. def rfun2(x, t): if x < 0.381 * l: return 2.5 elif x < 0.489 * l: return 50.3024 * x * x - 58.8475 * x + 17.6300 elif x < 0.587 * l: return 0.885 elif x < 0.665 * l: return 0.831 else: return 0.25 funs = [rfun0, rfun1, rfun2] if gui: gui.vars = v gui.frefs = funs # Parameters dx = l / n # cell length dt = cfl * dx / 1.0 # time step tmax = 0.1 # simulation time # Generate mesh and get groups msh = lmsh.run(l, n) fld = msh.groups[0] # field inl = msh.groups[1] # inlet oul = msh.groups[2] # outlet # Generate formulation pflx = pfl.Euler(gamma) # physical Euler flux ic = numc.Initial(fld, [fun0, fun1, fun2]) # initial condition dbcs = [numc.Dirichlet(fun0), numc.Dirichlet(fun1), numc.Dirichlet(fun2)] # Dirichlet BCs bcs = [numc.Boundary(inl, dbcs), numc.Boundary(oul, dbcs)] # inlet-outlet bc formul = numf.Formulation(msh, fld, len(v), pflx, ic, bcs) # Generate discretization nflx = nfl.LaxFried(pflx, 0.) # Lax–Friedrichs flux (0: full-upwind, 1: central) disc = numd.Discretization(formul, p, nflx) # Define time integration method wrt = wrtr.Writer('sol', 1, v, disc) tint = numt.SspRk4(disc, wrt, gui) tint.run(dt, tmax) # Test uexact = [[] for _ in range(len(v))] # exact solution at element eval point ucomp = [[] for _ in range(len(v))] # computed solution at element eval point for c, e in disc.elements.items(): xe = e.evalx() for j in range(len(v)): for i in range(len(xe)): uexact[j].append(funs[j](xe[i], tint.t)) ucomp[j].append(tint.u[e.rows[j][i]]) maxdiff = [] # infinite norm nrmdiff = [] # Frobenius norm for j in range(len(v)): maxdiff.append(np.max(np.abs(np.array(ucomp[j]) - np.array(uexact[j])))) nrmdiff.append( np.linalg.norm(np.array(ucomp[j]) - np.array(uexact[j]))) tests = tst.Tests() tests.add(tst.Test('Max(rho-rho_exact)', maxdiff[0], 0., 2e-1)) tests.add(tst.Test('Norm(rho-rho_exact)', nrmdiff[0], 0., 5e-1)) tests.add(tst.Test('Max(rhou-rhou_exact)', maxdiff[1], 0., 4e-1)) tests.add(tst.Test('Norm(rhou-rhou_exact)', nrmdiff[1], 0., 5e-1)) tests.add(tst.Test('Max(E-E_exact)', maxdiff[2], 0., 9e-1)) tests.add(tst.Test('Norm(E-E_exact)', nrmdiff[2], 0., 2e-0)) tests.run()
def main(gui): # Constants l = 10 # domain length n = 3 # number of elements p = 5 # order of discretization u1 = 1.0 # in-out velocity v = ['u'] # physical variables cfl = 0.5 * 1 / (2 * p + 1 ) # half of max. Courant-Friedrichs-Levy for stability # Functions def initial(x, t): return -u1 * np.sign(x - l / 2) if np.abs( x - l / 2) > l / n else -n * u1 / l * (x - l / 2) def inout(x, t): return -u1 * np.sign(x - l / 2) def fun(x, t): return -u1 * np.sign(x - l / 2) if gui: gui.vars = v gui.frefs = [fun] # Parameters dx = l / n # cell length dt = cfl * dx / abs(u1) # time step tmax = 5.0 # simulation time # Generate mesh and get groups msh = lmsh.run(l, n) fld = msh.groups[0] # field inl = msh.groups[1] # inlet oul = msh.groups[2] # outlet # Generate formulation pflx = pfl.Burger() # physical Burger's flux ic = numc.Initial(fld, [initial]) # initial condition dbc = [numc.Dirichlet(inout)] # Dirichlet BC bcs = [numc.Boundary(inl, dbc), numc.Boundary(oul, dbc)] # inlet-outlet bc formul = numf.Formulation(msh, fld, len(v), pflx, ic, bcs) # Generate discretization nflx = nfl.LaxFried(pflx, 0.) # Lax–Friedrichs flux (0: full-upwind, 1: central) disc = numd.Discretization(formul, p, nflx) # Define time integration method wrt = wrtr.Writer('sol', 1, v, disc) tint = numt.Rk4(disc, wrt, gui) tint.run(dt, tmax) # Test uexact = [] # exact solution at element eval point for c, e in disc.elements.items(): xe = e.evalx() for i in range(len(xe)): ue = fun(xe[i], tint.t) uexact.append(ue) maxdiff = np.max(np.abs(tint.u - np.array(uexact))) # infinite norm nrmdiff = np.linalg.norm(tint.u - np.array(uexact)) # Frobenius norm tests = tst.Tests() tests.add(tst.Test('Max(u-u_exact)', maxdiff, 0., 1e-1)) tests.add(tst.Test('Norm(u-u_exact)', nrmdiff, 0., 1e-1)) tests.run()