コード例 #1
0
ファイル: lbm.py プロジェクト: hietwll/sailfish-cfd
 def _update_ctx(self, ctx):
     ctx['gravity'] = self.gravity
     ctx['bc_wall'] = 'fullbb'
     ctx['bc_velocity'] = None
     ctx['bc_pressure'] = None
     ctx['bc_wall_'] = geo.get_bc('fullbb')
     ctx['bc_velocity_'] = geo.get_bc('fullbb')
     ctx['bc_pressure_'] = geo.get_bc('fullbb')
コード例 #2
0
    def define_nodes(self):
        radiussq = ((self.chan_diam) / 2)**2
        diam = sphere_diam(self.width, geo.get_bc(self.options.bc_velocity))
        x0 = int(2.4 * diam)
        y0 = (self.lat_ny - 1) / 2.0
        z0 = (self.lat_nz - 1) / 2.0
        h = 0.0

        bc = geo.get_bc(self.options.bc_velocity)
        h = -bc.location
        z0 -= bc.location
        y0 -= bc.location

        hz, hy, hx = np.mgrid[0:self.lat_nz, 0:self.lat_ny, 0:self.lat_nx]

        # Channel walls.
        node_map = (y0 - (hy + h))**2 + (z0 - (hz + h))**2 >= radiussq
        self.set_geo(node_map, self.NODE_VELOCITY, (self.maxv, 0.0, 0.0))

        # Inlet.
        self.set_geo(hx == 0, self.NODE_VELOCITY, (self.maxv, 0.0, 0.0))

        ix0 = int(x0)
        iy0 = int(y0)
        iz0 = int(z0)

        rsq = diam**2 / 4.0

        miny = iy0
        maxy = iy0

        radius = int(diam / 2)

        wall_map = (x0 - (hx + h))**2 + (y0 -
                                         (hy + h))**2 + (z0 -
                                                         (hz + h))**2 <= rsq
        self.set_geo(wall_map, self.NODE_WALL)
        maxy = np.max(hy[wall_map])
        miny = np.min(hy[wall_map])

        bc = geo.get_bc(self.options.bc_wall)
        self.sphere_diam = float(maxy - miny) + 2.0 * bc.location

        diam = int(diam)
        self.add_force_object(
            'sphere',
            (ix0 - diam / 2 - 3, iy0 - diam / 2 - 3, iz0 - diam / 2 - 3),
            (diam + 6, diam + 6, diam + 6))
コード例 #3
0
    def _velocity_profile(self, hi):
        bc = geo.get_bc(self.options.bc_wall)
        width = self.get_chan_width()
        lat_width = self.get_width()
        h = -bc.location

        return (4.0 * self.maxv/width**2 * (hi + h) * (width - hi - h))
コード例 #4
0
    def define_nodes(self):
        radiussq = ((self.chan_diam)/2)**2
        diam = sphere_diam(self.width, geo.get_bc(self.options.bc_velocity))
        x0 = int(2.4*diam)
        y0 = (self.lat_ny - 1) / 2.0
        z0 = (self.lat_nz - 1) / 2.0
        h = 0.0

        bc = geo.get_bc(self.options.bc_velocity)
        h = -bc.location
        z0 -= bc.location
        y0 -= bc.location

        hz, hy, hx = np.mgrid[0:self.lat_nz, 0:self.lat_ny, 0:self.lat_nx]

        # Channel walls.
        node_map = (y0 - (hy + h))**2 + (z0 - (hz + h))**2 >= radiussq
        self.set_geo(node_map, self.NODE_VELOCITY, (self.maxv, 0.0, 0.0))

        # Inlet.
        self.set_geo(hx == 0, self.NODE_VELOCITY, (self.maxv, 0.0, 0.0))

        ix0 = int(x0)
        iy0 = int(y0)
        iz0 = int(z0)

        rsq = diam**2 / 4.0

        miny = iy0
        maxy = iy0

        radius = int(diam / 2)

        wall_map = (x0 - (hx+h))**2 + (y0 - (hy+h))**2 + (z0 - (hz+h))**2 <= rsq
        self.set_geo(wall_map, self.NODE_WALL)
        maxy = np.max(hy[wall_map])
        miny = np.min(hy[wall_map])

        bc = geo.get_bc(self.options.bc_wall)
        self.sphere_diam = float(maxy - miny) + 2.0 * bc.location

        diam = int(diam)
        self.add_force_object('sphere', (ix0-diam/2-3, iy0-diam/2-3, iz0-diam/2-3),
                        (diam+6, diam+6, diam+6))
コード例 #5
0
 def get_profile(self):
     # NOTE: This only works for the 'along_y' option.
     if geo.get_bc(self.options.bc_wall).wet_nodes:
         return self.vy[:,
                        int(self.options.lat_ny / 2),
                        int(self.options.lat_nx / 2)]
     else:
         return self.vy[1:-1,
                        int(self.options.lat_ny / 2),
                        int(self.options.lat_nx / 2)]
