コード例 #1
0
ファイル: shearstress.py プロジェクト: henkjongbloed/iFlow
def shearstressGS(tau_order, data, submodule=None, friction='Roughness'):     # Shear stress following the formulation of Schramkowski; only subtidal sf and subtidal second order friction
    jmax = data.v('grid', 'maxIndex', 'x')
    kmax = data.v('grid', 'maxIndex', 'z')
    fmax = data.v('grid', 'maxIndex', 'f')
    rho0 = data.v('RHO0')
    sf = data.v(friction, range(0, jmax+1), 0, 0)

    if submodule is None:
        submodule = (None, )*(tau_order+1)

    ## 1. bed shear stress
    # the bed shear stress is extended over fmax+1 frequency components to prevent inaccuracies in truncation
    ulist = []
    for i in range(0, tau_order+1):
        if submodule[i] is None:
            u = data.v('u'+str(i), range(0, jmax+1), [kmax], range(0, fmax+1))
        else:
            u = data.v('u'+str(i), submodule[i], range(0, jmax+1), [kmax], range(0, fmax+1))
        if u is None:
            u = np.zeros((jmax+1, 1, fmax+1), dtype=complex)

        ulist.append(u)

    taub_abs = np.zeros((jmax+1, 1, fmax+1), dtype=complex)
    if tau_order == 0:
        # uabs0 = ny.absoluteU(ulist[0][:, 0, 1]+10**-6, 0)
        # uabs2 = ny.absoluteU(ulist[0][:, 0, 1]+10**-6, 2)+np.conj(ny.absoluteU(ulist[0][:, 0, 1]+10**-6, -2))
        uabs0 = ny.absoluteU(ulist[0][:, 0, 1], 0)
        uabs2 = ny.absoluteU(ulist[0][:, 0, 1], 2) + np.conj(ny.absoluteU(ulist[0][:, 0, 1], -2))
        taub_abs[:, 0, 0] = rho0*sf*uabs0
        taub_abs[:, 0, 2] = rho0*sf*uabs2
    elif tau_order ==1:
        signu = np.zeros((jmax+1, 1, np.maximum(fmax+1, 4)), dtype=complex)
        # signu[:, 0, 1] = ny.signU(ulist[0][:, 0, 1]+10**-6, 1) + np.conj(ny.signU(ulist[0][:, 0, 1]+10**-6, -1))
        # signu[:, 0, 3] = ny.signU(ulist[0][:, 0, 1]+10**-6, 3) + np.conj(ny.signU(ulist[0][:, 0, 1]+10**-6, -3))
        signu[:, 0, 1] = ny.signU(ulist[0][:, 0, 1], 1) + np.conj(ny.signU(ulist[0][:, 0, 1], -1))
        signu[:, 0, 3] = ny.signU(ulist[0][:, 0, 1], 3) + np.conj(ny.signU(ulist[0][:, 0, 1], -3))
        if fmax+1 < 4:
            ulist[1] = np.concatenate((ulist[1], np.zeros((jmax+1, 1, 4-fmax-1))), 2)
        taub_abs = rho0*sf.reshape((jmax+1, 1, 1))*ny.complexAmplitudeProduct(ulist[1], signu, 2)
    elif tau_order ==2:
        utid = ny.invfft2(ulist[0], 2, 90)
        ucomb = ny.invfft2(ulist[0]+ulist[1], 2, 90)
        uabs_tid = np.mean(np.abs(utid), axis=2)
        uabs_tot = np.mean(np.abs(ucomb), axis=2)
        uabs_eps = (uabs_tot - uabs_tid).reshape((jmax+1))

        taub_abs[:, 0, 0] = rho0*sf*uabs_eps

    return taub_abs[:, :, :fmax+1]
