Пример #1
0
 def __call__(self, lhs):
     angle = self.index * self.timestep * self.rotation
     ns = self.ns(lhs=lhs)
     x, u, normu, p = self.plotdomain.elem_eval(
         [ns.x, ns.u, function.norm2(ns.u), ns.p],
         ischeme='bezier9',
         separate=True)
     with plot.PyPlot('flow', index=self.index) as plt:
         plt.axes([0, 0, 1, 1], yticks=[], xticks=[], frame_on=False)
         tri = plt.mesh(x, normu, mergetol=1e-5, cmap='jet')
         plt.clim(0, 1.5)
         plt.tricontour(tri,
                        p,
                        every=self.every,
                        cmap='gray',
                        linestyles='solid',
                        alpha=.8)
         uv = plot.interpolate(tri, self.xy, u)
         plt.vectors(self.xy, uv, zorder=9, pivot='mid', stems=False)
         plt.plot(0,
                  0,
                  'k',
                  marker=(3, 2, angle * 180 / numpy.pi - 90),
                  markersize=20)
         plt.xlim(self.bbox[0])
         plt.ylim(self.bbox[1])
     self.xy = util.regularize(self.bbox, self.spacing,
                               self.xy + uv * self.timestep)
     self.index += 1
Пример #2
0
 def __init__( self, domain, geom, timestep, bbox=((-2,6),(-3,3)), video=False ):
   self.bbox = numpy.asarray(bbox)
   self.plotdomain = domain.select( function.piecewise( geom[0], self.bbox[0], 0, 1, 0 ) * function.piecewise( geom[1], self.bbox[1], 0, 1, 0 ), 'bezier3' )
   self.geom = geom
   self.plt = video and plot.PyPlotVideo( 'flow' )
   self.every = .01
   self.index = 0
   self.timestep = timestep
   self.spacing = .075
   self.xy = util.regularize( self.bbox, self.spacing )
Пример #3
0
 def __call__( self, velo, pres, angle ):
   self.index += 1
   points, velo, flow, pres = self.plotdomain.elem_eval( [ self.geom, velo, function.norm2(velo), pres ], ischeme='bezier9', separate=True )
   with self.plt if self.plt else plot.PyPlot( 'flow', index=self.index ) as plt:
     plt.axes( [0,0,1,1], yticks=[], xticks=[], frame_on=False )
     tri = plt.mesh( points, flow, mergetol=1e-5 )
     plt.clim( 0, 1.5 )
     plt.tricontour( tri, pres, every=self.every, cmap='gray', linestyles='solid', alpha=.8 )
     uv = plot.interpolate( tri, self.xy, velo )
     plt.vectors( self.xy, uv, zorder=9, pivot='mid', stems=False )
     plt.plot( 0, 0, 'k', marker=(3,2,angle*180/numpy.pi-90), markersize=20 )
     plt.xlim( self.bbox[0] )
     plt.ylim( self.bbox[1] )
   self.xy = util.regularize( self.bbox, self.spacing, self.xy + uv * self.timestep )
Пример #4
0
 def __init__(self, domain, ns, timestep, rotation, bbox=((-2,6),(-3,3))):
   self.bbox = numpy.asarray(bbox)
   self.plotdomain = domain.select(function.min(*(ns.x-self.bbox[:,0])*(self.bbox[:,1]-ns.x)), 'bezier3')
   self.ns = ns
   self.every = .01
   self.index = 0
   self.timestep = timestep
   self.rotation = rotation
   self.spacing = .075
   self.xy = util.regularize(self.bbox, self.spacing)
   x = domain.elem_eval(ns.x, ischeme='bezier5', separate=True)
   inflow = domain.boundary['inflow'].elem_eval(ns.x, ischeme='bezier5', separate=True)
   with plot.PyPlot('mesh', ndigits=0) as plt:
     plt.mesh(x)
     plt.rectangle(self.bbox[:,0], *(self.bbox[:,1] - self.bbox[:,0]), ec='green')
     plt.segments(inflow, colors='red')
