示例#1
0
def pickleload(filepath, variables):
    d = {}
    if filepath[-2:] != '.p':
        filepath = filepath + '.p'

    try:
        with open(filepath, 'rb') as fp:
            alldata = pickle.load(fp)
    except IOError as e:
        raise KnownError('Could not find file %s' % (filepath), e)
    except pickle.UnpicklingError as e:
        raise KnownError(
            'File %s is not a valid Pickle file and cannot be loaded.' %
            (filepath), e)

    # Check if requested variables are available and load them to dict d
    if variables is None:
        variables = alldata.keys()
        d = alldata
    else:
        for key in variables:
            # verify that requested key exists, else raise an exception
            if key not in alldata:
                raise KnownError('Could not load variable %s from file %s' %
                                 (key, file))
            # load data
            d[key] = alldata[key]

    # convert instances to functions
    __convertfunction(d, variables)

    return d
示例#2
0
    def run(self):
        if self.input.v('Av') is None:
            raise KnownError(
                'Reference level runs, but cannot find Av.\n'
                'Check if this variable is provided by the module that promisses this and if it is not deleted '
            )

        self.logger.info('Running module ReferenceLevel')

        # Init
        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')

        self.G = self.input.v('G')
        self.bottomBC = self.input.v('BottomBC')

        self.z = np.linspace(0, 1, np.minimum(kmax, 100))
        self.xaxis = self.input.v('grid',
                                  'axis',
                                  'x',
                                  x=np.linspace(0, 1, jmax + 1))
        self.Av = np.real(self.input.v('Av', x=self.xaxis, z=self.z, f=0))
        self.H = self.input.v('H', x=self.xaxis)
        self.sf = np.real(self.input.v('Roughness', x=self.xaxis, z=0, f=0))
        B = self.input.v('B', x=self.xaxis)

        # Construct reference level by stepping from x=0 towards x=L
        R = np.zeros((jmax + 1))
        x = ny.dimensionalAxis(self.input.slice('grid'), 'x')[:, 0, 0]
        dx = x[1:] - x[0:-1]
        R[0] = 0.
        for j in range(0, jmax):
            c = self.uSolver(j, R[j]) * B[j]
            b = self.uSolver2(j, R[j]) * B[j] * dx[j]
            a = self.uSolver3(j, R[j]) * B[j] * (dx[j]**2)
            Rx_all = np.roots([a, b, c, self.Q])
            for Rx in Rx_all:
                if np.imag(Rx) == 0:
                    Rx = np.real(Rx)
                    break
            R[j + 1] = R[j] + Rx * dx[j]

        # if self.input.v('zeta1', range(0, jmax+1), 0, 0) is not None:
        #     R = R+self.input.v('zeta1', range(0, jmax+1), 0, 0)-self.input.v('zeta1','river', range(0, jmax+1), 0, 0)

        # Compute convergence
        self.difference = np.linalg.norm(
            R - self.input.v('R', range(0, jmax + 1)), np.inf)

        d = {}
        d['R'] = np.maximum(R, -self.H + 0.2)

        return d
    def availability(self, F, T, G, alpha1, alpha2):
        """Calculates the solution to the bed-evolution equation: the erodibility and availability of sediment

        Parameters:
            F - diffusive coefficient in the availability equation that goes with a_x
            T - coefficient (advective, diffusive and stokes) in the availability equation that goes with a

        Returns:
            a - availability of sediment
            f - erodibility of sediment
        """
        ################################################################################################################
        ## Init
        ################################################################################################################
        jmax = self.input.v('grid', 'maxIndex', 'x')
        B = self.input.v('B', range(0, jmax + 1), 0, 0)
        x = ny.dimensionalAxis(self.input, 'x')[:, 0, 0]
        dx = x[1:] - x[:-1]

        ################################################################################################################
        ## Solution to bed-evolution equation
        ################################################################################################################
        ## analytical solution
        if np.all(G == 0):
            P = np.zeros(jmax+1)
        else:
            P = integrate.cumtrapz(G / (F - 10 ** -6) * np.exp(integrate.cumtrapz(T / F, dx=dx, axis=0, initial=0)), dx=dx, axis=0, initial=0)

        exponent = np.exp(-integrate.cumtrapz(T / F, dx=dx, axis=0, initial=0))

        # Boundary conditions (analytical solution)
            # BC 1: total amount of sediment in the system
        if self.input.v('sedbc') == 'astar':
            astar = self.input.v('astar')
            k = (astar * np.trapz(B, dx=dx, axis=0) / np.trapz(B * exponent, dx=dx, axis=0))

            # BC 2: concentration at the seaward boundary
        elif self.input.v('sedbc') == 'csea':
            csea = self.input.v('csea')
            c000 = alpha1[0]
            k = csea / c000 * (self.input.v('grid', 'low', 'z', 0) - self.input.v('grid', 'high', 'z', 0))

            # BC 3: incorrect boundary description
        else:
            from src.util.diagnostics.KnownError import KnownError
            raise KnownError('incorrect seaward boundary type (sedbc) for sediment module')

        # final solution (analytical)
        f0uncap = (k - P) * exponent

        ## Check if f<1 everywhere,
        # if not compute numerical solution instead with a time-stepping routine that maximises f at 1.
        if all(f0uncap < 1):
            f0 = f0uncap
        else:
            f0, Smod = self.availability_numerical(np.real(T), np.real(F), np.real(f0uncap), k, alpha1, alpha2, G)

        ## compute derivative
        if np.all(G == 0) and all(f0uncap < 1):
            f0x = -T / F * f0uncap  # only use analytical derivative in case with no fluvial source of sediment and f<1; else not reliable.
        else:
            f0x = ny.derivative(f0, 'x', self.input.slice('grid'))

        return f0uncap, f0, f0x
