def test_domain_with_fluid_rectangle(self): fname = 'fluid_rectangle.npz' dom2d = copy.deepcopy(self.dom2d) dom2d['elements'] = [ pylbm.Parallelogram([0., 0.], [1., 0], [0., 2.], label=20), pylbm.Parallelogram([0.23, 0.73], [0.5, 0], [0., .5], label=10, isfluid=True) ] dom = pylbm.Domain(dom2d) check_from_file(dom, fname)
def get_dictionary(self): def init_rho(x, y): #stepMask = (x >= self.xmin+self.step_xmin) * (y <= self.ymin+self.step_ymax) #return stepMask * 0. + np.logical_not(stepMask) * self.rho_in return self.rho_in def init_ux(x, y): #stepMask = (x >= self.xmin+self.step_xmin) * (y <= self.ymin+self.step_ymax) #return stepMask * 0. + np.logical_not(stepMask) * self.ux_in return self.ux_in def init_uy(x, y): #stepMask = (x >= self.xmin+self.step_xmin) * (y <= self.ymin+self.step_ymax) #return stepMask * 0. + np.logical_not(stepMask) * self.uy_in return self.uy_in def init_p(x, y): #stepMask = (x >= self.xmin+self.step_xmin) * (y <= self.ymin+self.step_ymax) #return stepMask * 0. + np.logical_not(stepMask) * self.p_in return self.p_in def init_qx(x, y): return init_rho(x, y) * init_ux(x, y) def init_qy(x, y): return init_rho(x, y) * init_uy(x, y) def init_E(x, y): return .5 * init_rho(x, y) * (init_ux(x, y)**2 + init_uy(x, y)** 2) + init_p(x, y) / (self.gamma - 1) BC_labels = [1, 1, 4, 4] step_BC_labels = [3, 3, 4, 4] return { 'box': { 'x': [self.xmin, self.xmax], 'y': [self.ymin, self.ymax], 'label': BC_labels }, 'elements': [ pylbm.Parallelogram((self.xmin + self.step_xmin, self.ymin), (self.xmax, self.ymin), (self.xmin, self.ymin + self.step_ymax), label=step_BC_labels) ], 'init': { self.equation.rho: init_rho, self.equation.qx: init_qx, self.equation.qy: init_qy, self.equation.E: init_E, }, 'parameters': { self.equation.gamma: self.gamma } }
# Benjamin Graille <*****@*****.**> # # License: BSD 3 clause """ Example of a square in 2D with a cavity """ import pylbm D_DOM = { 'box': { 'x': [0, 1], 'y': [0, 1], 'label': 0 }, 'elements': [ pylbm.Parallelogram((0.4, 0.3), (0, 0.4), (0.2, 0), label=1), pylbm.Circle((0.4, 0.5), 0.2, label=3), pylbm.Circle((0.6, 0.5), 0.2, label=3), pylbm.Parallelogram((0.45, 0.3), (0, 0.4), (0.1, 0), label=2, isfluid=True), ], 'space_step': 0.025, 'schemes': [{ 'velocities': list(range(9)) }], } DOMAIN = pylbm.Domain(D_DOM) print(DOMAIN) DOMAIN.visualize(view_distance=True,
# Authors: # Loic Gouarin <*****@*****.**> # Benjamin Graille <*****@*****.**> # # License: BSD 3 clause """ Example of the backward facing step in 2D """ import pylbm D_DOM = { 'box': { 'x': [0, 3], 'y': [0, 1], 'label': [0, 1, 0, 2] }, 'elements': [pylbm.Parallelogram((0., 0.), (.5, 0.), (0., .5), label=0)], 'space_step': 0.125, 'schemes': [{ 'velocities': list(range(9)) }], } DOMAIN = pylbm.Domain(D_DOM) print(DOMAIN) DOMAIN.visualize() DOMAIN.visualize(view_distance=True, view_normal=True)
def run(space_step, final_time, generator="cython", sorder=None, with_plot=True): """ Parameters ---------- space_step: double spatial step final_time: double final time generator: string pylbm generator sorder: list storage order with_plot: boolean if True plot the solution otherwise just compute the solution Returns ------- sol <class 'pylbm.simulation.Simulation'> """ # parameters scheme_name = 'Geier' xmin, xmax, ymin, ymax = 0., 4., 0., 0.5 # bounds of the domain width = 0.25 # radius of the obstacle la = 1. # velocity of the scheme rho_o = 1. # reference value of the mass u_o = 0.10 # boundary value of the velocity mu = 2.5e-7 # bulk viscosity zeta = 1.e-3 # shear viscosity def moments_choice(scheme_name, mu, zeta): if scheme_name == 'dHumiere': dummy = 1. / rho_o QX2 = dummy * QX**2 QY2 = dummy * QY**2 Q2 = QX2 + QY2 QXY = dummy * QX * QY polynomials = [ 1, X, Y, 3 * (X**2 + Y**2) - 4 * LA**2, 0.5 * (9 * (X**2 + Y**2)**2 - 21 * (X**2 + Y**2) * LA**2 + 8 * LA**4), 3 * X * (X**2 + Y**2) - 5 * X * LA**2, 3 * Y * (X**2 + Y**2) - 5 * Y * LA**2, X**2 - Y**2, X * Y ] equilibrium = [ RHO, QX, QY, -2 * RHO * LA**2 + 3 * Q2, RHO * LA**2 - 3 * Q2, -QX * LA**2, -QY * LA**2, QX2 - QY2, QXY ] dummy = 3.0 / (la * rho_o * space_step) sigma_1 = dummy * zeta sigma_2 = dummy * mu s_1 = 1 / (.5 + sigma_1) s_2 = 1 / (.5 + sigma_2) if scheme_name == 'Geier': UX, UY = QX / RHO, QY / RHO RHOU2 = RHO * (UX**2 + UY**2) polynomials = [ 1, X, Y, X**2 + Y**2, X * Y**2, Y * X**2, X**2 * Y**2, X**2 - Y**2, X * Y, ] equilibrium = [ RHO, QX, QY, RHOU2 + 2 / 3 * RHO * LA**2, QX * (LA**2 / 3 + UY**2), QY * (LA**2 / 3 + UX**2), RHO * (LA**2 / 3 + UX**2) * (LA**2 / 3 + UY**2), RHO * (UX**2 - UY**2), RHO * UX * UY, ] dummy = 3.0 / (la * rho_o * space_step) sigma_1 = dummy * (zeta - 2 * mu / 3) sigma_2 = dummy * mu s_1 = 1 / (.5 + sigma_1) s_2 = 1 / (.5 + sigma_2) if scheme_name == 'Lallemand': dummy = 1. / rho_o QX2 = dummy * QX**2 QY2 = dummy * QY**2 Q2 = QX2 + QY2 QXY = dummy * QX * QY polynomials = [ 1, X, Y, X**2 + Y**2, X * (X**2 + Y**2), Y * (X**2 + Y**2), (X**2 + Y**2)**2, X**2 - Y**2, X * Y, ] equilibrium = [ RHO, QX, QY, Q2 + 2 / 3 * LA**2 * RHO, 4 / 3 * QX * LA**2, 4 / 3 * QY * LA**2, ((21 * Q2 + 6 * RHO * LA**2) * LA**2 - (6 * Q2 - 2 * RHO * LA**2)) / 9, QX2 - QY2, QXY, ] dummy = 3.0 / (la * rho_o * space_step) sigma_1 = dummy * zeta sigma_2 = dummy * mu s_1 = 1 / (.5 + sigma_1) s_2 = 1 / (.5 + sigma_2) s = [0., 0., 0., s_1, s_1, s_1, s_1, s_2, s_2] return polynomials, equilibrium, s polynomials, equilibrium, s = moments_choice(scheme_name, mu, zeta) simu_cfg = { 'box': { 'x': [xmin, xmax], 'y': [ymin, ymax], 'label': [2, 1, 0, 0] }, 'elements': [pylbm.Parallelogram((xmin, ymin), (width, 0), (0, width), label=0)], 'space_step': space_step, 'scheme_velocity': la, 'schemes': [ { 'velocities': list(range(9)), 'polynomials': polynomials, 'relaxation_parameters': s, 'equilibrium': equilibrium, 'conserved_moments': [RHO, QX, QY], }, ], 'parameters': { LA: la }, 'init': { RHO: rho_o, QX: 0., QY: 0. }, 'boundary_conditions': { 0: { 'method': { 0: pylbm.bc.BouzidiBounceBack } }, 1: { 'method': { 0: pylbm.bc.NeumannX } }, 2: { 'method': { 0: pylbm.bc.BouzidiBounceBack }, 'value': (bc_in, (rho_o, u_o, width, ymax)) }, }, 'generator': generator, 'relative_velocity': [QX / RHO, QY / RHO], # 'show_code': True } sol = pylbm.Simulation(simu_cfg, sorder=sorder) if with_plot: Re = rho_o * u_o * 2 * width / mu print("Reynolds number {0:10.3e}".format(Re)) # init viewer viewer = pylbm.viewer.matplotlib_viewer fig = viewer.Fig(3, 1) ax_qx = fig[0] ax_qx.grid(visible=False) ax_qx.xaxis_set_visible(False) ax_qx.yaxis_set_visible(False) ax_qx.title = r"$u_x$ at $t={0:f}$".format(sol.t) ax_qy = fig[1] ax_qy.grid(visible=False) ax_qy.xaxis_set_visible(False) ax_qy.yaxis_set_visible(False) ax_qy.title = r"$u_y$" ax_v = fig[2] ax_v.grid(visible=False) ax_v.xaxis_set_visible(False) ax_v.yaxis_set_visible(False) ax_v.title = "vorticity" length = width / space_step ax_qx.polygon([[0, 0], [0, length], [length, length], [length, 0]], 'black') ax_qy.polygon([[0, 0], [0, length], [length, length], [length, 0]], 'black') ax_v.polygon([[0, 0], [0, length - 1], [length - 1, length - 1], [length - 1, 0]], 'black') surf_qx = ax_qx.SurfaceImage(sol.m[QX] / sol.m[RHO], cmap='jet', clim=[-u_o, u_o]) surf_qy = ax_qy.SurfaceImage(sol.m[QY] / sol.m[RHO], cmap='jet', clim=[-u_o, u_o]) surf_v = ax_v.SurfaceImage(vorticity(sol), cmap='jet', clim=[0, 0.025]) def update(iframe): # pylint: disable=unused-argument nrep = 64 for _ in range(nrep): sol.one_time_step() surf_qx.update(sol.m[QX] / sol.m[RHO]) surf_qy.update(sol.m[QY] / sol.m[RHO]) surf_v.update(vorticity(sol)) ax_qx.title = r"$u_x$ at $t={0:f}$".format(sol.t) # run the simulation fig.animate(update, interval=1) fig.show() else: while sol.t < final_time: sol.one_time_step() return sol
def run(dx, Tf, generator="cython", sorder=None, withPlot=True): """ Parameters ---------- dx: double spatial step Tf: double final time generator: pylbm generator sorder: list storage order withPlot: boolean if True plot the solution otherwise just compute the solution """ # parameters xmin, xmax, ymin, ymax = 0., 1., 0., 1 rayon = 0.25 * (xmax - xmin) la = 1. # velocity of the scheme rhoo = 1. uo = 0.05 mu = 2.5e-5 #0.00185 zeta = 10 * mu dummy = 3.0 / (la * rhoo * dx) s3 = 1.0 / (0.5 + zeta * dummy) s4 = s3 s5 = s4 s6 = s4 s7 = 1.0 / (0.5 + mu * dummy) s8 = s7 s = [0., 0., 0., s3, s4, s5, s6, s7, s8] dummy = 1. / (LA**2 * rhoo) qx2 = dummy * qx**2 qy2 = dummy * qy**2 q2 = qx2 + qy2 qxy = dummy * qx * qy xc = xmin + 0.75 * (xmax - xmin) yc = ymin + 0.75 * (ymax - ymin) dico = { 'box': { 'x': [xmin, xmax], 'y': [ymin, ymax], 'label': [2, 0, 1, 0] }, 'elements': [pylbm.Parallelogram((xmin, ymin), (xc, ymin), (xmin, yc), label=0)], 'scheme_velocity': la, 'space_step': dx, 'schemes': [{ 'velocities': list(range(9)), 'polynomials': [ 1, X, Y, 3 * (X**2 + Y**2) - 4, 0.5 * (9 * (X**2 + Y**2)**2 - 21 * (X**2 + Y**2) + 8), 3 * X * (X**2 + Y**2) - 5 * X, 3 * Y * (X**2 + Y**2) - 5 * Y, X**2 - Y**2, X * Y ], 'relaxation_parameters': s, 'equilibrium': [ rho, qx, qy, -2 * rho + 3 * q2, rho - 3 * q2, -qx, -qy, qx2 - qy2, qxy ], 'conserved_moments': [rho, qx, qy], 'init': { rho: rhoo, qx: 0., qy: 0. }, }], 'boundary_conditions': { 0: { 'method': { 0: pylbm.bc.BouzidiBounceBack } }, 1: { 'method': { 0: pylbm.bc.NeumannY } }, 2: { 'method': { 0: pylbm.bc.BouzidiBounceBack }, 'value': (bc_in, (rhoo, uo, ymin, ymax)) } }, 'generator': generator, 'parameters': { LA: la }, # 'show_code': True } sol = pylbm.Simulation(dico, sorder=sorder) if withPlot: # init viewer viewer = pylbm.viewer.matplotlib_viewer fig = viewer.Fig() ax = fig[0] image = ax.image(norme_q, (sol, ), cmap='jet', clim=[0, uo**2]) ax.polygon([[xmin / dx, ymin / dx], [xmin / dx, yc / dx], [xc / dx, yc / dx], [xc / dx, ymin / dx]], 'k') def update(iframe): nrep = 64 for i in range(nrep): sol.one_time_step() image.set_data(norme_q(sol)) ax.title = "Solution t={0:f}".format(sol.t) # run the simulation fig.animate(update, interval=1) fig.show() else: while sol.t < Tf: sol.one_time_step() return sol
# Loic Gouarin <*****@*****.**> # Benjamin Graille <*****@*****.**> # # License: BSD 3 clause """ pylbm: tests for the geometry """ import pytest import pylbm ELEMENTS = [ [2, pylbm.Circle([0, 0], 1)], [2, pylbm.Ellipse([0, 0], [1, 0], [0, 1])], [2, pylbm.Triangle([-1, -1], [0, 2], [2, 0])], [2, pylbm.Parallelogram([-1, -1], [0, 2], [2, 0])], [3, pylbm.CylinderCircle([0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1])], [3, pylbm.CylinderEllipse([0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1])], [3, pylbm.CylinderTriangle([0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1])], [3, pylbm.Parallelepiped([-1, -1, -1], [2, 0, 0], [0, 2, 0], [0, 0, 2])], [3, pylbm.Ellipsoid([0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1])], [3, pylbm.Sphere([0, 0, 0], 1)], ] @pytest.fixture(params=ELEMENTS, ids=[elem[1].__class__.__name__ for elem in ELEMENTS]) def get_element(request): """get one element of the geometry""" return request.param
# Authors: # Loic Gouarin <*****@*****.**> # Benjamin Graille <*****@*****.**> # # License: BSD 3 clause """ Example of a complex geometry in 2D """ import pylbm square = pylbm.Parallelogram((.1, .1), (.8, 0), (0, .8), isfluid=False) strip = pylbm.Parallelogram((0, .4), (1, 0), (0, .2), isfluid=True) circle = pylbm.Circle((.5, .5), .25, isfluid=True) inner_square = pylbm.Parallelogram((.4, .5), (.1, .1), (.1, -.1), isfluid=False) d = {'box':{'x': [0, 1], 'y': [0, 1], 'label':0}, 'elements':[square, strip, circle, inner_square], } g = pylbm.Geometry(d) g.visualize() # rounded inner angles g.add_elem(pylbm.Parallelogram((0.1, 0.9), (0.05, 0), (0, -0.05), isfluid=True)) g.add_elem(pylbm.Circle((0.15, 0.85), 0.05, isfluid=False)) g.add_elem(pylbm.Parallelogram((0.1, 0.1), (0.05, 0), (0, 0.05), isfluid=True)) g.add_elem(pylbm.Circle((0.15, 0.15), 0.05, isfluid=False)) g.add_elem(pylbm.Parallelogram((0.9, 0.9), (-0.05, 0), (0, -0.05), isfluid=True)) g.add_elem(pylbm.Circle((0.85, 0.85), 0.05, isfluid=False)) g.add_elem(pylbm.Parallelogram((0.9, 0.1), (-0.05, 0), (0, 0.05), isfluid=True)) g.add_elem(pylbm.Circle((0.85, 0.15), 0.05, isfluid=False)) g.visualize()
# Authors: # Loic Gouarin <*****@*****.**> # Benjamin Graille <*****@*****.**> # # License: BSD 3 clause """ Example of the backward facing step in 2D """ from six.moves import range import pylbm # pylint: disable=invalid-name ddom = { 'box': {'x': [0, 3], 'y': [0, 1], 'label': [0, 1, 0, 2]}, 'elements': [ pylbm.Parallelogram((0., 0.), (.5, 0.), (0., .5), label=0) ], 'space_step': 0.125, 'schemes': [ { 'velocities': list(range(9)) } ], } dom = pylbm.Domain(ddom) print(dom) dom.visualize() dom.visualize(view_distance=True)
a = .5 skappa = 1. / (.5 + 10 * kappa / (4 + a)) #skappa = 1./(.5+np.sqrt(3)/6) se = 1. / (.5 + np.sqrt(3) / 3) snu = se sT = [0., skappa, skappa, se, snu] #print sT dico = { 'box': { 'x': [xmin, xmax], 'y': [ymin, ymax], 'label': [1, 2, 0, 0] }, 'elements': [ pylbm.Parallelogram([xmin, ymin], [.1, 0], [0, .8], label=0), pylbm.Parallelogram([xmax, ymin], [-.1, 0], [0, .8], label=0), ], 'space_step': dx, 'scheme_velocity': la, 'schemes': [ { 'velocities': list(range(9)), 'conserved_moments': [rho, qx, qy], 'polynomials': [ 1, X, Y, 3 * (X**2 + Y**2) - 4, 0.5 * (9 * (X**2 + Y**2)**2 - 21 * (X**2 + Y**2) + 8), 3 * X * (X**2 + Y**2) - 5 * X, 3 * Y * (X**2 + Y**2) - 5 * Y,
# Benjamin Graille <*****@*****.**> # # License: BSD 3 clause """ Example of a square in 2D with a square hole """ import pylbm D_DOM = { 'box': { 'x': [0, 2], 'y': [0, 1], 'label': 0 }, 'elements': [ pylbm.Parallelogram((0.5, 0.3), (0, 0.4), (0.4, 0), label=1), ], 'space_step': 0.1, 'schemes': [{ 'velocities': list(range(13)) }], } DOMAIN = pylbm.Domain(D_DOM) print(DOMAIN) DOMAIN.visualize(scale=1.5) DOMAIN.visualize(view_distance=True, label=None, view_in=True, view_out=True, view_bound=True) DOMAIN.visualize(
def run(dx, Tf, generator="cython", sorder=None, with_plot=True): """ Parameters ---------- dx: double spatial step Tf: double final time generator: pylbm generator sorder: list storage order with_plot: boolean if True plot the solution otherwise just compute the solution """ # parameters T0 = .5 Tin = -.5 xmin, xmax, ymin, ymax = 0., 1., 0., 1. Ra = 2000 Pr = 0.71 Ma = 0.01 alpha = .005 la = 1. # velocity of the scheme rhoo = 1. g = 9.81 uo = 0.025 nu = np.sqrt(Pr * alpha * 9.81 * (T0 - Tin) * (ymax - ymin) / Ra) kappa = nu / Pr eta = nu #print nu, kappa snu = 1. / (.5 + 3 * nu) seta = 1. / (.5 + 3 * eta) sq = 8 * (2 - snu) / (8 - snu) se = seta sf = [0., 0., 0., seta, se, sq, sq, snu, snu] #print sf a = .5 skappa = 1. / (.5 + 10 * kappa / (4 + a)) #skappa = 1./(.5+np.sqrt(3)/6) se = 1. / (.5 + np.sqrt(3) / 3) snu = se sT = [0., skappa, skappa, se, snu] #print sT dico = { 'box': { 'x': [xmin, xmax], 'y': [ymin, ymax], 'label': [1, 2, 0, 0] }, 'elements': [ pylbm.Parallelogram([xmin, ymin], [.1, 0], [0, .8], label=0), pylbm.Parallelogram([xmax, ymin], [-.1, 0], [0, .8], label=0), ], 'space_step': dx, 'scheme_velocity': la, 'schemes': [ { 'velocities': list(range(9)), 'conserved_moments': [rho, qx, qy], 'polynomials': [ 1, X, Y, 3 * (X**2 + Y**2) - 4, sp.Rational(1, 2) * (9 * (X**2 + Y**2)**2 - 21 * (X**2 + Y**2) + 8), 3 * X * (X**2 + Y**2) - 5 * X, 3 * Y * (X**2 + Y**2) - 5 * Y, X**2 - Y**2, X * Y ], 'relaxation_parameters': sf, 'equilibrium': [ rho, qx, qy, -2 * rho + 3 * (qx**2 + qy**2), rho - 3 * (qx**2 + qy**2), -qx, -qy, qx**2 - qy**2, qx * qy ], 'source_terms': { qy: alpha * g * T }, }, { 'velocities': list(range(5)), 'conserved_moments': T, 'polynomials': [1, X, Y, 5 * (X**2 + Y**2) - 4, (X**2 - Y**2)], 'equilibrium': [T, T * qx, T * qy, a * T, 0.], 'relaxation_parameters': sT, }, ], 'init': { rho: 1., qx: 0., qy: 0., T: (init_T, (T0, )) }, 'boundary_conditions': { 0: { 'method': { 0: pylbm.bc.BouzidiBounceBack, 1: pylbm.bc.BouzidiAntiBounceBack }, 'value': (bc, (T0, )) }, 1: { 'method': { 0: pylbm.bc.BouzidiBounceBack, 1: pylbm.bc.BouzidiAntiBounceBack }, 'value': (bc_in, (T0, Tin, ymax, rhoo, uo)) }, 2: { 'method': { 0: pylbm.bc.NeumannX, 1: pylbm.bc.NeumannX }, }, }, 'generator': generator, } sol = pylbm.Simulation(dico) if with_plot: # create the viewer to plot the solution viewer = pylbm.viewer.matplotlib_viewer fig = viewer.Fig() ax = fig[0] im = ax.image(sol.m[T].transpose(), cmap='jet', clim=[Tin, T0]) ax.title = 'solution at t = {0:f}'.format(sol.t) ax.polygon([[xmin / dx, ymin / dx], [xmin / dx, (ymin + .8) / dx], [(xmin + .1) / dx, (ymin + .8) / dx], [(xmin + .1) / dx, ymin / dx]], 'k') ax.polygon([[ (xmax - .1) / dx, ymin / dx ], [(xmax - .1) / dx, (ymin + .8) / dx], [xmax / dx, (ymin + .8) / dx], [xmax / dx, ymin / dx]], 'k') def update(iframe): nrep = 64 for i in range(nrep): sol.one_time_step() im.set_data(sol.m[T].transpose()) ax.title = 'temperature at t = {0:f}'.format(sol.t) fig.animate(update, interval=1) fig.show() else: while sol.t < Tf: sol.one_time_step() return sol
# Authors: # Loic Gouarin <*****@*****.**> # Benjamin Graille <*****@*****.**> # # License: BSD 3 clause """ Example of a 2D geometry: the backward facing step """ import pylbm dgeom = { 'box': { 'x': [0, 3], 'y': [0, 1], 'label': [0, 1, 2, 3] }, 'elements': [pylbm.Parallelogram((0., 0.), (.5, 0.), (0., .5), label=[4, 5, 6, 7])], } geom = pylbm.Geometry(dgeom) geom.visualize(viewlabel=True)