예제 #1
0
def draglift(simulations, sortby="dx", **kwargs):
    """
    Compute mean drag coefficient, rms lift coefficient, and Strouhal number
    for flow past a circular cylinder.
    If the flow is steady, only drag and lift coefficients are computed.

    Call signature:
      draglift(simulations, d_cylinder=0.1, u_0=1.0, flow_dir='y',
               t_start=-1, sortby='dx'):

    Keyword arguments:

    *simulations*
      array of simulation names to be included in the computations

    *d_cylinder*:
      diameter of the cylinder

    *u_0*
      velocity at the inlet

    *flow_dir*:
      direction of the flow

    *t_start*
      time to start the drag computations from
      should be where the a steady vortex shedding has developed

    *sortby*
      property to sort the arrays by
      typical choices for parametric studies are grid size, length of domain, etc.

    Returns
      object with information: sim-name, drag (mean), lift (rms), and st (non-dim shedding frequency)
    """
    sims = []
    for simulation in simulations:
        sims.append(sim.get(simulation, quiet=True))

    # Sort simulations
    sims = sim.sort(sims, sortby, reverse=True)

    draglift_tmp = []
    for i, thissim in enumerate(sims):
        draglift_tmp.append(Draglift())
        draglift_tmp[i].set_name(thissim)
        draglift_tmp[i].compute(thissim, **kwargs)

    return draglift_tmp
예제 #2
0
def twonorm_accuracy1D(simulations,
                       field='ur',
                       strip=1,
                       direction='r',
                       varfile='ogvar.dat',
                       noerr=True,
                       quiet=True):
    """
    Assessment of accuracy of simulation:
    Computes the two-norm error of all available simulation, where the simulation
    with the maximum amount of grid points is used as the correct/reference solution.
    E.g., for runs with grid points assessment of accuracy of x-component of velocity
    along the y-direction, for runs with grid points nxgrid = n, 2n, 4n, 8n, compute

    || u_n - u_0 || = dy \sum\limits_{n=0}^n (sqrt(u_n(x_n)-u_0(x_8n)))

    for all runs (except for the 8n case, used as reference).

    Requires that the runs have matching grids, that is, grid refined by a factor of 2m,
    and grids adjusted so that the grid point overlap (needs ofset if periodic BC is used).

    call signature:
      twonorm_accuracy(simulations)

    Keyword arguments:

    *simulations*
      array of simulation names to be included in the computations

    *field*
      variable used in accuracy assessment

    *varfile*:
      name of varfile to read from each sim

    *noerr*:
      set to false if you want to return an array of maximum error along strip, in
      addition to the two-norm

    Returns
      array of two-norms where the larges array is used as base
    """

    import numpy as np
    import os as os
    from pencil import read
    from pencil import sim

    # Find directories to include in accuracy assessment
    sims = []
    for simulation in simulations:
        sims.append(sim.get(simulation, quiet=True))

    # Sort runs by size of grid spacing
    sims = sim.sort(sims, 'dx', reverse=True)

    # From this point we only need the varfile to compute accuracy
    # Need to update dim to ogdim for reading of ogvar to be done
    # correctly from simulation object
    for i, thissim in enumerate(sims):
        sims[i].dim = read.ogdim(datadir=thissim.datadir)
        sims[i] = read.ogvar(sim=thissim, trimall=True, varfile=varfile)

    # Check that increase in size is correct for use in two-norm calculation
    nsims = len(sims)
    nx_min = sims[0].r.size
    ny_min = sims[0].th.size
    for thissim in sims:
        if ((thissim.r.size - 1) % (nx_min - 1) != 0):
            print('ERROR: Incorrect size in r-dir')
            print('sims.r', thissim.r.size)
            print('nx_min', nx_min)
            return False

        if (thissim.th.size % ny_min != 0):
            print('ERROR: Incorrect size in th-dir')
            return False

    # Check that all var-files are for the same time
    t = sims[0].t
    for thissim in sims:
        if thissim.t != t:
            print('WARNING: Incorrect time for one or more simulations')

    # Now we are sure that first coordinate of r and th are the same for all runs
    # Can compute the two-norms for increasing sizes. Use largest size as normalization of error
    twonorms = np.zeros(nsims - 1)
    maxerrs = np.zeros(nsims - 1)

    # Compute array of factor used to jump indices when comparing two arrays of size N and 2N etc.
    # Usually n2_fac = [8, 4, 2] or similar
    n2_fac = np.empty(nsims - 1)
    for i, thissim in enumerate(sims[:-1]):
        n2_fac[i] = thissim.dx / sims[-1].dx

    u2 = getattr(sims[-1], field)
    if not (field == 'ux' or field == 'uy'):
        u2 = u2[0, :, :]

    for i, thissim in enumerate(sims[:-1]):
        u1 = getattr(thissim, field)
        if not (field == 'ux' or field == 'uy'):
            u1 = u1[0, :, :]

        dr = np.empty(thissim.r.size)
        dr[0:-1] = thissim.r[1:] - thissim.r[0:-1]
        dr[-1] = dr[-2]
        dth = thissim.dy
        twonorms[i] = 0.
        n2 = n2_fac[i]
        if (direction == 'r'):
            r = sims[0].r[strip]
            j = int(strip * sims[0].dx / thissim.dx)
            for k in range(thissim.th.size):
                twonorms[i] = twonorms[i] + dth * r * (
                    u1[k, j] - u2[int(k * n2), int(j * n2)])**2
        elif (direction == 'th'):
            k = int(strip * sims[0].dx / thissim.dx)
            for j in range(thissim.r.size):
                twonorms[i] = twonorms[i] + dr[j] * (
                    u1[k, j] - u2[int(k * n2), int(j * n2)])**2
        else:
            print('ERROR: Invalid direction chosen')
            return False

        twonorms[i] = np.sqrt(twonorms[i])

    if not noerr:
        return twonorms, maxerrs
    else:
        return twonorms