示例#4
0
    def run(self):
        self.logger.info('Running module StaticAvailability')

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

        c0 = self.input.v('hatc0', 'a', range(0, jmax + 1), range(0, kmax + 1),
                          range(0, fmax + 1))
        c1_a0 = self.input.v('hatc1', 'a', range(0, jmax + 1),
                             range(0, kmax + 1), range(0, fmax + 1))
        c1_a0x = self.input.v('hatc1', 'ax', range(0, jmax + 1),
                              range(0, kmax + 1), range(0, fmax + 1))
        if isinstance(c1_a0x, bool):
            c1_a0x = np.zeros((jmax + 1, kmax + 1, fmax + 1))

        d = {}

        c0_int = ny.integrate(c0, 'z', kmax, 0, self.input.slice('grid'))
        B = self.input.v('B', range(0, jmax + 1), [0], [0])
        u0 = self.input.v('u0', range(0, jmax + 1), range(0, kmax + 1),
                          range(0, fmax + 1))
        zeta0 = self.input.v('zeta0', range(0, jmax + 1), [0],
                             range(0, fmax + 1))
        Kh = self.input.v('Kh', range(0, jmax + 1), [0], [0])

        ################################################################################################################
        ## Second order closure
        ################################################################################################################
        u1 = self.input.v('u1', range(0, jmax + 1), range(0, kmax + 1),
                          range(0, fmax + 1))

        d['T'] = {}
        d['F'] = {}
        T0 = 0
        F0 = 0

        ## Transport T  ############################################################################################
        ## T.1. - u0*c1_a0
        # Total
        c1a_f0 = c1_a0
        T0 += ny.integrate(ny.complexAmplitudeProduct(u0, c1a_f0, 2), 'z',
                           kmax, 0, self.input.slice('grid'))

        # Decomposition
        for submod in self.input.getKeysOf('hatc1', 'a'):
            if submod == 'erosion':
                for subsubmod in self.input.getKeysOf('hatc1', 'a', 'erosion'):
                    c1_a0_comp = self.input.v('hatc1', 'a', submod, subsubmod,
                                              range(0, jmax + 1),
                                              range(0, kmax + 1),
                                              range(0, fmax + 1))
                    c1a_f0_comp_res = c1_a0_comp
                    d['T'] = self.dictExpand(
                        d['T'], subsubmod,
                        ['TM' + str(2 * n) for n in range(0, fmax + 1)
                         ])  # add submod index to dict if not already
                    # transport with residual availability
                    for n in range(0, fmax + 1):
                        tmp = np.zeros(c1a_f0_comp_res.shape, dtype=complex)
                        tmp[:, :, n] = c1a_f0_comp_res[:, :, n]
                        tmp = ny.integrate(
                            ny.complexAmplitudeProduct(u0, tmp, 2), 'z', kmax,
                            0, self.input.slice('grid'))[:, 0, 0]
                        if any(abs(tmp)) > 10**-14:
                            d['T'][subsubmod]['TM' + str(2 * n)] += tmp
            else:
                c1_a0_comp = self.input.v('hatc1', 'a', submod,
                                          range(0,
                                                jmax + 1), range(0, kmax + 1),
                                          range(0, fmax + 1))
                c1a_f0_comp_res = c1_a0_comp
                d['T'] = self.dictExpand(
                    d['T'], submod,
                    ['TM' + str(2 * n) for n in range(0, fmax + 1)
                     ])  # add submod index to dict if not already
                # transport with residual availability
                for n in range(0, fmax + 1):
                    tmp = np.zeros(c1a_f0_comp_res.shape, dtype=complex)
                    tmp[:, :, n] = c1a_f0_comp_res[:, :, n]
                    tmp = ny.integrate(ny.complexAmplitudeProduct(u0, tmp, 2),
                                       'z', kmax, 0,
                                       self.input.slice('grid'))[:, 0, 0]
                    if any(abs(tmp)) > 10**-14:
                        d['T'][submod]['TM' + str(2 * n)] += tmp

        ## T.2. - u1*c0
        # Total
        T0 += ny.integrate(ny.complexAmplitudeProduct(u1, c0, 2), 'z', kmax, 0,
                           self.input.slice('grid'))

        # Decomposition
        for submod in self.input.getKeysOf('u1'):
            u1_comp = self.input.v('u1', submod, range(0, jmax + 1),
                                   range(0, kmax + 1), range(0, fmax + 1))
            d['T'] = self.dictExpand(
                d['T'], submod,
                ['TM' + str(2 * n) for n in range(0, fmax + 1)
                 ])  # add submod index to dict if not already
            # transport with residual availability
            for n in range(0, fmax + 1):
                tmp = np.zeros(u1_comp.shape, dtype=complex)
                tmp[:, :, n] = u1_comp[:, :, n]
                if submod == 'stokes':
                    tmp = ny.integrate(ny.complexAmplitudeProduct(tmp, c0, 2),
                                       'z', kmax, 0,
                                       self.input.slice('grid'))[:, 0, 0]
                    if any(abs(tmp)) > 10**-14:
                        d['T'][submod] = self.dictExpand(
                            d['T'][submod], 'TM' + str(2 * n),
                            ['return', 'drift'])
                        d['T'][submod]['TM0']['return'] += tmp
                else:
                    tmp = ny.integrate(ny.complexAmplitudeProduct(tmp, c0, 2),
                                       'z', kmax, 0,
                                       self.input.slice('grid'))[:, 0, 0]
                    if any(abs(tmp)) > 10**-14:
                        d['T'][submod]['TM' + str(2 * n)] += tmp

        ## T.5. - u0*c0*zeta0
        # Total
        T0 += ny.complexAmplitudeProduct(
            ny.complexAmplitudeProduct(u0[:, [0], :], c0[:, [0], :], 2), zeta0,
            2)

        # Decomposition
        uzeta = ny.complexAmplitudeProduct(u0[:, [0], :], zeta0, 2)
        d['T'] = self.dictExpand(
            d['T'], 'stokes', ['TM' + str(2 * n) for n in range(0, fmax + 1)])
        # transport with residual availability
        for n in range(0, fmax + 1):
            tmp = np.zeros(c0[:, [0], :].shape, dtype=complex)
            tmp[:, :, n] = c0[:, [0], n]
            tmp = ny.complexAmplitudeProduct(uzeta, tmp, 2)[:, 0, 0]
            if any(abs(tmp)) > 10**-14:
                d['T']['stokes']['TM' + str(2 * n)]['drift'] += tmp

        ## T.6. - u1riv*c2rivriv
        c2 = self.input.v('hatc2', 'a', 'erosion', 'river_river',
                          range(0, jmax + 1), range(0, kmax + 1),
                          range(0, fmax + 1))
        u1riv = self.input.v('u1', 'river', range(0, jmax + 1),
                             range(0, kmax + 1), range(0, fmax + 1))
        if u1riv is not None:
            d['T'] = self.dictExpand(
                d['T'], 'river_river',
                'TM0')  # add submod index to dict if not already
            tmp = ny.integrate(ny.complexAmplitudeProduct(u1riv, c2, 2), 'z',
                               kmax, 0, self.input.slice('grid'))
            if any(abs(tmp[:, 0, 0])) > 10**-14:
                d['T']['river_river']['TM0'] = tmp[:, 0, 0]

            T0 += tmp

        ## T.7. - diffusive part
        # Total
        c0x = self.input.d('hatc0',
                           'a',
                           range(0, jmax + 1),
                           range(0, kmax + 1),
                           range(0, fmax + 1),
                           dim='x')
        T0 += -Kh * ny.integrate(c0x, 'z', kmax, 0, self.input.slice('grid'))

        c2x = self.input.d('hatc2',
                           'a',
                           'erosion',
                           'river_river',
                           range(0, jmax + 1),
                           range(0, kmax + 1),
                           range(0, fmax + 1),
                           dim='x')
        T0 += -Kh * ny.integrate(c2x, 'z', kmax, 0, self.input.slice('grid'))

        # Decomposition
        d['T'] = self.dictExpand(d['T'], 'diffusion_tide', ['TM0'])
        d['T'] = self.dictExpand(d['T'], 'diffusion_river', ['TM0'])
        # transport with residual availability
        tmp = -(Kh * ny.integrate(c0x, 'z', kmax, 0,
                                  self.input.slice('grid')))[:, 0, 0]
        if any(abs(tmp)) > 10**-14:
            d['T']['diffusion_tide']['TM0'] = tmp
        tmp = -(Kh * ny.integrate(c2x, 'z', kmax, 0,
                                  self.input.slice('grid')))[:, 0, 0]
        if any(abs(tmp)) > 10**-14:
            d['T']['diffusion_river']['TM0'] = tmp

        ## Diffusion F  ############################################################################################
        ## F.1. - u0*C1ax*f0
        # Total
        F0 += ny.integrate(ny.complexAmplitudeProduct(u0, c1_a0x, 2), 'z',
                           kmax, 0, self.input.slice('grid'))

        # Decomposition
        for submod in self.input.getKeysOf('hatc1', 'ax'):
            c1_ax0_comp = self.input.v('hatc1', 'ax', submod,
                                       range(0, jmax + 1), range(0, kmax + 1),
                                       range(0, fmax + 1))
            d['F'] = self.dictExpand(
                d['F'], submod,
                ['FM' + str(2 * n) for n in range(0, fmax + 1)
                 ])  # add submod index to dict if not already
            # transport with residual availability
            for n in range(0, fmax + 1):
                tmp = np.zeros(u0.shape, dtype=complex)
                tmp[:, :, n] = u0[:, :, n]
                tmp = ny.integrate(
                    ny.complexAmplitudeProduct(tmp, c1_ax0_comp, 2), 'z', kmax,
                    0, self.input.slice('grid'))[:, 0, 0]
                if any(abs(tmp)) > 10**-14:
                    d['F'][submod]['FM' + str(2 * n)] += tmp

        ## F.3. - diffusive part
        # Total
        F0 += -Kh * ny.integrate(c0, 'z', kmax, 0, self.input.slice('grid'))
        F0 += -Kh * ny.integrate(c2, 'z', kmax, 0, self.input.slice('grid'))

        # Decomposition
        d['F'] = self.dictExpand(d['F'], 'diffusion_tide', ['FM0'])
        d['F'] = self.dictExpand(d['F'], 'diffusion_river', ['FM0'])
        # transport with residual availability
        tmp = -(Kh * ny.integrate(c0, 'z', kmax, 0,
                                  self.input.slice('grid')))[:, 0, 0]
        if any(abs(tmp)) > 10**-14:
            d['F']['diffusion_tide']['FM0'] = tmp
        tmp = -(Kh * ny.integrate(c2, 'z', kmax, 0,
                                  self.input.slice('grid')))[:, 0, 0]
        if any(abs(tmp)) > 10**-14:
            d['F']['diffusion_river']['FM0'] = tmp

        ## Solve    ################################################################################################
        ## Add all mechanisms & compute a0c
        from src.DataContainer import DataContainer
        dc = DataContainer(d)
        dc.merge(self.input.slice('grid'))
        T_til = np.real(dc.v('T', range(0, jmax + 1)))
        F_til = np.real(dc.v('F', range(0, jmax + 1)))

        # DEBUG: CHECKS IF COMPOSITE T, F == total T, F
        # print np.max(abs((dc.v('T', range(0, jmax+1))-T0[:, 0, 0])/(T0[:, 0, 0]+10**-10)))
        # print np.max(abs((dc.v('F', range(0, jmax+1))-F0[:, 0, 0])/(F0[:, 0, 0]+10**-10)))

        integral = -ny.integrate(T_til / (F_til - 10**-6), 'x', 0,
                                 range(0, jmax + 1), self.input.slice('grid'))
        if self.input.v('Qsed') is None:
            G = 0
        else:
            G = self.input.v('Qsed') / B[-1, 0, 0]

        P = ny.integrate(G / (F_til - 10**-6) * np.exp(-integral), 'x', 0,
                         range(0, jmax + 1), self.input.slice('grid'))
        ################################################################################################################
        # Boundary condition 1
        ################################################################################################################
        if self.input.v('sedbc') == 'astar':
            astar = self.input.v('astar')
            k = astar * ny.integrate(B[:, 0, 0], 'x', 0, jmax,
                                     self.input.slice('grid')) / ny.integrate(
                                         B[:, 0, 0] * np.exp(integral), 'x', 0,
                                         jmax, self.input.slice('grid'))

            f0 = (k - P) * np.exp(integral)
            f0x = (-T_til * f0 - G) / (F_til - 10**-6)

        ################################################################################################################
        # Boundary condition 2
        ################################################################################################################
        elif self.input.v('sedbc') == 'csea':
            csea = self.input.v('csea')
            c000 = np.real(c0_int[0, 0, 0])
            k = csea / c000 * (self.input.v('grid', 'low', 'z', 0) -
                               self.input.v('grid', 'high', 'z', 0))
            f0 = (k - P) * np.exp(integral)
            f0x = (-T_til * f0 - G) / (F_til - 10**-6)

        else:
            from src.util.diagnostics.KnownError import KnownError
            raise KnownError(
                'sediment boundary sedbc not known: use astar or csea')

        ################################################################################################################
        # Store in dict
        ################################################################################################################
        d['a'] = f0
        d['c0'] = c0 * f0.reshape((jmax + 1, 1, 1))
        d['c1'] = c1_a0 * f0.reshape((jmax + 1, 1, 1)) + c1_a0x * f0x.reshape(
            (jmax + 1, 1, 1))
        d['c2'] = c2 * f0.reshape((jmax + 1, 1, 1))

        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