Пример #5
0
 def __init__(self, domain, ns, timestep, rotation, bbox=((-2,6),(-3,3))):
   self.bbox = numpy.asarray(bbox)
   self.plotdomain = domain.select(function.min(*(ns.x-self.bbox[:,0])*(self.bbox[:,1]-ns.x)), 'bezier3')
   self.ns = ns
   self.every = .01
   self.index = 0
   self.timestep = timestep
   self.rotation = rotation
   self.spacing = .075
   self.xy = util.regularize(self.bbox, self.spacing)
   x = domain.elem_eval(ns.x, ischeme='bezier5', separate=True)
   inflow = domain.boundary['inflow'].elem_eval(ns.x, ischeme='bezier5', separate=True)
   with plot.PyPlot('mesh', ndigits=0) as plt:
     plt.mesh(x)
     plt.rectangle(self.bbox[:,0], *(self.bbox[:,1] - self.bbox[:,0]), ec='green')
     plt.segments(inflow, colors='red')
Пример #6
0
 def __call__(self, lhs):
   angle = self.index * self.timestep * self.rotation
   ns = self.ns(lhs=lhs)
   x, u, normu, p = self.plotdomain.elem_eval([ns.x, ns.u, function.norm2(ns.u), ns.p], ischeme='bezier9', separate=True)
   with plot.PyPlot('flow', index=self.index) as plt:
     plt.axes([0,0,1,1], yticks=[], xticks=[], frame_on=False)
     tri = plt.mesh(x, normu, mergetol=1e-5, cmap='jet')
     plt.clim(0, 1.5)
     plt.tricontour(tri, p, every=self.every, cmap='gray', linestyles='solid', alpha=.8)
     uv = plot.interpolate(tri, self.xy, u)
     plt.vectors(self.xy, uv, zorder=9, pivot='mid', stems=False)
     plt.plot(0, 0, 'k', marker=(3,2,angle*180/numpy.pi-90), markersize=20)
     plt.xlim(self.bbox[0])
     plt.ylim(self.bbox[1])
   self.xy = util.regularize(self.bbox, self.spacing, self.xy + uv * self.timestep)
   self.index += 1