コード例 #2
0
def shearstress_truncated(tau_order, data, submodule=None, friction='Roughness'):     # Shear stress derived using time series (truncated, only for standard forcing conditions)
    jmax = data.v('grid', 'maxIndex', 'x')
    kmax = data.v('grid', 'maxIndex', 'z')
    fmax = data.v('grid', 'maxIndex', 'f')
    rho0 = data.v('RHO0')
    sf = data.v(friction, range(0, jmax+1), 0, 0)

    if submodule is None:
        submodule = (None, )*(tau_order+1)

    ## 1. bed shear stress
    # the bed shear stress is extended over fmax+1 frequency components to prevent inaccuracies in truncation
    ulist = []
    for i in range(0, 2):
        if submodule[i] is None:
            u = data.v('u'+str(i), range(0, jmax+1), [kmax], range(0, fmax+1))
        else:
            u = data.v('u'+str(i), submodule[i], range(0, jmax+1), [kmax], range(0, fmax+1))
        if u is None:
            u = np.zeros((jmax+1, 1, fmax+1), dtype=complex)

        ulist.append(u)
    u = sum(ulist)
    utim = ny.invfft2(u, 2, 90)
    utim = np.abs(utim)
    uabs = ny.fft(utim, 2)[:, :, :fmax+1]
    taub_abs = rho0*sf.reshape((jmax+1, 1, 1))*uabs
    if tau_order == 0:
        taub_abs[:, :, 1] =0
    elif tau_order == 1:
        taub_abs[:, :, 0] =0
        taub_abs[:, :, 2] =0
    else:
        taub_abs[:, :, 1:] =0
    return taub_abs