예제 #3
0
def twonorm_accuracy(simulations,
                     field='ux',
                     strip=0,
                     var_file='ogvar.dat',
                     direction='x',
                     noerr=True,
                     quiet=True):
    """
    Assessment of accuracy of simulation:
    Computes the two-norm error of all available simulation, where the simulation
    with the maximum amount of grid points is used as the correct/reference solution.
    E.g., for runs with grid points assessment of accuracy of x-component of velocity
    along the y-direction, for runs with grid points nxgrid = n, 2n, 4n, 8n, compute

    || u_n - u_0 || = dy \sum\limits_{n=0}^n (sqrt(u_n(x_n)-u_0(x_8n)))

    for all runs (except for the 8n case, used as reference).

    Requires that the runs have matching grids, that is, grid refined by a factor of 2m,
    and grids adjusted so that the grid point overlap (needs ofset if periodic BC is used).

    call signature:
      twonorm_accuracy(simulations)

    Keyword arguments:

    *simulations*
      array of simulation names to be included in the computations

    *field*
      variable used in accuracy assessment

    *strip*:
      index for strip along coordinate

    *var_file*:
      name of varfile to read from each sim

    *direction*:
      compute two-norm along 'x' or 'y' direction

    *noerr*:
      set to false if you want to return an array of maximum error along strip, in
      addition to the two-norm

    Returns
      array of two-norms where the larges array is used as base
    """

    import numpy as np
    import os as os
    from pencil import read
    from pencil import sim

    # Find directories to include in accuracy assessment
    sims = []
    for simulation in simulations:
        sims.append(sim.get(simulation, quiet=True))

    # Sort runs by size of grid spacing
    if (direction == 'x' or direction == 'r'):
        sims = sim.sort(sims, 'nx', reverse=False)
    elif (direction == 'y' or direction == 'th'):
        sims = sim.sort(sims, 'ny', reverse=False)

    # From this point we only need the varfile to compute accuracy
    # Need to update dim to ogdim for reading of ogvar to be done
    # correctly from simulation object
    for i, thissim in enumerate(sims):
        sims[i].dim = read.ogdim(datadir=thissim.datadir)
        sims[i] = read.ogvar(sim=thissim, trimall=True, var_file=var_file)

    # Check that increase in size is correct for use in two-norm calculation
    nsims = len(sims)
    nx_min = sims[0].r.size
    ny_min = sims[0].th.size
    for thissim in sims:
        if ((thissim.r.size - 1) % (nx_min - 1) != 0):
            print('ERROR: Incorrect size in r-dir')
            print('sims.r', thissim.r.size)
            print('nx_min', nx_min)
            return False

        if (thissim.th.size % ny_min != 0):
            print('ERROR: Incorrect size in th-dir')
            return False

    # Check that all var-files are for the same time
    t = sims[0].t
    for thissim in sims:
        if thissim.t != t:
            print('WARNING: Incorrect time for one or more simulations')

    # Now we are sure that first coordinate of r and th are the same for all runs
    # Can compute the two-norms for increasing sizes. Use largest size as normalization of error
    twonorms = np.zeros(nsims - 1)
    maxerrs = np.zeros(nsims - 1)
    if (direction == 'x' or direction == 'r'):
        dh = sims[0].dx
        n2_factor = int(dh / sims[-1].dx)
    elif (direction == 'y' or direction == 'th'):
        dh = sims[0].dy
        n2_factor = int(dh / sims[-1].dy)

    attribute = getattr(sims[-1], field)
    if (field == 'ux' or field == 'uy'):
        u2 = attribute[0::n2_factor, 0::n2_factor]
    else:
        u2 = attribute[0, 0::n2_factor, 0::n2_factor]

    strip = int(strip)
    if (direction == 'x' or direction == 'r'):
        dh = sims[-1].dx
        dx_max = sims[0].dx
        n2_factor = int(thissim.dx / dh)
        #for i,thissim in enumerate(sims[:-1]):
        #    strips[i]=int(thissim.dx/dx_max*strip)
        #n1_factor = int(sims[0].dx/sims[-1].dx)
    elif (direction == 'y' or direction == 'th'):
        dh = sims[-1].dy
        dx_max = sims[0].dy
        #for i,thissim in enumerate(sims[:-1]):
        #    strips[i]=int(thissim.dy/dx_max*strip)
        #n1_factor = int(sims[0].dx/sims[-1].dy)

    attribute = getattr(sims[-1], field)
    #    if(field=='ux' or field=='uy'):
    #        u2 = attribute[0::n2_factor,0::n2_factor]
    #    else:
    #        u2 = attribute[0,0::n2_factor,0::n2_factor]
    j = 1
    for i, thissim in enumerate(sims[:-1]):
        n1_factor = 1
        if (direction == 'x' or direction == 'r'):
            n2_factor = int(thissim.dx / dh)
        elif (direction == 'y' or direction == 'th'):
            n2_factor = int(thissim.dy / dh)

        u1 = getattr(thissim, field)
        if (field == 'ux' or field == 'uy'):
            u2 = attribute[0::n2_factor, 0::n2_factor]
            #u1 = u1[0::n1_factor]
        else:
            u2 = attribute[0, 0::n2_factor, 0::n2_factor]
            u1 = u1[0, :, :]  #0::n1_factor,:]
            #u1 = u1[0,0::n1_factor,:]

        radius_l = sims[-1].r[0::n2_factor]
        if (direction == 'x' or direction == 'r'):
            twonorms[i] = (twonorm(u1[:, strip * j], u2[:, strip * j],
                                   thissim.dy * sims[0].r[strip]))
            maxerrs[i] = (maxerror(u1[:, strip * j], u2[:, strip * j]))
        elif (direction == 'y' or direction == 'th'):
            twonorms[i] = (twonorm(u1[strip * j, :], u2[strip * j, :],
                                   thissim.dx))
            maxerrs[i] = (maxerror(u1[strip * j, :], u2[strip * j, :]))
        j = j * 2


