Beispiel #1
0
def count_nzero_grid(wfun, dh: float, re: float, ndim=0) -> float:
    """Count n_0 on simple grid."""
    nzero = 0.0

    nband = estim_nband(dh, re)

    if ndim <= 0:
        ndim = pympscore.GetSpaceDim()

    if ndim == 2:
        for i in range(-nband, nband + 1):
            for j in range(-nband, nband + 1):
                if i != 0 or j != 0:
                    x = dh * i
                    y = dh * j
                    r = sqrt(x**2 + y**2)
                    w = wfun(r, re)
                    nzero += w
    elif ndim == 3:
        for i in range(-nband, nband + 1):
            for j in range(-nband, nband + 1):
                for k in range(-nband, nband + 1):
                    if i != 0 or j != 0 or k != 0:
                        x = dh * i
                        y = dh * j
                        z = dh * k
                        r = sqrt(x**2 + y**2 + z**2)
                        w = wfun(r, re)
                        nzero += w
    else:
        raise ValueError("Invalid ndim=%s" % ndim)

    return nzero
Beispiel #2
0
    def __init__(self):
        # bootstrap
        self.ndim = 2
        pympscore.SetSpaceDim(ndim)
        print('spacedim=%d' % pympscore.GetSpaceDim())

        # physical
        init_phys(self)

        # numerical
        init_comp(self)
Beispiel #3
0
def newVectorArray(numpart: int,
                   ndim: int = 0,
                   data_type=float,
                   data_order: str = 'F') -> NP.ndarray:
    """Create new vector array. 
    If NDIM not given, use MPS space dimension.
    The array is by default Fortan-style, to be consistent with Eigen.
    """
    if ndim <= 0:
        ndim = pympscore.GetSpaceDim()
    return NP.empty((numpart, ndim), dtype=data_type, order=data_order)
Beispiel #4
0
def count_lambda_grid(wfun, dh: float, re: float, ndim=0) -> float:
    """Count lambda for Laplacian"""
    lam = 0.0
    wgt = 0.0

    nband = estim_nband(dh, re)

    if ndim <= 0:
        ndim = pympscore.GetSpaceDim()

    if ndim == 2:
        for i in range(-nband, nband + 1):
            for j in range(-nband, nband + 1):
                if i != 0 or j != 0:
                    x = dh * i
                    y = dh * j
                    r = sqrt(x**2 + y**2)
                    w = wfun(r, re)
                    lam += w * r**2
                    wgt += w
    elif ndim == 3:
        for i in range(-nband, nband + 1):
            for j in range(-nband, nband + 1):
                for k in range(-nband, nband + 1):
                    if i != 0 or j != 0 or k != 0:
                        x = dh * i
                        y = dh * j
                        z = dh * k
                        r = sqrt(x**2 + y**2 + z**2)
                        w = wfun(r, re)
                        lam += w * r**2
                        wgt += w
    else:
        raise ValueError("Invalid ndim=%s" % ndim)

    lam /= wgt

    return lam