コード例 #3
0
    def positivity_correction(self, quantity, value_currentorder, order, include_vertical):
        """Correct 'quantity' so that its total over all orders does not become negative.
        Do this by reducing the time-varying components at the current order

        Parameters:
            quantity (str) - name of the quantity without order marking (assumes that leading order is not marked with a number, e.g. Av, Av1, Av2 ..)
            value_currentorder (int) - value of quantity at current order of computation
            order (int or None) - current order of computation (None=truncation)
            include_vertical (bool) - is there a vertical dependency?

        Returns:
            corrected result of 'quantity' only at the current order

        """
        # Init
        jmax = self.input.v('grid', 'maxIndex', 'x')
        if include_vertical:
            kmax = self.input.v('grid', 'maxIndex', 'z')
        else:
            kmax = 0
            value_currentorder = value_currentorder.reshape((value_currentorder.shape[0], 1, value_currentorder.shape[-1]))
        fmax = self.input.v('grid', 'maxIndex', 'f')

        # Add all eddy viscosity components
        if order is None:
            Av = value_currentorder         # use value supplied in truncation method
        else:
            Av = 0 + 0*1j
            for i in range(0, order):       # take all lower orders from DC, then add the value at current order
                if i==0:
                    ordstr = quantity
                else:
                    ordstr = quantity+str(order)
                Av += self.input.v(ordstr, range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
            Av += value_currentorder

        # make a time series with 100 time steps
        Avt = ny.invfft2(Av, len(Av.shape)-1, 90) - Av[:, :, [0]]

        # correct by reducing time varying components
        if not np.min(np.real(np.minimum(1, abs(Av[:, :, 0])/(-np.min(Avt, axis=-1)+10**-10))))==1.:
            value_currentorder[:, :, 1:] = value_currentorder[:, :, 1:]*np.real(np.minimum(1, .95*abs(Av[:, :, 0])/(-np.min(Avt, axis=-1)+10**-10)).reshape((jmax+1, kmax+1, 1)))
            # value_currentorder = self.positivity_correction(quantity, value_currentorder, include_vertical)

        if not include_vertical:
            value_currentorder = value_currentorder.reshape((value_currentorder.shape[0], value_currentorder.shape[-1]))
        return value_currentorder
コード例 #4
0
ファイル: KEFittedMAW.py プロジェクト: henkjongbloed/iFlow
    def run(self):
        ################################################################################################################
        ## 1. Init
        ################################################################################################################
        # self.timers[0].tic()

        ## prepare output message
        self.logger.info('Running MAW turbulence model')
        denstr = ''
        if self.betac ==0:
            denstr = '- not including density effects'
        self.logger.info('\tMAW rel. difference in Av in last iteration: %s %s' % (self.difference, denstr))

        d = {}

        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        fmax = self.input.v('grid', 'maxIndex', 'f')

        G = self.input.v('G')
        rho0 = self.input.v('RHO0')
        uzmin = self.input.v('uzmin')

        Avold = self.input.v('Av', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
        Kvold = self.input.v('Kv', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
        sfold = self.input.v('Roughness', range(0, jmax+1), 0, 0)
        # self.timers[0].toc()

        ################################################################################################################
        ## 2. KEFitted run
        ################################################################################################################
        # self.timers[1].tic()
        d.update(self.kem.run())
        self.input.merge(d)

        # load data resulting from KEFitted model
        Avmid = self.input.v('Av', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
        Kvmid = Avmid/self.input.v('sigma_rho', range(0, jmax+1), range(0, kmax+1), [0])
        sfmid = self.input.v('Roughness', range(0, jmax+1), 0, 0)
        # self.timers[1].toc()

        ################################################################################################################
        ## 3. Density effects
        ################################################################################################################
        if self.betac == 0:     # no density effect included, first let KEFitted spin up
            Av0 = Avmid[:, :, 0]
            Kv0 = Kvmid[:, :, 0]
            sf = sfmid

            Cd = 1.
            MA_av = 1.
            MA_kv = 1.
            Ri = 0.
        else:
            ## Load data
            # self.timers[2].tic()
            cz = self.input.d('c0', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1), dim='z') + self.input.d('c1', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1), dim='z') + self.input.d('c2', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1), dim='z')
            uz = self.input.d('u0', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1), dim='z') + self.input.d('u1', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1), dim='z')
            zeta0 = self.input.v('zeta0', range(0, jmax+1), [0], range(0, fmax+1))
            H = self.input.v('grid', 'low', 'z', range(0, jmax+1)) - self.input.v('grid', 'high', 'z', range(0, jmax+1))
            # self.timers[2].tic()

            ## Convert to time series
            # self.timers[3].tic()
            cz = ny.invfft2(cz, 2, 90)
            uz = ny.invfft2(uz, 2, 90)
            zeta0 = ny.invfft2(zeta0, 2, 90)
            Avmid = ny.invfft2(Avmid, 2, 90)
            Kvmid = ny.invfft2(Kvmid, 2, 90)
            # self.timers[3].toc()
            # self.timers[4].tic()
            uzmin = np.ones(uz.shape)*uzmin

            ## Compute Richardson number
            Ri = -G*self.betac/rho0*cz/(uz**2+uzmin**2)

            Rida = 1./H.reshape((jmax+1, 1, 1))*ny.integrate(Ri.reshape((jmax+1, kmax+1, 1, Ri.shape[-1])), 'z', kmax, 0, self.input.slice('grid')).reshape((jmax+1, 1, Ri.shape[-1]))  # depth-average
            Rida += zeta0*(Ri[:, [0], :]-Rida)/H.reshape((jmax+1, 1, 1))        # depth average continued
            Rida0 = np.maximum(Rida, 0.)                                        # only accept positive Ri
            Ribed = np.maximum(Ri[:, [-1], :], 0.)                              # only accept positive Ri
            Ribedmax = self.input.v('Ribedmax')
            Ribed = np.minimum(Ribed, Ribedmax)                                 # 5-3-2018 limit near-bed Ri

            ## relaxation on Rida
            if hasattr(self, 'Rida'):       # Relaxation of Ri_da using previously saved value
                dRida = self.Rida - Rida0
                Rida = np.max((Rida0, np.min((dRida * (1 - self.RELAX), dRida * (1. + self.RELAX)), axis=0) + Rida0), axis=0)
                Rida = np.min((Rida,   np.max((dRida * (1 - self.RELAX), dRida * (1. + self.RELAX)), axis=0) + Rida0), axis=0)
                self.Rida = Rida
            else:                           # No value saved if the init found an available Ri. Then start with full signal computed here (do not use saved value, as this has been truncated to frequency components)
                Rida = Rida0

            # self.timers[4].toc()

            ## Compute damping functions
            # self.timers[5].tic()
            # Av
            MA_av = (1+10*Rida)**(-0.5)
            dAv = ny.fft(Avmid*MA_av, 2)[:, :, :fmax+1] - Avold
            Av = Avold + (1-self.RELAX)*(self.LOCAL*dAv + .5*(1-self.LOCAL)*dAv[[0]+range(0, jmax), :, :] + .5*(1-self.LOCAL)*dAv[range(1, jmax+1)+[jmax], :, :])
            # Av = Avold + dAv
            Av0 = Av[:, :, 0]

            # Kv
            MA_kv = (1+3.33*Rida)**(-1.5)
            dKv = ny.fft(Kvmid*MA_kv, 2)[:, :, :fmax+1] - Kvold
            Kv = Kvold + (1-self.RELAX)*(self.LOCAL*dKv + .5*(1-self.LOCAL)*dKv[[0]+range(0, jmax), :, :] + .5*(1-self.LOCAL)*dKv[range(1, jmax+1)+[jmax], :, :])
            # Kv = Kvold + dKv
            Kv0 = Kv[:, :, 0]

            # Sf
            Rfmean = np.mean(Ribed[:, 0, :]*(Kvmid*MA_kv)[:, 0, :]/(Avmid*MA_av)[:, 0, :], axis=-1)
            Cd = (1+5.5*Rfmean)**-2.
            damp_sf = Cd
            sf = sfmid*damp_sf
            dsf = sf - sfold
            sf = sfold + (1-self.RELAX)*(self.LOCAL*dsf + .5*(1-self.LOCAL)*dsf[[0]+range(0, jmax)] + .5*(1-self.LOCAL)*dsf[range(1, jmax+1)+[jmax]])
            # self.timers[5].toc()

            # process for output
            MA_av = ny.fft(MA_av, 2)[:, :, :fmax+1]
            MA_kv = ny.fft(MA_kv, 2)[:, :, :fmax+1]
            Ri = ny.fft(Ri, 2)[:, :, :fmax+1]

        ################################################################################################################
        ## Reference level
        ################################################################################################################
        if self.referenceLevel == 'True':
            self.input.merge({'Av': Av0, 'Roughness': sf})
            d['R'] = self.kem.RL.run()['R']

        ################################################################################################################
        ## Compute difference
        ################################################################################################################
        Av0s = ny.savitzky_golay(Av0[:, 0], self.filterlength, 1)
        difference = np.max(abs(Av0s-Avold[:, 0, 0])/abs(Av0s+10**-4))
        self.difference = copy.copy(difference)

        ###############################################################################################################
        # DEBUG plots
        ###############################################################################################################
        # import matplotlib.pyplot as plt
        # import step as st
        # x = ny.dimensionalAxis(self.input.slice('grid'), 'x')[:, 0,0]
        #
        # if self.betac > 0 and np.mod(self.iteration, 3)==0:  # and self.difference>0.15:
        #     st.configure()
        #     plt.figure(1, figsize=(2,2))
        #     plt.subplot(1,2,1)
        #     plt.plot(x/1000., Avold[:, 0, 0], label='old')
        #     plt.plot(x/1000., Av0[:, 0], label='new')
        #     plt.ylim(0, np.maximum(np.max(Av0[:, 0]), np.max(Avold[:, 0, 0])))
        #     plt.legend()
        #
        #     plt.subplot(1,2,2)
        #     plt.plot(x/1000., Avold[:, 0, 0]-Av0[:, 0])
        #     plt.twinx()
        #     plt.plot(x/1000., self.input.v('f', range(0, jmax+1)), color='grey')
        #     plt.ylim(0, 1.)
        #
        #     st.save('plot_'+str(len(x))+'_'+str(self.iteration))
        #
        #     plt.figure(2, figsize=(1, 2))
        #     ws = self.input.v('ws0', range(0, jmax+1), 0, 0)
        #     plt.plot(x/1000., ws)
        #
        #     st.save('ws_'+str(len(x))+'_'+str(self.iteration))


        ################################################################################################################
        ## Prepare Output
        ################################################################################################################
        # self.timers[6].tic()

        x = ny.dimensionalAxis(self.input.slice('grid'),'x')[:, 0,0]
        nf = ny.functionTemplates.NumericalFunctionWrapper(ny.savitzky_golay(Av0[:, 0], self.filterlength, 1).reshape((jmax+1, 1)), self.input.slice('grid'))
        nf.addDerivative(ny.savitzky_golay(ny.derivative(Av0[:, 0], 'x', self.input), self.filterlength, 1).reshape((jmax+1, 1)), 'x')
        nf.addDerivative(ny.savitzky_golay(ny.secondDerivative(Av0[:, 0], 'x', self.input), self.filterlength, 1).reshape((jmax+1, 1)), 'xx')
        d['Av'] = nf.function

        nf2 = ny.functionTemplates.NumericalFunctionWrapper(ny.savitzky_golay(Kv0[:, 0], self.filterlength, 1).reshape((jmax+1, 1)), self.input.slice('grid'))
        nf2.addDerivative(ny.savitzky_golay(ny.derivative(Kv0[:, 0], 'x', self.input), self.filterlength, 1).reshape((jmax+1, 1)), 'x')
        nf2.addDerivative(ny.savitzky_golay(ny.secondDerivative(Kv0[:, 0], 'x', self.input), self.filterlength, 1).reshape((jmax+1, 1)), 'xx')
        d['Kv'] = nf2.function

        d['Roughness'] = sf
        d['skin_friction'] = sfmid
        d['dampingFunctions'] = {}
        d['dampingFunctions']['Roughness'] = Cd
        d['dampingFunctions']['Av'] = MA_av
        d['dampingFunctions']['Kv'] = MA_kv
        d['Ri'] = Ri
        # self.timers[6].toc()

        ## Timers
        # self.timers[0].disp('0 init MAW')
        # self.timers[1].disp('1 KEFitted')
        # self.timers[2].disp('2 load data')
        # self.timers[3].disp('3 invfft')
        # self.timers[4].disp('4 Ri')
        # self.timers[5].disp('5 Compute Av, Kv, sf')
        # self.timers[6].disp('6 Load in dict')

        return d