示例#6
0
    def run(self):
        measurementset = self.input.v('measurementset')
        data = self.input.getKeysOf('experimentdata')
        calib_param = ny.toList(self.input.v('calibration_parameter'))
        label = ny.toList(self.input.v('label'))
        unit_temp = ny.toList(self.input.v('unit'))
        unit = []
        for u in unit_temp:
            if u == '-':
                unit.append('')
            else:
                unit.append('($' + u + '$)')
        if len(calib_param) == 1:
            param_range = [[]]
        elif len(calib_param) == 2:
            param_range = [[], []]
        else:
            raise KnownError(
                'ManualCalibration not implemented for calibration with more than 3 parameters.'
            )

        # inital loop to determine the parameter ranges
        for i, dat in enumerate(data):
            dc = self.input.v('experimentdata', dat)
            for j in range(0, len(calib_param)):
                param_range[j].append(dc.v(calib_param[j]))
        for j in range(0, len(calib_param)):
            param_range[j] = sorted(list(set(param_range[j])))

        # second loop to determine the values per parameter setting
        cost_range = np.nan * np.zeros([len(l) for l in param_range] + [2])
        for dat in data:
            dc = self.input.v('experimentdata', dat)
            index = [
                l.index(dc.v(calib_param[i]))
                for i, l in enumerate(param_range)
            ]

            L = dc.v('grid', 'high', 'x')
            H0 = dc.n('grid', 'high', 'z', x=0)
            dc.merge(self.input.slice(measurementset))
            x_obs = dc.v(measurementset, 'x_waterlevel') / L
            x_ext = np.zeros(len(x_obs) + 2)
            x_ext[1:-1] = x_obs
            x_ext[0] = 0
            x_ext[-1] = 1
            zeta_obs = dc.v(measurementset, 'zeta', x=x_obs, z=0, f=[1, 2])

            # Start fix
            # zeta_obs = dc.data[measurementset]['zeta'].im_self.dataContainer.data['value'][:,1:3] #fix
            # from copy import deepcopy                                                                     #fix
            # newgrid = deepcopy(dc.data['zeta0']['tide'].im_self.dataContainer.data['grid']['outputgrid']) #fix
            # i = 0
            # while i is not None:
            #     try:
            #         keys = dc.data['zeta'+str(i)].keys()
            #         for key in keys:
            #             if i<2:
            #                 dc.data['zeta'+str(i)][key].im_self.dataContainer.data['grid'] = newgrid
            #             else:
            #                 keys2 =dc.data['zeta'+str(i)][key].keys()
            #                 for key2 in keys2:
            #                     dc.data['zeta'+str(i)][key][key2].im_self.dataContainer.data['grid'] = newgrid
            #         i += 1
            #     except:
            #         i = None
            # End fix

            zeta_mod = 0
            i = 0
            while True:
                if dc.v('zeta' + str(i), x=x_obs, z=0, f=[1, 2]) is not None:
                    zeta_mod += dc.v('zeta' + str(i), x=x_obs, z=0, f=[1, 2])
                    i += 1
                else:
                    break
                if i > 3:
                    break

            cost_range[tuple(index) + (0, )] = cost_function_DJ96(
                x_ext, zeta_obs[:, 0], zeta_mod[:, 0])
            cost_range[tuple(index) + (1, )] = cost_function_DJ96(
                x_ext, zeta_obs[:, 1], zeta_mod[:, 1])

        st.configure()
        # 1D plots
        if len(calib_param) == 1:
            try:
                minlocM2 = [
                    param_range[0][np.where(
                        cost_range[:, 0] == np.min(cost_range[:, 0]))[0]]
                ]
                minlocM4 = [
                    param_range[0][np.where(
                        cost_range[:, 1] == np.min(cost_range[:, 1]))[0]]
                ]
            except:
                minlocM2 = [np.nan]
                minlocM4 = [np.nan]
            print 'Minumim $M_2$: '
            print calib_param[0] + ' ' + str(minlocM2[0])
            print 'Minumim $M_4$: '
            print calib_param[0] + ' ' + str(minlocM4[0])

            if self.input.v('axis') == 'log':
                axis = np.log10(param_range[0])
                label = '$log_{10}$($' + label[0] + '$)' + unit[0]
                minlocM2 = np.log10(minlocM2)
                minlocM4 = np.log10(minlocM4)
            else:
                axis = param_range[0]
                label = '$' + calib_param[0] + '$' + unit[0]

            plt.figure(1, figsize=(1, 1))
            plt.plot(axis, cost_range[:, 0], 'k.')
            plt.plot(minlocM2[0], np.min(cost_range[:, 0]), 'ro')
            plt.xlabel(label)
            plt.ylabel('Cost $M_2$')
            plt.yticks([], [])
            plt.ylim(0, max(cost_range[:, 0]))

            plt.figure(2, figsize=(1, 1))
            plt.plot(axis, cost_range[:, 1], 'k.')
            plt.plot(minlocM4[0], np.min(cost_range[:, 1]), 'ro')
            plt.xlabel(label)
            plt.ylabel('Cost $M_4$')
            plt.yticks([], [])
            plt.ylim(0, max(cost_range[:, 1]))

        # 2D plots
        elif len(calib_param) == 2:
            try:
                minlocM2 = [
                    param_range[0][np.where(
                        cost_range[:, :, 0] == np.min(cost_range[:, :,
                                                                 0]))[0]],
                    param_range[1][np.where(
                        cost_range[:, :, 0] == np.min(cost_range[:, :, 0]))[1]]
                ]
                minlocM4 = [
                    param_range[0][np.where(
                        cost_range[:, :, 1] == np.min(cost_range[:, :,
                                                                 1]))[0]],
                    param_range[1][np.where(
                        cost_range[:, :, 1] == np.min(cost_range[:, :, 1]))[1]]
                ]
            except:
                minlocM2 = [np.nan, np.nan]
                minlocM4 = [np.nan, np.nan]
            print 'Minumim $M_2$: '
            print calib_param[0] + ' ' + str(minlocM2[0])
            print calib_param[1] + ' ' + str(minlocM2[1])
            print 'Minumim $M_4$: '
            print calib_param[0] + ' ' + str(minlocM4[0])
            print calib_param[1] + ' ' + str(minlocM4[1])

            if self.input.v('axis') == 'log':
                axis1 = np.log10(param_range[0])
                axis2 = np.log10(param_range[1])
                label1 = '$log_{10}$($' + label[0] + '$)' + unit[0]
                label2 = '$log_{10}$($' + label[1] + '$)' + unit[1]
                minlocM2 = [np.log10(i) for i in minlocM2]
                minlocM4 = [np.log10(i) for i in minlocM4]
            else:
                axis1 = param_range[0]
                axis2 = param_range[1]
                label1 = '$' + label[0] + '$' + unit[0]
                label2 = '$' + label[1] + '$' + unit[1]
            plt.figure(1, figsize=(1, 1))
            plt.hold(True)
            plt.contourf(axis1, axis2, np.transpose(cost_range[:, :, 0]), 30)

            plt.plot(minlocM2[0], minlocM2[1], 'ro')
            # plt.plot(axis1, np.log10(0.5*10**axis2*H0), 'r')
            plt.xlim(min(axis1), max(axis1))
            plt.ylim(min(axis2), max(axis2))
            # plt.plot(np.log10(0.003), np.log10(0.061), 'yo')  # best Scheldt calibration
            # plt.plot(np.log10(0.098), np.log10(0.019), 'yo')  # best Ems1981 calibration
            plt.title('Cost $M_2$')
            plt.xlabel(label1)
            plt.ylabel(label2)
            #plt.colorbar()

            plt.figure(2, figsize=(1, 1))
            plt.hold(True)
            plt.plot(minlocM4[0], minlocM4[1], 'ro')
            plt.contourf(axis1, axis2, np.transpose(cost_range[:, :, 1]), 30)
            # plt.plot(axis1, np.log10(0.5*10**axis2*H0), 'r')
            plt.xlim(min(axis1), max(axis1))
            plt.ylim(min(axis2), max(axis2))
            plt.title('Cost $M_4$')
            plt.xlabel(label1)
            plt.ylabel(label2)
            #plt.colorbar()

        st.show()

        d = {}
        return d