Beispiel #5
0
def main2d():
    '''2D run'''
    
    # bootstrap
    ndim = 2
    pympscore.SetSpaceDim(ndim)
    print('spacedim=%d' % pympscore.GetSpaceDim())

    # physical
    rho = 1.0e3
    cs = 10.0
    pref = rho * cs**2
    nu = 1.0e-1
    grav = NP.array([0.0, -9.81])

    # discretization
    dh = 0.01
    re_dens = dh * 2.1
    re_grad = dh * 2.1
    re_visc = dh * 4.1
    re_pres = dh * 4.1
    re_max = max(re_dens, re_grad, re_visc, re_pres)

    # weight function
    wfun = pympscore.StandardWeightFunction()
    wgradfun = wfun
    print(wfun)

    nzero = count_nzero_grid(wfun, dh, re_dens)
    nzero_part = count_nzero_grid(ConstWeight(), dh, re_dens)
    nzero_grad = count_nzero_grid(wgradfun, dh, re_grad)
    nzero_visc = count_nzero_grid(wfun, dh, re_visc)
    nzero_pres = count_nzero_grid(wfun, dh, re_pres)
    nlam_visc = count_lambda_grid(wfun, dh, re_visc)
    nlam_pres = count_lambda_grid(wfun, dh, re_pres)
    nsurf = nzero * 0.97
    relax_pres = 0.2
    nlam_pres *= relax_pres
    print('nzero=%g' % nzero)
    print('nzero_part=%g' % nzero_part)
    print('nzero_grad=%g' % nzero_grad)
    print('nzero_visc=%g' % nzero_visc)
    print('nzero_pres=%g' % nzero_pres)
    print('lambda_visc=%g' % nlam_visc)
    print('lambda_pres=%g' % nlam_pres)


    # data 
    prob_type = -1
    prob_type = 0
    fluid_data = pympscore.FluidData(ndim)
    npart = 0
    if prob_type == 0:
        init_pos = []
        #init_pos += gen_simple_block(dh, [100,100], [-0.5,-0.5])
        #init_pos += gen_simple_block(dh, [100,50], [-1.0,-0.25])
        #init_pos += gen_simple_block(dh, [50,100], [0.0,-0.5])
        init_pos += gen_simple_block(dh, [100, 50], [-0.5, 0.0])
        init_pos += gen_simple_block(dh, [200, 10], [-1.0, -0.1])
        npart = len(init_pos)

        # 
        fluid_data.numParticle = npart
        fluid_data.alloc()
        NP.copyto(fluid_data.position(), init_pos)

        # mask walls
        msk: NP.ndarray = (fluid_data.position()[:,1] <= 0)
    else:
        prof = load_prof_file('input.grid', ndim)
        npart = prof['npart']

        #
        fluid_data.numParticle = npart
        fluid_data.alloc()
        NP.copyto(fluid_data.position(), prof['pos'])
        NP.copyto(fluid_data.surfflag(), prof['type'])

        msk: NP.ndarray = (fluid_data.surfflag() != 0)

    # domain
    domain = pympscore.Domain()
    domain.vlo = [-2.5, -2.5]
    domain.vhi = [2.5, 2.5]
    print(domain)

    # cache
    re_big = re_max * 1.05
    bucket = pympscore.BucketCache(domain)
    bucket.define(re_big)
    print(bucket)
    bucket.cachePositions(fluid_data.position())

    # neighbor
    neigh_table = pympscore.NeighborTable()
    neigh_table.cutoff = re_big
    neigh_table.resize(fluid_data.numParticle)
    neigh_table.buildFromCache(bucket, fluid_data.position())
    print("table size=%d" % len(neigh_table))

    # expose data access
    numdens: NP.ndarray = fluid_data.numdens()
    surfflag: NP.ndarray = fluid_data.surfflag()
    pympscore.calcNumDens(wfun, re_dens, neigh_table, numdens)
    print("dens_min=%f" % numdens.min())
    print("dens_max=%f" % numdens.max())

    #
    coords: NP.ndarray = fluid_data.position()
    vel: NP.ndarray = fluid_data.velocity()
    pres: NP.ndarray = fluid_data.pressure()
    # assign some values
    vel.fill(0)
    pres.fill(0)

    # local buffers
    grad = newVectorArray(npart, ndim)
    visc = newVectorArray(npart, ndim)

    #
    iplot = 0
    write_fluiddata_vtu("./output/homu%04d"%iplot, fluid_data)
    iplot += 1

    #sys.exit(0)

    time = 0.0
    dt = 0.001
    max_step = 1000
    for step in range(1, max_step+1):

        # build neighbor list
        bucket.cachePositions(coords)
        neigh_table.buildFromCache(bucket, coords)

        # compute number density
        pympscore.calcNumDens(wfun, re_dens, neigh_table, numdens)
        
        # tag surface part
        pympscore.tagSurfFlag(nsurf, numdens, surfflag)

        # compute viscosity
        for dir in range(ndim):
            coef = 2.0*ndim/(nlam_visc*nzero_visc)
            pympscore.calcLaplace(wfun, re_visc, coef, neigh_table, vel[:,dir], visc[:,dir])

        # compute pressure
        if False:
            # explicit use EOS
            pympscore.calcPresEos(numdens, pres, pref, nzero)

            pympscore.calcSymGrad(wgradfun, re, nzero_grad, neigh_table, coords, pres, grad)

            # update
            acc = (-1.0/rho) * grad + nu * visc + grav
            #acc[:,0] += grav[0]
            #acc[:,1] += grav[1]
            vel += acc * dt
            vel[msk,:] = 0
            coords += vel * dt
        else:
            # semi-implicit 

            # trial move
            acc = nu * visc + grav
            vel += acc * dt
            vel[msk,:] = 0
            coords += vel * dt

            neigh_table.updateInfo(coords)

            #
            pympscore.calcNumDens(wfun, re_dens, neigh_table, numdens)
            pympscore.tagSurfFlag(nsurf, numdens, surfflag)

            #
            rhs = (1.0/dt) / nzero * (numdens-nzero)

            #
            coef = 2.0*ndim / (nlam_pres * nzero_pres)
            coef *= (dt/rho)
            pympscore.solvePres(wfun, re_pres, 
                                coef, 
                                neigh_table, surfflag, 
                                rhs, pres)
            
            # clip pressure
            pres[pres<0] = 0

            # 
            pympscore.calcSymGrad(wfun, re_grad, nzero_grad, neigh_table, coords, pres, grad)

            # update
            acc = (-1.0/rho) * grad
            acc[msk,:] = 0
            vel += acc * dt
            coords += acc * dt**2

        # advance time
        time += dt

        if step%10 == 0:
            print('step=%d, time=%f' % (step,time))
            write_fluiddata_vtu("./output/homu%04d"%iplot, fluid_data)
            iplot += 1

    return