コード例 #5
0
    def profileSelection(self, uabs, uabsH, order):
        """ Go through a menu with turbulence profiles and roughness parameters. Selects the correct one based on the input
         Then determines the coefficients and prepares the functions for the eddy viscosity and Roughness

        Parameters:
            uabs (array) - approximation of the absolute depth-averaged velocity (at the current order)
            uabsH (array) - approximation of the absolute depth-averaged velocity * depth (at the current order)
            order (int or None) - current order of the calculation

        Returns:
            prepared functions for Av and the roughness parameter of choice. Also returns the type of boundary condition
        """
        # Init
        jmax = self.input.v('grid', 'maxIndex', 'x')
        fmax = self.input.v('grid', 'maxIndex', 'f')
        if order < 1:
            Avmin = self.Avmin

        #   Make a new data container with the roughness parameter with the depth-scaling param n incorporated
        data = self.input.slice('grid')
        data.addData('coef', self.input.v(self.roughnessParameter))
        roughness = self.input.slice('grid')
        roughness.addData('Roughness', UniformX('x', data, self.n).function)

        ################################################################################################################
        # Select the correct profile and roughness parameter:
        #   1. Uniform
        #       1a. uniform + sf0 (linear)
        #       1b. uniform + z0*(non-linear)
        ################################################################################################################

        ################################################################################################################
        ## case 1a: uniform + sf0 (linear)
        ################################################################################################################
        if self.roughnessParameter == 'sf0':
            ## 1. Eddy viscosity
            Av0 = np.zeros((jmax + 1, fmax + 1), dtype=complex)
            # truncated model
            if order == None:
                depth = np.zeros((jmax+1, fmax+1), dtype=complex)
                depth[:, 0] = self.input.v('grid', 'low', 'z', range(0,jmax+1)) - self.input.v('grid', 'high', 'z', range(0,jmax+1))
                i = 0
                while self.input.v('zeta'+str(i)) and i <= self.truncationorder:
                    depth += self.input.v('zeta'+str(i), range(0, jmax+1), 0, range(0, fmax+1))
                    for submod in self.ignoreSubmodule:
                        try:
                            depth -= self.input.v('zeta'+str(i), submod, range(0, jmax+1), 0, range(0, fmax+1))
                        except:
                            pass
                    i += 1

                Av0[:, :] = 0.49 * roughness.v('Roughness', range(0, jmax + 1), 0, [0]) * depth

            # Leading order
            elif order == 0:
                depth = self.input.v('grid', 'low', 'z', x=0) - self.input.v('grid', 'high', 'z', x=0)
                Av0[:, 0] = 0.49 * roughness.v('Roughness', range(0, jmax + 1)) * depth

            # Higher orders
            else:
                depth = self.input.v('zeta'+str(order-1), range(0, jmax+1), 0, range(0, fmax+1))
                for submod in self.ignoreSubmodule:
                    try:
                        depth -= self.input.v('zeta'+str(order-1), submod, range(0, jmax+1), 0, range(0, fmax+1))
                    except:
                        pass
                Av0[:, :] = 0.49 * roughness.v('Roughness', range(0, jmax + 1)).reshape((jmax+1, 1)) * self.input.v('zeta'+str(order-1), range(0, jmax+1), 0, range(0, fmax+1))

            #   background eddy viscosity
            if order < 1:       # i.e. None or 0
                Av0[:, 0] = np.maximum(Av0[:, 0], Avmin)

            #   adjust time dependence (NB no risk of negative eddy viscosity if zeta < H+R)
            Av0[:, 1:] = self.timedependence*Av0[:, 1:]

            #   put data in output variables
            data = self.input.slice('grid')
            data.addData('coef', Av0)
            if order == 0:
                Av = UniformXF(['x', 'f'], data, 1.).function
            else:
                Av = UniformXF(['x', 'f'], data, 0.).function

            ## 2. Roughness
            if order == 0 or order==None:
                sf0 = np.zeros((jmax + 1, fmax + 1))
                sf0[:, 0] = roughness.v('Roughness', range(0, jmax+1))

                dataRough = self.input.slice('grid')
                dataRough.addData('coef', sf0)

                roughness = UniformXF(['x', 'f'], dataRough, 0.).function
            else:
                roughness = 0.

            ## 3. Boundary type
            BottomBC = 'PartialSlip'

            # No iteration required unless the reference level is computed
            if self.referenceLevel == 'False':
                self.difference = 0.

        ################################################################################################################
        ## case 1b: constant + z0* (non-linear)
        ################################################################################################################
        elif self.roughnessParameter in ['z0*']:
            # 1. prepare coefficients
            z0st = roughness.v('Roughness', range(0, jmax + 1))
            Cd_div_k2 = (((1. + z0st) * np.log(1. / z0st + 1) - 1) ** -2.).reshape(jmax + 1, 1)

            Av0 = 0.10 / 0.636 * Cd_div_k2 * uabsH[:, 0, :]
            sf0 = 0.22 / 0.636 * Cd_div_k2 * uabs[:, 0, :]

            #   background eddy viscosity
            if order < 1:       # i.e. None or 0
                Av0[:, 0] = np.maximum(Av0[:,0], self.Avmin)
                depth = self.input.v('grid', 'low', 'z', x=0) - self.input.v('grid', 'high', 'z', x=0)
                sf0[:, 0] = np.maximum(sf0[:,0], self.Avmin*2/depth)       # minimum sf = 2*Avmin/H (relation from case 1a)

            #   remove time dependence if required
            Av0[:, 1:] = self.timedependence*Av0[:, 1:]
            sf0[:, 1:] = self.timedependence*sf0[:, 1:]

            #   correct possible negative eddy viscosity
            Av0 = self.positivity_correction('Av', Av0, order, False)
            sf0 = self.positivity_correction('Roughness', sf0, order, False)

            sf0t = ny.invfft2(sf0, 1, 90)
            Av0t = ny.invfft2(Av0, 1, 90)
            ind = 0
            while (sf0t<0).any() and ind < 50:
                sf0 = self.positivity_correction('Roughness', sf0, order, False)
                sf0t = ny.invfft2(sf0, 1, 90)
                ind += 1
            if ind == 50:
                raise KnownError('sf not sufficiently corrected for positivity')
            ind = 0
            while (Av0t<0).any() and ind < 50:
                Av0 = self.positivity_correction('Av', Av0, order, False)
                Av0t = ny.invfft2(Av0, 1, 90)
                ind += 1
            if ind == 50:
                raise KnownError('Av not sufficiently corrected for positivity')

            # 2. prepare smaller DataContainers
            data = self.input.slice('grid')
            data.addData('coef', Av0)

            dataRough = self.input.slice('grid')
            dataRough.addData('coef', sf0)

            # 3. prepare functions
            Av = UniformXF(['x', 'f'], data, 0.).function
            roughness = UniformXF(['x', 'f'], dataRough, 0.).function
            BottomBC = 'PartialSlip'

        else:
            raise KnownError('Combination of turbulence profile and roughness parameter is not implemented')

        return Av, roughness, BottomBC