コード例 #6
0
 def get_profile(self):
     if geo.get_bc(self.options.bc_wall).wet_nodes:
         if self.options.horizontal:
             return self.vx[:,int(self.options.lat_nx/2)]
         else:
             return self.vy[int(self.options.lat_ny/2),:]
     else:
         if self.options.horizontal:
             return self.vx[1:-1,int(self.options.lat_nx/2)]
         else:
             return self.vy[int(self.options.lat_ny/2),1:-1]
コード例 #7
0
    def __init__(self, geo_class, defaults={}, args=sys.argv[1:]):
        opts = []
        opts.append(optparse.make_option('--re', dest='re', type='int', help='Reynolds number', default=100))
        defaults_ = {'lat_nz': 128,
            'lat_ny': 128,
            'lat_nx': 512,
            'max_iters': 320000,
            'model': 'mrt',
            'every': 100,
            'incompressible': True,
            'grid': 'D3Q13',
            'bc_velocity': 'fullbb',
            'verbose': True}
        defaults_.update(defaults)

        lb_single.FluidLBMSim.__init__(self, geo_class, options=opts, args=args, defaults=defaults_)

        if self.options.batch and not ('every' in self.options.specified):
            self.options.every = 1000

        diam = sphere_diam(self.options.lat_ny, geo.get_bc(self.options.bc_velocity))

        # If the diameter here is odd, the channel width is even and we will end up
        # with a sphere of an even diameter so that the system can be symmetric.
        if diam % 2:
            diam -= 1.0

        # maxv / visc
        ratio = self.options.re / diam

        visc = 0.12
        maxv = ratio * visc

        # Try to keep the viscosity as high as possible to make sure the computed force
        # is correct.  For single precision calculations, flows with low viscosity and
        # low flow speed can yield incorrect values.  There are no such problems for
        # double precision simulations.
        if maxv > 0.1:
            geo_class.maxv = 0.1
            self.options.visc = geo_class.maxv / ratio
        else:
            geo_class.maxv = maxv
            self.options.visc = visc

        if self.options.verbose:
            self._timed_print('# maxv = %s' % geo_class.maxv)

        self.add_iter_hook(self.options.every, self.print_force, every=True)

        if self.options.verbose:
            self.add_iter_hook(5, self.print_theoretical_drag)

        self.coeffs = []
コード例 #8
0
ファイル: lb_single.py プロジェクト: hietwll/sailfish-cfd
    def _update_ctx(self, ctx):
        ctx['incompressible'] = self.incompressible
        ctx['bc_wall'] = self.options.bc_wall
        ctx['bc_slip'] = self.options.bc_slip

        if self.geo.has_velocity_nodes:
            ctx['bc_velocity'] = self.options.bc_velocity
        else:
            ctx['bc_velocity'] = None

        if self.geo.has_pressure_nodes:
            ctx['bc_pressure'] = self.options.bc_pressure
        else:
            ctx['bc_pressure'] = None

        ctx['bc_wall_'] = geo.get_bc(self.options.bc_wall)
        ctx['bc_slip_'] = geo.get_bc(self.options.bc_slip)
        ctx['bc_velocity_'] = geo.get_bc(self.options.bc_velocity)
        ctx['bc_pressure_'] = geo.get_bc(self.options.bc_pressure)
        ctx['simtype'] = 'fluid'
        ctx['subgrid'] = self.options.subgrid
        ctx['smagorinsky_const'] = self.options.smagorinsky_const
コード例 #9
0
    def get_velocity_profile(self, fluid_only=False):
        bc = geo.get_bc(self.options.bc_wall)
        x = self.lat_nx/2
        if fluid_only and not bc.wet_nodes:
            zvals = range(1, self.lat_nz-1)
        else:
            zvals = range(0, self.lat_nz)

        ret = []

        for z in zvals:
            rc = math.sqrt((x-self.lat_nx/2.0+0.5)**2 + (z-self.lat_nz/2.0+0.5)**2)
            ret.append(self.get_velocity(rc))

        return ret
コード例 #10
0
    def get_velocity_profile(self, fluid_only=False):
        bc = geo.get_bc(self.options.bc_wall)
        width = self.get_chan_width()
        lat_width = self.get_width()
        ret = []
        h = -bc.location

        for x in range(0, lat_width):
            tx = x+h
            ret.append(4.0*self.maxv/width**2 * tx * (width-tx))

        # Remove data corresponding to non-fluid nodes if necessary.
        if fluid_only and not bc.wet_nodes:
            return ret[1:-1]

        return ret