#        n1_factor = 1
#        u1 = getattr(thissim,field)
#        if(not(field=='ux' or field=='uy')):
#            u1=u1[0,:,:]
#
#        if(direction=='x' or direction=='r'):
#            n1_factor = int(dx_max/thissim.dx)
#            n2_factor = int(thissim.dx/dh)
#            u1 = u1[:,0::n1_factor]
#            u2 = attribute[0,0::n2_factor,0::n2_factor]
#            u2 = u2[:,0::n1_factor]
#        elif(direction=='y' or direction=='th'):
#            n1_factor = int(dx_max/thissim.dy)
#            n2_factor = int(thissim.dy/dh)
#            u1 = u1[0::n1_factor,:]
#            u2 = attribute[0,0::n2_factor,0::n2_factor]
#            u2 = u2[0::n1_factor,:]
#
#        if(direction=='x' or direction=='r'):
#           twonorms[i] = (twonorm(u1[:,strip],u2[:,strip],thissim.dy*sims[0].r[strip]))
#           maxerrs[i] = (maxerror(u1[:,strip],u2[:,strip]))
#        elif(direction=='y' or direction=='th'):
#           twonorms[i] = (twonorm(u1[strip,:],u2[strip,:],thissim.dx))
#           maxerrs[i] = (maxerror(u1[strip,:],u2[strip,:]))
    if (not quiet):
        print('Two-norm computed for field:', field, ', along strip:', strip)
        if (direction == 'x'):
            print('Along x-direction')
        elif (direction == 'r'):
            print('Along r-direction')
        elif (direction == 'y'):
            print('Along y-direction')
        elif (direction == 'th'):
            print('Along th-direction')

    if not noerr:
        return twonorms, maxerrs
    else:
        return twonorms