Пример #7
0
def main(nelems: int, degree: int, reynolds: float, rotation: float,
         timestep: float, maxradius: float, seed: int, endtime: float):
    '''
  Flow around a cylinder.

  .. arguments::

     nelems [24]
       Element size expressed in number of elements along the cylinder wall.
       All elements have similar shape with approximately unit aspect ratio,
       with elements away from the cylinder wall growing exponentially.
     degree [3]
       Polynomial degree for velocity space; the pressure space is one degree
       less.
     reynolds [1000]
       Reynolds number, taking the cylinder radius as characteristic length.
     rotation [0]
       Cylinder rotation speed.
     timestep [.04]
       Time step
     maxradius [25]
       Target exterior radius; the actual domain size is subject to integer
       multiples of the configured element size.
     seed [0]
       Random seed for small velocity noise in the intial condition.
     endtime [inf]
       Stopping time.
  '''

    elemangle = 2 * numpy.pi / nelems
    melems = int(numpy.log(2 * maxradius) / elemangle + .5)
    treelog.info('creating {}x{} mesh, outer radius {:.2f}'.format(
        melems, nelems, .5 * numpy.exp(elemangle * melems)))
    domain, geom = mesh.rectilinear([melems, nelems], periodic=(1, ))
    domain = domain.withboundary(inner='left', outer='right')

    ns = function.Namespace()
    ns.uinf = 1, 0
    ns.r = .5 * function.exp(elemangle * geom[0])
    ns.Re = reynolds
    ns.phi = geom[1] * elemangle  # add small angle to break element symmetry
    ns.x_i = 'r <cos(phi), sin(phi)>_i'
    ns.J = ns.x.grad(geom)
    ns.unbasis, ns.utbasis, ns.pbasis = function.chain([  # compatible spaces
        domain.basis(
            'spline', degree=(degree, degree - 1), removedofs=((0, ), None)),
        domain.basis('spline', degree=(degree - 1, degree)),
        domain.basis('spline', degree=degree - 1),
    ]) / function.determinant(ns.J)
    ns.ubasis_ni = 'unbasis_n J_i0 + utbasis_n J_i1'  # piola transformation
    ns.u_i = 'ubasis_ni ?lhs_n'
    ns.p = 'pbasis_n ?lhs_n'
    ns.sigma_ij = '(u_i,j + u_j,i) / Re - p δ_ij'
    ns.h = .5 * elemangle
    ns.N = 5 * degree / ns.h
    ns.rotation = rotation
    ns.uwall_i = '0.5 rotation <-sin(phi), cos(phi)>_i'

    inflow = domain.boundary['outer'].select(
        -ns.uinf.dotnorm(ns.x),
        ischeme='gauss1')  # upstream half of the exterior boundary
    sqr = inflow.integral('(u_i - uinf_i) (u_i - uinf_i)' @ ns,
                          degree=degree * 2)
    cons = solver.optimize(
        'lhs', sqr, droptol=1e-15)  # constrain inflow semicircle to uinf

    sqr = domain.integral('(u_i - uinf_i) (u_i - uinf_i) + p^2' @ ns,
                          degree=degree * 2)
    lhs0 = solver.optimize('lhs', sqr)  # set initial condition to u=uinf, p=0

    numpy.random.seed(seed)
    lhs0 *= numpy.random.normal(1, .1, lhs0.shape)  # add small velocity noise

    res = domain.integral(
        '(ubasis_ni u_i,j u_j + ubasis_ni,j sigma_ij + pbasis_n u_k,k) d:x'
        @ ns,
        degree=9)
    res += domain.boundary['inner'].integral(
        '(N ubasis_ni - (ubasis_ni,j + ubasis_nj,i) n_j) (u_i - uwall_i) d:x / Re'
        @ ns,
        degree=9)
    inertia = domain.integral('ubasis_ni u_i d:x' @ ns, degree=9)

    bbox = numpy.array(
        [[-2, 46 / 9],
         [-2, 2]])  # bounding box for figure based on 16x9 aspect ratio
    bezier0 = domain.sample('bezier', 5)
    bezier = bezier0.subset((bezier0.eval(
        (ns.x - bbox[:, 0]) * (bbox[:, 1] - ns.x)) > 0).all(axis=1))
    interpolate = util.tri_interpolator(
        bezier.tri, bezier.eval(ns.x),
        mergetol=1e-5)  # interpolator for quivers
    spacing = .05  # initial quiver spacing
    xgrd = util.regularize(bbox, spacing)

    with treelog.iter.plain(
            'timestep',
            solver.impliciteuler('lhs',
                                 residual=res,
                                 inertia=inertia,
                                 lhs0=lhs0,
                                 timestep=timestep,
                                 constrain=cons,
                                 newtontol=1e-10)) as steps:
        for istep, lhs in enumerate(steps):

            t = istep * timestep
            x, u, normu, p = bezier.eval(
                ['x_i', 'u_i', 'sqrt(u_k u_k)', 'p'] @ ns, lhs=lhs)
            ugrd = interpolate[xgrd](u)

            with export.mplfigure('flow.png', figsize=(12.8, 7.2)) as fig:
                ax = fig.add_axes([0, 0, 1, 1],
                                  yticks=[],
                                  xticks=[],
                                  frame_on=False,
                                  xlim=bbox[0],
                                  ylim=bbox[1])
                im = ax.tripcolor(x[:, 0],
                                  x[:, 1],
                                  bezier.tri,
                                  p,
                                  shading='gouraud',
                                  cmap='jet')
                import matplotlib.collections
                ax.add_collection(
                    matplotlib.collections.LineCollection(x[bezier.hull],
                                                          colors='k',
                                                          linewidths=.1,
                                                          alpha=.5))
                ax.quiver(xgrd[:, 0],
                          xgrd[:, 1],
                          ugrd[:, 0],
                          ugrd[:, 1],
                          angles='xy',
                          width=1e-3,
                          headwidth=3e3,
                          headlength=5e3,
                          headaxislength=2e3,
                          zorder=9,
                          alpha=.5)
                ax.plot(0,
                        0,
                        'k',
                        marker=(3, 2, t * rotation * 180 / numpy.pi - 90),
                        markersize=20)
                cax = fig.add_axes([0.9, 0.1, 0.01, 0.8])
                cax.tick_params(labelsize='large')
                fig.colorbar(im, cax=cax)

            if t >= endtime:
                break

            xgrd = util.regularize(bbox, spacing, xgrd + ugrd * timestep)

    return lhs0, lhs