コード例 #11
0
    def get_velocity_profile(self, fluid_only=False):
        bc = geo.get_bc(self.options.bc_wall)
        x = self.lat_nx / 2
        if fluid_only and not bc.wet_nodes:
            zvals = range(1, self.lat_nz - 1)
        else:
            zvals = range(0, self.lat_nz)

        ret = []

        for z in zvals:
            rc = math.sqrt((x - self.lat_nx / 2.0 + 0.5)**2 +
                           (z - self.lat_nz / 2.0 + 0.5)**2)
            ret.append(self.get_velocity(rc))

        return ret
コード例 #12
0
 def get_profile(self):
     # NOTE: This only works for the 'along_y' option.
     if geo.get_bc(self.options.bc_wall).wet_nodes:
         return self.vy[:,int(self.options.lat_ny/2),int(self.options.lat_nx/2)]
     else:
         return self.vy[1:-1,int(self.options.lat_ny/2),int(self.options.lat_nx/2)]
コード例 #13
0
 def get_chan_width(self):
     bc = geo.get_bc(self.options.bc_wall)
     return self.get_width() - 1 - 2 * bc.location
コード例 #14
0
 def chan_diam(self):
     """The actual channel diameter in lattice units."""
     bc = geo.get_bc(self.options.bc_velocity)
     return self.width - 1 - 2.0 * bc.location
コード例 #15
0
    def __init__(self, geo_class, defaults={}, args=sys.argv[1:]):
        opts = []
        opts.append(
            optparse.make_option('--re',
                                 dest='re',
                                 type='int',
                                 help='Reynolds number',
                                 default=100))
        defaults_ = {
            'lat_nz': 128,
            'lat_ny': 128,
            'lat_nx': 512,
            'max_iters': 320000,
            'model': 'mrt',
            'every': 100,
            'incompressible': True,
            'grid': 'D3Q13',
            'bc_velocity': 'fullbb',
            'verbose': True
        }
        defaults_.update(defaults)

        lb_single.FluidLBMSim.__init__(self,
                                       geo_class,
                                       options=opts,
                                       args=args,
                                       defaults=defaults_)

        if self.options.batch and not ('every' in self.options.specified):
            self.options.every = 1000

        diam = sphere_diam(self.options.lat_ny,
                           geo.get_bc(self.options.bc_velocity))

        # If the diameter here is odd, the channel width is even and we will end up
        # with a sphere of an even diameter so that the system can be symmetric.
        if diam % 2:
            diam -= 1.0

        # maxv / visc
        ratio = self.options.re / diam

        visc = 0.12
        maxv = ratio * visc

        # Try to keep the viscosity as high as possible to make sure the computed force
        # is correct.  For single precision calculations, flows with low viscosity and
        # low flow speed can yield incorrect values.  There are no such problems for
        # double precision simulations.
        if maxv > 0.1:
            geo_class.maxv = 0.1
            self.options.visc = geo_class.maxv / ratio
        else:
            geo_class.maxv = maxv
            self.options.visc = visc

        if self.options.verbose:
            self._timed_print('# maxv = %s' % geo_class.maxv)

        self.add_iter_hook(self.options.every, self.print_force, every=True)

        if self.options.verbose:
            self.add_iter_hook(5, self.print_theoretical_drag)

        self.coeffs = []
コード例 #16
0
 def chan_diam(self):
     """The actual channel diameter in lattice units."""
     bc = geo.get_bc(self.options.bc_velocity)
     return self.width - 1 - 2.0 * bc.location
コード例 #17
0
 def get_chan_width(self):
     bc = geo.get_bc(self.options.bc_wall)
     return self.get_width() - 1 - 2 * bc.location
コード例 #18
0
ファイル: poiseuille.py プロジェクト: xyuan/sailfish
if options.grid:
    grid = options.grid
else:
    if options.dim == "2":
        grid = "D2Q9"
    else:
        grid = "D3Q13"

if options.drive == "force":
    geo_type = geo.LBMGeo.NODE_WALL
else:
    geo_type = geo.LBMGeo.NODE_PRESSURE

if options.bc:
    bcs = filter(lambda x: geo_type in geo.get_bc(x).supported_types, options.bc.split(","))
else:
    bcs = [x.name for x in geo.SUPPORTED_BCS if geo_type in x.supported_types]


class LTestPoiSim(LPoiSim):
    def __init__(self, args, defaults):
        super(LTestPoiSim, self).__init__(LBMGeoPoiseuille, args, defaults)
        self.clear_hooks()
        self.add_iter_hook(self.options.max_iters - 1, self.save_output)

    def save_output(self):
        #       self.result = (numpy.max(self.vy[16,1:self.geo.lat_nx-1]) / max(self.geo.get_velocity_profile())) - 1.0
        self.res_maxv = numpy.max(self.geo.mask_array_by_fluid(self.vy))
        self.th_maxv = max(self.geo.get_velocity_profile())