Пример #1
0
    def __init__(self, raw, seg, gt=None, patchSize=[100, 100], **kwargs):

        #raw input data
        self.raw = numpy.squeeze(raw)
        self.seg = numpy.squeeze(seg)
        self.gt = numpy.squeeze(gt)

        # shorthands
        self.shape = self.raw.shape

        # settings
        self.patchSize = patchSize

        # apply paddings
        ps = self.patchSize
        padding = ((ps[0], ps[0]), (ps[1], ps[1]))
        pad = partial(numpy.pad, pad_width=padding)

        self.paddingMask = pad(numpy.zeros(self.shape),
                               mode='constant',
                               constant_values=1)
        self.paddedRaw = pad(self.raw, mode='reflect')
        self.paddedSeg = vigra.analysis.labelImage(
            pad(self.seg, mode='reflect')).squeeze()
        self.paddedGt = None
        if self.gt is not None:
            self.paddedGt = vigra.analysis.labelImage(
                pad(self.gt, mode='reflect')).squeeze()
            #self.paddedGt = pad(self.gt + 1, mode='constant', constant_values=0)

        # compute cgp
        self.tGrid = ncgp.TopologicalGrid2D(self.paddedSeg)
        self.tShape = self.tGrid.topologicalGridShape
        self.numberOfCells = self.tGrid.numberOfCells
        self.fGrid = ncgp.FilledTopologicalGrid2D(self.tGrid)
        self.cellGrids = [
            self.fGrid.cellMask([1, 0, 0]),
            self.fGrid.cellMask([0, 1, 0]), None
        ]
        self.cellGrids[0][
            self.cellGrids[0] != 0] -= self.fGrid.cellTypeOffset[0]
        self.cellGrids[1][
            self.cellGrids[1] != 0] -= self.fGrid.cellTypeOffset[1]

        self.cellMasks = [numpy.clip(x, 0, 1)
                          for x in self.cellGrids[0:2]] + [None]
        rawT = vigra.sampling.resize(self.paddedRaw, self.tShape)
        #rawT[self.cellMasks[1]!=0] = 0

        self.cellsBounds = self.tGrid.extractCellsBounds()
        self.cellsGeometry = self.tGrid.extractCellsGeometry(fill=True)
        self.cells1Bounds = self.cellsBounds[1]
        self.cells1Geometry = self.cellsGeometry[1]

        # center of mass
        self.cell1CentersOfMass = self.cells1Geometry.centersOfMass()

        print(self.cell1CentersOfMass)

        # compute gt
        ol = Overlap(self.numberOfCells[2], self.paddedSeg, self.paddedGt)
        cell1Probs = ol.differentOverlaps(numpy.array(self.cells1Bounds))

        with nifty.Timer("makeCellImage"):
            probImg = ncgp.makeCellImage(rawT, self.cellGrids[1],
                                         cell1Probs * 255.0)

        vigra.imshow(probImg.astype('uint8'), cmap='gist_heat')
        vigra.show()

        if False:
            vigra.imshow(self.paddingMask)
            vigra.show()

            vigra.imshow(self.paddedRaw)
            vigra.show()

            vigra.segShow(self.paddedRaw, self.paddedSeg)
            vigra.show()

            vigra.segShow(self.paddedRaw, self.paddedGt)
            vigra.show()
Пример #2
0
class EcologyCore:
    # Variables
    logger = logging.getLogger(__name__)
    time = [ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer()]
    DT = 24*3600.*10#0.05

    # Methods
    def __init__(self, input):
        self.input = input
        return

    def main(self, components, ws, Kv, Kh, Csea, QC, S, Gamma, Gamma_factor, source):
        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        taumax = self.input.v('taumax') or 1

        if False:#hasattr(self, 'X'):       #DEBUG
            X = self.X
            spinup = False
        else:
            X = np.zeros((jmax+1, len(components)))
            spinup = True

        # time integration and initial condition
        Chat_prim = np.zeros((jmax+1, kmax+1, len(components)))
        Chat_int = np.zeros((jmax+1, len(components)))
        Ts = np.zeros((jmax+1, len(components)))
        Fs = np.zeros((jmax+1, len(components)))
        Hs = np.zeros((jmax+1, len(components)))
        Chat = np.zeros((jmax+1, kmax+1, len(components)))

        ################################################################################################################
        # Compute transport rates & potential concentrations
        ################################################################################################################
        dc = self.input.slice('grid')
        for i, comp_name in enumerate(components):
            T, F, Hs[:, i], Chat[:, :, i] = self.component(ws[i], Kv[i], Kh[i])
            dc.merge({comp_name: {'T': T}})
            dc.merge({comp_name: {'F': F}})
            Ts[:, i] = dc.v(comp_name, 'T', range(0, jmax+1))
            Fs[:, i] = dc.v(comp_name, 'F', range(0, jmax+1))

            # integrals
            Chat_prim[:, :, i] = -ny.primitive(np.real(Chat[:, :, i]), 'z', 0, kmax, self.input.slice('grid'))   # primitive counted from surface
            Chat_int[:, i] = np.sum(Chat_prim[:, :, i], axis=1)

        ## process growth function so that no duplicate computations are done
        Gamma_flat = [item for sublist in Gamma for item in sublist]
        Gamma_list = list(set(Gamma_flat))
        Gamma_index = [[Gamma_list.index(i) for i in j] for j in Gamma]

        ################################################################################################################
        # Initial conditions
        ################################################################################################################
        if spinup:
            for i, comp_name in enumerate(components):
                if i==0:
                    P0 = Csea[i]*np.exp(-10*np.linspace(0, 1, jmax+1))
                    H = self.input.v('grid', 'low', 'z', range(0, jmax+1)) - self.input.v('grid', 'high', 'z', range(0, jmax+1))
                    X[:, i] = P0/np.real(ny.integrate(Chat[:, :, i], 'z', kmax, 0, self.input.slice('grid'))[:, 0])*H
                else:
                    # initial condition (equilibrium without growth)
                    integrand = ny.integrate(Ts[:, i]/(Fs[:, i]), 'x', 0, range(0, jmax+1), self.input.slice('grid'))
                    P = QC[i]/(Fs[:, i])*np.exp(integrand.reshape((jmax+1, 1))*np.ones((1, jmax+1))-integrand.reshape((1, jmax+1)))
                    Pint = ny.integrate(P.reshape((jmax+1, 1, 1, jmax+1)), 'x', 0, range(0, jmax+1), self.input.slice('grid'))
                    Pint = Pint[range(0, jmax+1), 0, 0, range(0, jmax+1)]
                    C0 = np.exp(-integrand)*Csea[i] + Pint
                    X[:, i] = C0/Chat_int[:, i]*H

            self.Xprev = np.ones(X.shape)*np.inf

        ################################################################################################################
        # Time integration
        ################################################################################################################
        init_growth = True
        ctd = True

        # set time step
        if not spinup and self.input.v('dtau'):
            dtau = self.input.v('dtau')*24*3600.
            tau = np.linspace(0, dtau, np.ceil(dtau/self.DT)+1)
            i_tau_now = 0
            dt = tau[1]-tau[0]
        else:
            dt = self.DT
            spinup = True

        # run time stepping
        dind = 0                    # index for the iteration number
        self.dif_prev = np.inf      # difference in previous step (only in spin-up)
        while ctd:
            dind +=1
            ## Growth functions
            Gamma_eval = [fun(Chat, Chat_prim, Chat_int, X[:, :], init_growth) for fun in Gamma_list]
            init_growth = False
            Gamma_sum = [self.sumdict(copy(j)) for j in Gamma_eval]

            Gamma = [[Gamma_sum[i] for i in j] for j in Gamma_index]
            for i, comp_name in enumerate(components):
                G = sum([a*b for a,b in zip(Gamma_factor[i], Gamma[i])])
                G += source[:, i]
                X[:, i] = cSolverTime(Ts[:, i], Fs[:, i], np.zeros(jmax+1), G, Hs[:, i], Hs[:, i]*X[:, i], X[0, i], 'flux', QC[i], dt, X[:, i], self.input)

            if spinup:
                dif = self.DT/dt*np.linalg.norm((X - self.Xprev)/(X+0.001*np.max(X)), np.inf)
                print dind, dif

                ## DEBUG
                # if np.max(X[:, 0]) > 50/1000. and dind > 100:
                #     print 'exit simulation; non-realistic result'
                #     ctd = False
                #     X = np.nan*X
                ## END
                # print dif
                if dif < 10**-5 or dind>2000:#10**-8:
                    ctd = False
                elif self.dif_prev < dif and dind > 100:                                     # adjust time step if diffence increases after 200th iteration (only in spin-up)
                    dt = dt/2.
                    dind = 0
                    print 'timestep: ' + str(dt)
                else:
                    self.Xprev = copy(X)
                    self.dif_prev = dif
            else:
                i_tau_now += 1
                if i_tau_now == len(tau)-1:
                    ctd = False


        ################################################################################################################
        ## Return
        ################################################################################################################
        self.X = copy(X)

        Gamma = [[Gamma_eval[i] for i in j] for j in Gamma_index]
        # Gamma2 = [0]*len(Gamma)
        # for i in range(0, len(Gamma)):
        #     for j in range(1, len(Gamma[i])):
        #         mergeDicts(Gamma[i][0], Gamma[i][j])
        #     Gamma2[i] = Gamma[i][0]
        d = {}


        d['Ceco'] = {}
        d['Teco'] = {}
        d['Feco'] = {}
        d['Geco'] = {}
        for i, comp_name in enumerate(components):
            d['Ceco'][comp_name] = Chat[:, :, i]*X[:, i].reshape(jmax+1, 1)
            d['Geco'][comp_name] = {}
            for j in range(0, len(Gamma[i])):
                d['Geco'][comp_name].update(Gamma[i][j])
            #      d['Geco'][comp_name] = mergeDicts(d['Geco'][comp_name], Gamma[i][j])
            d['Teco'][comp_name] = dc.data[comp_name]['T']
            d['Feco'][comp_name] = dc.data[comp_name]['F']

        return d

    def update(self, dlist_old, dlist_new):
        return [mergeDicts(dlist_old[j], dlist_new[j]) for j in range(0, len(dlist_old))]

    def sumdict(self, d):
        for k in d.keys():
            if isinstance(d[k], dict):
                d[k] = self.sumdict(d[k])

        return sum(d.values())

    def component(self, ws, Kv, Kh):
        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        fmax = self.input.v('grid', 'maxIndex', 'f')

        z = ny.dimensionalAxis(self.input.slice('grid'), 'z')[:, :, 0]
        depth = (self.input.v('grid', 'low', 'z', range(0, jmax+1)) - self.input.v('grid', 'high', 'z', range(0, jmax+1))).reshape((jmax+1, 1))
        B = self.input.v('B', range(0, jmax+1))

        u0 = self.input.v('u0', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
        w0 = self.input.v('w0', 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))

        ################################################################################################################
        # Leading order
        ################################################################################################################
        Chat = np.zeros((jmax+1, kmax+1, fmax+1), dtype=complex)
        if ws[0,0] != 0:
            k = depth*ws[:, [-1]]/Kv[:, [-1]]*(1-np.exp(-ws[:, [-1]]/Kv[:, [-1]]*depth))**-1.
        else:
            k = 1
        Chat[:, :, 0] = k*np.exp(-ws[:, [-1]]/Kv[:, [-1]]*(z+depth))        # k is such that depth-av Chat = 1.

        Chatx = ny.derivative(Chat, 'x', self.input.slice('grid'))
        Chatz = -(ws[:, [-1]]/Kv[:, [-1]]).reshape((jmax+1, 1, 1))*Chat

        ################################################################################################################
        # First order
        ################################################################################################################
        F = np.zeros((jmax+1, kmax+1, 2*fmax+1, 2), dtype=complex)
        Fsurf = np.zeros((jmax+1, 1, 2*fmax+1, 2), dtype=complex)
        Fbed = np.zeros((jmax+1, 1, 2*fmax+1, 2), dtype=complex)

        ## forcing terms
        # advection
        F[:, :, fmax:, 0] = -ny.complexAmplitudeProduct(u0, Chatx, 2) - ny.complexAmplitudeProduct(w0, Chatz, 2)
        F[:, :, fmax:, 1] = -ny.complexAmplitudeProduct(u0, Chat, 2)

        ## solve
        Chat1, _ = pFunction(1, ws, Kv, F[:, :, fmax+1], Fsurf[:, :, fmax+1], Fbed[:, :, fmax+1], self.input)
        Chat1 = ny.eliminateNegativeFourier(Chat1, 2)

        ################################################################################################################
        # Closure
        ################################################################################################################
        # transport
        T = {}
        T['adv'] = {}
        T['adv']['tide'] = np.real(ny.integrate(ny.complexAmplitudeProduct(u0, Chat1[:, :, :, 0], 2), 'z', kmax, 0, self.input.slice('grid'))[:, 0, 0]*B)
        for key in self.input.getKeysOf('u1'):
            utemp = self.input.v('u1', key, range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
            try:
                T['adv'][key] += np.real(ny.integrate(ny.complexAmplitudeProduct(utemp, Chat, 2), 'z', kmax, 0, self.input.slice('grid'))[:, 0, 0]*B)
            except:
                T['adv'][key] = np.real(ny.integrate(ny.complexAmplitudeProduct(utemp, Chat, 2), 'z', kmax, 0, self.input.slice('grid'))[:, 0, 0]*B)
        T['dif'] = - np.real(ny.integrate(ny.complexAmplitudeProduct(Kh, Chatx, 2), 'z', kmax, 0, self.input.slice('grid'))[:, 0, 0]*B)
        T['noflux'] = np.real(ny.complexAmplitudeProduct(ny.complexAmplitudeProduct(u0[:, [0], :], Chat[:, [0], :], 2), zeta0, 2)[:, 0, 0]*B)

        F = {}
        F['adv'] = {}
        F['adv']['tide'] = np.real(ny.integrate(ny.complexAmplitudeProduct(u0, Chat1[:, :, :, -1], 2), 'z', kmax, 0, self.input.slice('grid'))[:, 0, 0]*B)
        F['dif'] = - np.real(Kh[:, 0]*depth[:, 0]*B)

        H1 = np.real(depth[:, 0]*B)

        return T, F, H1, Chat[:, :, 0]
Пример #3
0
class DynamicAvailability(EquilibriumAvailability):
    # Variables
    logger = logging.getLogger(__name__)
    theta = 1.  # theta=0 is Forward Euler, theta=1 is Backward Euler and theta=0.5 is Crank-Nicolson
    TOL = 1.e-10
    MAXITER = 100
    timer = ny.Timer()

    # Methods
    def __init__(self, input):
        EquilibriumAvailability.__init__(self, input)
        self.input = input
        return

    def run(self):
        """         """
        self.logger.info('Running module DynamicAvailability_upwind')

        ################################################################################################################
        # Init
        ################################################################################################################
        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        fmax = self.input.v('grid', 'maxIndex', 'f')
        self.x = ny.dimensionalAxis(self.input.slice('grid'), 'x')[:, 0, 0]
        self.dx = (self.x[1:] - self.x[:-1])
        self.zarr = ny.dimensionalAxis(self.input.slice('grid'), 'z')[:, :, 0]

        self.B = self.input.v('B', range(0, jmax + 1))
        self.Bx = self.input.d('B', range(0, jmax + 1), dim='x')

        self.Kh = self.input.v('Kh')
        self.u0tide_bed = self.input.v('u0', 'tide', range(0, jmax + 1), kmax,
                                       1)
        c00 = np.real(
            self.input.v('hatc0', range(0, jmax + 1), range(0, kmax + 1), 0))

        c04 = np.abs(
            self.input.v('hatc0', range(0, jmax + 1), range(0, kmax + 1), 2))
        c04_int = np.trapz(c04, x=-self.zarr)
        hatc2 = np.abs(
            self.input.v('hatc2', range(0, jmax + 1), range(0, kmax + 1), 0))
        alpha1 = np.trapz(c00 + hatc2, x=-self.zarr, axis=1)
        if alpha1[-1] == 0:
            alpha1[-1] = alpha1[-2]
        alpha2 = c04_int / alpha1 + 1e-3

        ## load time series Q
        t = self.interpretValues(self.input.v('t'))
        toutput = self.interpretValues(self.input.v('toutput'))
        toutput[0] = t[
            0]  # correct output time; first time level is always equal to initial computation time
        Qarray = self.interpretValues(self.input.v('Q1'))
        if len(Qarray) != len(t):
            from src.util.diagnostics.KnownError import KnownError
            raise KnownError(
                'Length of Q does not correspond to length of time array.')

    ################################################################################################################
    # Compute transport, source and BC
    ################################################################################################################
    ## Transport
        d = self.compute_transport()
        dc = DataContainer(d)

        #       change size of those components that depend on the river discharge and put init value in first element
        T_r = copy(dc.v('T', 'river', range(0, jmax + 1)))
        T_rr = copy(dc.v('T', 'river_river', range(0, jmax + 1)))
        T_dr = copy(dc.v('T', 'diffusion_river', range(0, jmax + 1)))
        F_dr = dc.v('F', 'diffusion_river', range(0, jmax + 1))

        d['T']['river'] = np.zeros((jmax + 1, 1, 1, len(toutput)))
        d['T']['river'][:, 0, 0, 0] = T_r
        d['T']['river_river'] = np.zeros((jmax + 1, 1, 1, len(toutput)))
        d['T']['river_river'][:, 0, 0, 0] = T_rr
        d['T']['diffusion_river'] = np.zeros((jmax + 1, 1, 1, len(toutput)))
        d['T']['diffusion_river'][:, 0, 0, 0] = T_dr
        d['F']['diffusion_river'] = np.zeros((jmax + 1, 1, 1, len(toutput)))
        d['F']['diffusion_river'][:, 0, 0, 0] = F_dr

        T = dc.v('T', range(0, jmax + 1), 0, 0, 0)
        F = dc.v('F', range(0, jmax + 1), 0, 0, 0)

        ## Source
        G = self.compute_source()  #NB does not change over long time scale

        ## Seaward boundary condition
        if self.input.v('sedbc') == 'csea':
            csea = self.input.v('csea')
            fsea = csea / alpha1[0] * (
                self.input.v('grid', 'low', 'z', 0) -
                self.input.v('grid', 'high', 'z', 0)
            )  #NB does not change over long time scale
        else:
            from src.util.diagnostics.KnownError import KnownError
            raise KnownError(
                'incorrect seaward boundary type (sedbc) for sediment module')

        ## compute TQ, uQ, hatc2Q: quantities relative to the river discharge
        u1river = np.real(
            self.input.v('u1', 'river', range(0, jmax + 1), range(0, kmax + 1),
                         0))
        Q_init = -np.trapz(u1river[-1, :], x=-self.zarr[-1, :]) * self.B[
            -1]  # initial discharge
        self.TQ = T_r / Q_init  # river transport per discharge unit
        self.uQ = u1river / Q_init  # river velocity per discharge unit

        ################################################################################################################
        # Initialise X = (f, S)
        ################################################################################################################
        if self.input.v('initial') == 'erodibility':
            finit = self.input.v('finit', range(0, jmax + 1))
            Sinit = self.init_stock(finit, alpha1, alpha2)

        elif self.input.v('initial') == 'stock':
            Sinit = self.input.v('Sinit', range(0, jmax + 1))
            finit = self.erodibility_stock_relation(alpha2, Sinit / alpha1)

        elif self.input.v('initial') == 'equilibrium':
            _, finit, _ = self.availability(F, T, G, alpha1, alpha2)
            Sinit = self.init_stock(finit, alpha1, alpha2)

        else:
            from src.util.diagnostics.KnownError import KnownError
            raise KnownError(
                'incorrect initial value for sediment module. Use erodibility, stock or equilibrium'
            )

        X = np.concatenate((finit, Sinit))
        f = np.zeros((jmax + 1, 1, 1, len(toutput)))
        S = np.zeros((jmax + 1, 1, 1, len(toutput)))
        f[:, 0, 0, 0] = finit
        S[:, 0, 0, 0] = Sinit

        ################################################################################################################
        # Time integrator
        ################################################################################################################
        T_base = dc.v('T', range(0, jmax + 1), 0, 0, 0) - dc.v(
            'T', 'river', range(0, jmax + 1), 0, 0, 0) - dc.v(
                'T', 'river_river', range(0, jmax + 1), 0, 0, 0) - dc.v(
                    'T', 'diffusion_river', range(0, jmax + 1), 0, 0, 0)
        F_base = dc.v('F', range(0, jmax + 1), 0, 0, 0) - dc.v(
            'F', 'diffusion_river', range(0, jmax + 1), 0, 0, 0)

        #   loop
        self.timer.tic()
        qq = 1  # counter for saving
        for i, Q in enumerate(Qarray[1:]):
            # quantities at old time step
            Told = copy(T)
            Fold = copy(F)
            alpha1old = copy(alpha1)
            alpha2old = copy(alpha2)

            # Update transport terms and hatc2 & load new transport terms
            T_riv, T_rivriv, T_difriv, F_difriv = self.update_transport(Q)
            ur = self.uQ[:, -1] * Q
            hatc2 = self.update_hatc2(ur)
            T = T_base + T_riv + T_rivriv + T_difriv
            F = F_base + F_difriv

            # Make one time step and iterate over non-linearity
            self.dt = t[i + 1] - t[i]

            alpha1 = np.trapz(c00 + hatc2, x=-self.zarr, axis=1)
            if alpha1[-1] == 0:
                alpha1[-1] = alpha1[-2]
            alpha2 = c04_int / alpha1 + 1e-3
            X = self.timestepping(T, F, alpha1, alpha2, Told, Fold, alpha1old,
                                  alpha2old, X, fsea, G)

            # save output on output timestep
            if t[i + 1] >= toutput[qq]:
                toutput[qq] = t[
                    i +
                    1]  # correct output time to real time if time step and output time do not correspond
                d['T']['river'][:, 0, 0, qq] = T_riv
                d['T']['river_river'][:, 0, 0, qq] = T_rivriv
                d['T']['diffusion_river'][:, 0, 0, qq] = T_difriv
                d['F']['diffusion_river'][:, 0, 0, qq] = F_difriv
                f[:, 0, 0, qq] = X[:jmax + 1]
                S[:, 0, 0, qq] = X[jmax + 1:]
                qq += 1
                qq = np.minimum(qq, len(toutput) - 1)

            # display progress
            if i % np.floor(len(Qarray[1:]) / 100.) == 0:
                percent = float(i) / len(Qarray[1:])
                hashes = '#' * int(round(percent * 10))
                spaces = ' ' * (10 - len(hashes))
                sys.stdout.write("\rProgress: [{0}]{1}%".format(
                    hashes + spaces, int(round(percent * 100))))
                sys.stdout.flush()
        sys.stdout.write('\n')
        self.timer.toc()
        self.timer.disp('time integration time')

        ################################################################################################################
        # Prepare output
        ################################################################################################################
        d['f'] = f
        d['a'] = S

        fx = np.gradient(f, self.x, axis=0, edge_order=2)
        hatc0 = self.input.v('hatc0', 'a', range(0, jmax + 1),
                             range(0, kmax + 1), range(0, fmax + 1), [0])
        hatc1 = self.input.v('hatc1', 'a', range(0, jmax + 1),
                             range(0, kmax + 1), range(0, fmax + 1), [0])
        hatc1x = self.input.v('hatc1', 'ax', range(0, jmax + 1),
                              range(0, kmax + 1), range(0, fmax + 1), [0])
        hatc2 = self.input.v('hatc2', 'a', range(0, jmax + 1),
                             range(0, kmax + 1), range(0, fmax + 1), [0])
        d['c0'] = hatc0 * f
        d['c1'] = hatc1 * f + hatc1x * fx
        d['c2'] = hatc2 * f

        d['t'] = toutput

        return d

    def update_transport(self, Q):
        """Update transport terms T and F for time dependent river discharge forcing Q.

        Parameters:
            Q - river discharge Q

        Returns:
            T - advection function
            F - diffusion function
            A - variable appearing the the Exner equation, i.e. A = (BF)_x / B
            C20 - second-order sediment concentration
        """
        # T - river
        T_riv = self.TQ * Q

        # T - river_river
        ur = self.uQ * Q
        hatc2 = self.update_hatc2(ur[:, -1])
        T_rivriv = np.real(np.trapz(ur * hatc2, x=-self.zarr, axis=1))

        # T - diffusion river
        hatc2x = np.gradient(hatc2, self.x, axis=0, edge_order=2)
        T_difriv = -self.Kh * np.real(np.trapz(hatc2x, x=-self.zarr, axis=1))

        # F - diffusion river
        F_difriv = -self.Kh * np.real(np.trapz(hatc2, x=-self.zarr, axis=1))
        return T_riv, T_rivriv, T_difriv, F_difriv

    def update_hatc2(self, u_riv_bed):
        """Update shear stress for hatc2 based on varying river discharge"""
        jmax = self.input.v('grid', 'maxIndex', 'x')
        RHOS = self.input.v('RHOS')
        RHO0 = self.input.v('RHO0')
        DS = self.input.v('DS')
        GPRIME = self.input.v('G') * (RHOS - RHO0) / RHO0  #
        HR = (self.input.v('H', range(0, jmax + 1)).reshape(jmax + 1, 1) +
              self.input.v('R', range(0, jmax + 1)).reshape(jmax + 1, 1))
        WS = self.input.v('ws0', range(0, jmax + 1), [0], 0)
        Kv0 = self.input.v('Kv', range(0, jmax + 1), 0, 0).reshape(jmax + 1, 1)
        if self.input.v('friction') is not None:
            sf = self.input.v(self.input.v('friction'), range(0, jmax + 1), 0,
                              0).reshape(jmax + 1, 1)
        else:
            sf = self.input.v('Roughness', range(0, jmax + 1), 0,
                              0).reshape(jmax + 1, 1)
        finf = self.input.v('finf')

        # shear stress
        T = np.linspace(0, 2 * np.pi, 100)
        utid = np.zeros((jmax + 1, len(T)), dtype='complex')
        ucomb = np.zeros((jmax + 1, len(T)), dtype='complex')
        for i, t in enumerate(T):
            utid[:, i] = 0.5 * (self.u0tide_bed * np.exp(1j * t) +
                                np.conj(self.u0tide_bed) * np.exp(-1j * t))
            ucomb[:, i] = u_riv_bed + 0.5 * (self.u0tide_bed * np.exp(
                1j * t) + np.conj(self.u0tide_bed) * np.exp(-1j * t))
        uabs_tid = np.mean(np.abs(utid), axis=1)
        uabs_tot = np.mean(np.abs(ucomb), axis=1)
        uabs_eps = (uabs_tot - uabs_tid).reshape(jmax + 1, 1)

        # erosion
        if self.input.v('erosion_formulation') == 'Partheniades':
            Ehat = finf * sf * (uabs_eps) * RHO0
        else:
            Ehat = (WS * finf * RHOS * sf / (GPRIME * DS)) * (uabs_eps)

        hatc2 = np.real(Ehat / WS * np.exp(-WS * (HR + self.zarr) / Kv0))
        return hatc2

    def init_stock(self, f, alpha1, alpha2):
        """Compute stock given f, alpha1 and alpha2.
        For f=1, S equals Smax, which is S corresponding to f=0.999.
        """

        # Establish initial minimum stock Smax, such that f=0.999
        Smax = np.array([0.999])  # initial guess
        F = self.erodibility_stock_relation(alpha2[[0]], Smax) - np.array(
            [0.999])
        while max(abs(F)) > 10**-4:
            dfdS = self.erodibility_stock_relation_der(alpha2[[0]], Smax)
            Smax = Smax - F / dfdS
            F = self.erodibility_stock_relation(alpha2[[0]], Smax) - np.array(
                [0.999])

        # Newton-Raphson iteration towards actual Shat
        #   init
        Shat = f
        F = self.erodibility_stock_relation(alpha2, Shat) - f

        i = 0
        while max(abs(F)) > self.TOL and i < 50:
            i += 1
            dfdS = self.erodibility_stock_relation_der(alpha2, Shat)
            Shat = Shat - F / (dfdS + 10**-12)
            F = self.erodibility_stock_relation(alpha2, Shat) - f
            if i == 50:
                f = self.erodibility_stock_relation(alpha2, Shat)

        Shat = np.minimum(Shat, Smax)
        return Shat * alpha1

    def timestepping(self, T, F, alpha1, alpha2, Told, Fold, alpha1old,
                     alpha2old, Xold, fsea, G):
        """        """
        jmax = self.input.v('grid', 'maxIndex', 'x')
        A = np.zeros((4, jmax + 1))
        rhs = np.zeros((jmax + 1))

        Sold = Xold[jmax + 1:]
        hatSold = Sold / alpha1old
        fold = Xold[:jmax + 1]
        h = self.erodibility_stock_relation(alpha2old, hatSold)
        hder = self.erodibility_stock_relation_der(alpha2old, hatSold)
        hda2 = self.erodibility_stock_relation_da2(alpha2old, hatSold)
        beta = h - hder * hatSold + hda2 * (alpha2 - alpha2old)

        Tx = np.gradient(T, self.x, edge_order=2)
        Fx = np.gradient(F, self.x, edge_order=2)
        dif = self.B * F
        adv = self.B * T + self.Bx * F + self.B * Fx
        BTx = self.B * Tx + self.Bx * T

        Txold = np.gradient(Told, self.x, edge_order=2)
        Fxold = np.gradient(Fold, self.x, edge_order=2)
        dif_old = self.B * Fold
        adv_old = self.B * Told + self.Bx * Fold + self.B * Fxold
        BTx_old = self.B * Txold + self.Bx * Told

        # interior
        A[0, 2:] = +self.theta * np.minimum(adv[1:-1], 0) * hder[2:] / (
            alpha1[2:] * self.dx[1:]) + self.theta * dif[1:-1] / (
                0.5 * (self.dx[1:] +
                       self.dx[:-1])) * hder[2:] / alpha1[2:] / self.dx[1:]
        A[1, 1:-1] = self.B[1:-1]/self.dt + self.theta*BTx[1:-1]*hder[1:-1]/alpha1[1:-1] + \
                     self.theta*np.maximum(adv[1:-1], 0)*hder[1:-1]/(alpha1[1:-1]*self.dx[:-1]) - self.theta*np.minimum(adv[1:-1], 0)*hder[1:-1]/(alpha1[1:-1]*self.dx[1:]) \
                     - self.theta*dif[1:-1]/(0.5*(self.dx[1:]+self.dx[:-1]))*hder[1:-1]/alpha1[1:-1]*(1./self.dx[1:]+1./self.dx[:-1])
        A[2, :-2] = -self.theta * np.maximum(adv[1:-1], 0) * hder[:-2] / (
            alpha1[:-2] * self.dx[:-1]) + self.theta * dif[1:-1] / (
                0.5 * (self.dx[1:] +
                       self.dx[:-1])) * hder[:-2] / alpha1[:-2] / self.dx[:-1]

        rhs[1:-1] = self.B[1:-1]/self.dt*Sold[1:-1] - self.theta*BTx[1:-1]*beta[1:-1] - self.theta*np.maximum(adv[1:-1], 0)*(beta[1:-1]-beta[:-2])/self.dx[:-1] - self.theta*np.minimum(adv[1:-1], 0)*(beta[2:]-beta[1:-1])/self.dx[1:] \
                    -self.theta*dif[1:-1]*((beta[2:]-beta[1:-1])/self.dx[1:] - (beta[1:-1]-beta[:-2])/self.dx[:-1])/(0.5*(self.dx[1:]+self.dx[:-1])) \
                    + (1-self.theta) * (-BTx_old[1:-1]*fold[1:-1] - np.maximum(adv_old[1:-1], 0)*(fold[1:-1]-fold[:-2])/self.dx[:-1] - np.minimum(adv_old[1:-1], 0)*(fold[2:]-fold[1:-1])/self.dx[1:] \
                                      -dif_old[1:-1]*((fold[2:]-fold[1:-1])/self.dx[1:] - (fold[1:-1]-fold[:-2])/self.dx[:-1])/(0.5*(self.dx[1:]+self.dx[:-1])))
        rhs[1:-1] += -self.B[1:-1] * G[1:-1]

        # Quick fix for ensuring positivity (Patankar, 1980); could be neater for greater accuracy
        A[1, 1:-1] += -np.minimum(rhs[1:-1], 0) / (Sold[1:-1] + 1.e-6)
        rhs[1:-1] = np.maximum(rhs[1:-1], 0)

        # Boundaries
        #   x=0
        if hder[0] == 0:
            A[1, 0] = 1
            rhs[0] = Sold[0]
        else:
            A[1, 0] = hder[0] / alpha1[0]
            rhs[0] = fsea - h[0] + hder[0] * hatSold[0]

        #   x=L
        if hder[-1] == 0:
            A[1,
              -1] = 1  # TODO - needs correction; VIOLATION OF MASS BALANCE. This line will only apply in case Q1 = 0
            rhs[-1] = Sold[-1]
            self.logger.warning(
                'f=1 at upstream boundary. The code is not correct for this case and mass balance may be violated. Please investigate.'
            )
        else:
            A[1, -1] = self.B[-1] * T[-1] * hder[-1] / alpha1[
                -1] + 3. / 2. * self.B[-1] * F[-1] * hder[-1] / alpha1[
                    -1] / self.dx[-1]
            A[2, -2] = -2. * self.B[-1] * F[-1] * hder[-2] / alpha1[
                -2] / self.dx[-1]
            A[3, -3] = 0.5 * self.B[-1] * F[-1] * hder[-3] / alpha1[
                -3] / self.dx[-1]
            rhs[-1] = -self.B[-1] * T[-1] * beta[-1] - self.B[-1] * F[-1] * (
                3. / 2. * beta[-1] - 2. * beta[-2] +
                0.5 * beta[-3]) / self.dx[-1]
            rhs[-1] += -self.B[-1] * G[-1]

            #   alternative first order
            # A[1, -1] = self.B[-1]*T[-1]*hder[-1]/alpha1[-1] + self.B[-1]*F[-1]*hder[-1]/alpha1[-1]/self.dx[-1]
            # A[2, -2] = -1.*self.B[-1]*F[-1]*hder[-2]/alpha1[-2]/self.dx[-1]
            # rhs[-1] = -self.B[-1]*T[-1]*beta[-1] - self.B[-1]*F[-1]*(1*beta[-1] - 1.*beta[-2])/self.dx[-1]
            # rhs[-1] += self.B[-1]*G[-1]

        try:
            S = scipy.linalg.solve_banded((2, 1),
                                          A,
                                          rhs,
                                          overwrite_ab=False,
                                          overwrite_b=False)
        except:
            print Xold[:jmax + 1]
            raise KnownError('Time integration failed.')

        f = self.erodibility_stock_relation(alpha2, S / alpha1)
        X = np.concatenate((f, S), axis=0)

        return X

    def interpretValues(self, values):
        """inpterpret values on input as space-separated list or as pure python input

        Parameters
            values - values to evaluate

        Returns:
            values - evaluated values
        """
        values = toList(values)

        # case 1: pure python: check for (, [, range, np.arange
        #   merge list to a string
        valString = ' '.join([str(f) for f in values])
        #   try to interpret as python string
        if any([i in valString for i in ['(', '[', ',', '/', '*', '+', '-']]):
            try:
                valuespy = None
                exec('valuespy =' + valString)
                return valuespy
            except Exception as e:
                try:
                    errorString = ': ' + e.message
                except:
                    errorString = ''
                raise KnownError(
                    'Failed to interpret input as python command %s in input: %s'
                    % (errorString, valString), e)

        # case 2: else interpret as space-separated list
        else:
            return values
Пример #4
0
blocking = nifty.tools.blocking(roiBegin=[0] * 3,
                                roiEnd=shape,
                                blockShape=blockShape)

numberOfBlocks = blocking.numberOfBlocks

nThreads = 40

if True:
    # now the same in python
    h5File = h5py.File(fileName, 'r')
    array = h5File[dsetName]
    lock = threading.Lock()

    with nifty.Timer("python"):
        val = long(0)

        def f(blockIndex):
            global val
            block = blocking.getBlock(blockIndex)
            b, e = block.begin, block.end

            with lock:
                subarray = array[b[0]:e[0], b[1]:e[1], b[2]:e[2]]
                _val = subarray[0, 0, 0]
                val += long(_val)

        nifty.tools.parallelForEach(range(numberOfBlocks),
                                    f=f,
                                    nWorkers=nThreads)
Пример #5
0
affinities = numpy.require(affinities, dtype='float32', requirements=['C'])

# load raw
import skimage.io
raw_path = "/home/tbeier/src/nifty/src/python/examples/multicut/NaturePaperDataUpl/ISBI2012/raw_test.tif"
#raw_path = '/home/tbeier/src/nifty/mysandbox/NaturePaperDataUpl/ISBI2012/raw_test.tif'
raw = skimage.io.imread(raw_path)
raw = raw[z, 0:w, 0:w]

isMergeEdgeOffset = numpy.zeros(offsets.shape[0], dtype='bool')
isMergeEdgeOffset[0:2] = True

if True:
    affinities = vigra.gaussianSmoothing(vigra.taggedView(affinities, 'xyc'),
                                         0.2)
    with nifty.Timer("jay"):
        nodeSeg = nifty.graph.agglo.pixelWiseFixation2D(
            mergePrios=(
                1.0 - affinities
            ),  #vigra.gaussianSmoothing(vigra.taggedView( (1.0 - affinities),'xyc'),0.01),
            notMergePrios=
            affinities,  #vigra.gaussianSmoothing(vigra.taggedView( (affinities),'xyc'),0.01),
            offsets=offsets,
            isMergeEdgeOffset=isMergeEdgeOffset)

    #nodeSeg = nodeSeg.reshape(shape)

    import pylab

    pylab.imshow(nodeSeg)
    pylab.show()
Пример #6
0
class KEFittedMAW:
    # Variables
    TOLLERANCE = 1.e-3      # relative convergence criterion for Av
    RELAX = 0.8             # relaxation value; as RELAX*old estimate + (1-RELAX)*new estimate
    invfft_length = 90
    LOCAL = 0.5
    filterlength = 15

    cmax = []
    ETMloc = []
    logger = logging.getLogger(__name__)
    timers = [ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer(), ny.Timer()]

    # Methods
    def __init__(self, input):
        self.input = input
        self.kem = KEFittedTruncated(self.input)
        return

    def stopping_criterion(self, iteration):
        self.iteration = iteration

        ## Check convergence
        if self.difference < self.TOLLERANCE*(1-self.RELAX):# or self.iteration>10:
            if self.betac == 0 and not self.input.v('BETAC') == 0:
                self.betac = self.input.v('BETAC')
                self.logger.info('\tMAW starting to include density differences, rel. difference may go up.')
                return False
            else:
                return True
        else:
            return False

    def run_init(self):
        self.logger.info('Running MAW turbulence model - init')
        self.difference = np.inf

        d = {}

        dkem = self.kem.run_init()          # initialise KE model
        self.kem.referenceLevel = False     # only let KE model compute the initial reference level
        self.betac = self.input.v('BETAC')  # set density dependency parameter for sediment
        self.referenceLevel = self.input.v('referenceLevel')    # include computation of reference level in computation (boolean)

        Av = self.input.v('Av')
        Kv = self.input.v('Kv')
        Ri = self.input.v('Ri')
        Roughness = self.input.v('Roughness')
        skin_friction = self.input.v('skin_friction')
        jmax = self.input.v('grid', 'maxIndex', 'x')
        fmax = self.input.v('grid', 'maxIndex', 'f')

        # Initialisation uses data that might be available, or starts clean
        if Av is None or Roughness is None:
            d.update(dkem)                      # use input from initial k-eps fitted run - contains Av and Roughness
            self.input.merge(d)

        if Ri is None or skin_friction is None:
            self.betac = 0                      # start without density effect, first allow KEFitted to converge
            self.Rida = 0.

            # initially set skin friction equal to roughness
            data = self.input.slice('grid')
            data.addData('coef', self.input.v('Roughness', range(0, jmax+1), 0, range(0, fmax+1)))
            ss = UniformXF(['x', 'f'], data, 0.).function
            d['skin_friction'] = ss


        if Kv is None:
            # make eddy diffusivity
            Av = self.input.v('Av', range(0, jmax+1), 0, range(0, fmax+1))
            data = self.input.slice('grid')
            data.addData('coef', Av/self.input.v('sigma_rho', range(0, jmax+1), 0, [0]))
            Kv = UniformXF(['x', 'f'], data, 0.).function
            d['Kv'] = Kv

        # all first-order turbulence quantities are set to zero
        d['Kv1'] = 0.
        d['Av1'] = 0.
        d['Roughness1'] = 0.
        d['skin_friction1'] = 0.
        d['BottomBC'] = 'PartialSlip'

        return d

    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
Пример #7
0
class SedimentCapacity:
    # Variables
    logger = logging.getLogger(__name__)
    timer = ny.Timer()

    # Methods
    def __init__(self, input):
        self.input = input
        return

    def run(self):
        self.timer.tic()
        self.logger.info('Running module Sediment Capacity')

        ## Init
        d = {}

        self.submodulesToRun = ny.toList(self.input.v('submodules'))
        self.erosion_method = self.input.v('erosion_formulation')
        self.frictionpar = self.input.v(
            'friction'
        )  # friction parameter used for the erosion, by default the total roughness
        if self.frictionpar == None:
            self.frictionpar = 'Roughness'

        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        fmax = self.input.v('grid', 'maxIndex', 'f')
        self.Kv = self.input.v('Kv', range(0, jmax + 1), range(0, kmax + 1),
                               range(0, fmax + 1))
        self.ws = self.input.v('ws0', range(0, jmax + 1), range(0, kmax + 1),
                               range(0, fmax + 1))

        ## Run orders
        d.update(self.leading_order(d))
        d.update(self.first_order(d))
        d.update(self.second_order_river(d))

        self.timer.toc()
        self.timer.disp('time sediment capacity')
        self.timer.reset()
        # d['hatc0']['a']['erosion'][:, :, 0] += 1e-4
        return d

    def leading_order(self, d):
        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        fmax = self.input.v('grid', 'maxIndex', 'f')
        ftot = 2 * fmax + 1

        ################################################################################################################
        # Forcing terms
        ################################################################################################################
        F = np.zeros([jmax + 1, kmax + 1, ftot, 1], dtype=complex)
        Fsurf = np.zeros([jmax + 1, 1, ftot, 1], dtype=complex)
        Fbed = np.zeros([jmax + 1, 1, ftot, 1], dtype=complex)

        # erosion
        E = erosion(self.ws,
                    0,
                    self.input,
                    self.erosion_method,
                    friction=self.frictionpar)
        Fbed[:, :, fmax:, 0] = -E

        ################################################################################################################
        # Solve equation
        ################################################################################################################
        # Coupled system
        c, cMatrix = cFunction(self.ws,
                               self.Kv,
                               F,
                               Fsurf,
                               Fbed,
                               self.input,
                               hasMatrix=False)
        c = c.reshape((jmax + 1, kmax + 1, ftot))
        hatc0 = ny.eliminateNegativeFourier(c, 2)

        # Uncoupled system
        # hatc0 = np.zeros((jmax+1, kmax+1, fmax+1), dtype=complex)
        # hatc0[:, :, 0] = cFunctionUncoupled(self.ws, self.Kv, F, Fsurf, Fbed, self.input, 0).reshape((jmax+1, kmax+1))
        # hatc0[:, :, 2] = cFunctionUncoupled(self.ws, self.Kv, F, Fsurf, Fbed, self.input, 2).reshape((jmax+1, kmax+1))

        # correction at the bed (optional)
        # cbed00 = E[:, -1, 0]/self.ws[:, -1, 0]
        # frac = cbed00/hatc0[:, -1, 0]
        # hatc0 = hatc0*frac.reshape((jmax+1, 1, 1))

        ## analytical solutions
        # ahatc0 = np.zeros((jmax+1, kmax+1, fmax+1), dtype=complex)
        # ahatc02 = np.zeros((jmax+1, kmax+1, fmax+1), dtype=complex)
        # z = ny.dimensionalAxis(self.input.slice('grid'), 'z')[:, :, 0]
        # self.ws = self.ws[:, 0, 0]
        # self.Kv = self.Kv[:, 0, 0]
        # OMEGA = self.input.v('OMEGA')
        # H = self.input.v('H', range(0, jmax+1))
        #
        # # M0
        # ahatc0[:, :, 0] = (E[:, 0, 0]/self.ws).reshape((jmax+1, 1))*np.exp(-(self.ws/self.Kv).reshape((jmax+1, 1))*(z+H.reshape((jmax+1, 1))))
        #
        #
        # # M4
        #
        # r1 = -self.ws/(2.*self.Kv)+np.sqrt(self.ws**2+8*1j*OMEGA*self.Kv)/(2*self.Kv)
        # r2 = -self.ws/(2.*self.Kv)-np.sqrt(self.ws**2+8*1j*OMEGA*self.Kv)/(2*self.Kv)
        # k2 = -E[:, 0, 2]*(self.Kv*(-r1*(self.ws+self.Kv*r2)/(self.ws+self.Kv*r1)*np.exp(-r1*H) + r2*np.exp(-r2*H)))**-1.
        # k1 = -k2*(self.ws+self.Kv*r2)/(self.ws+self.Kv*r1)
        # ahatc0[:, :, 2] = k1.reshape((jmax+1, 1))*np.exp(r1.reshape((jmax+1, 1))*z) + k2.reshape((jmax+1, 1))*np.exp(r2.reshape((jmax+1, 1))*z)

        # import step as st
        # import matplotlib.pyplot as plt
        #
        # st.configure()
        # plt.figure(1, figsize=(1,3))
        # plt.subplot(1,3,1)
        # plt.plot(np.real(ahatc0[0, :, 0]), z[0, :], label='analytical')
        # plt.plot(np.real(hatc0[0, :, 0]), z[0, :], label='numerical')
        # plt.xlim(0, np.max(np.maximum(abs(ahatc0[0, :, 0]), abs(hatc0[0, :, 0])))*1.05)
        #
        # plt.subplot(1,3,2)
        # plt.plot(np.abs(ahatc0[0, :, 2]), z[0, :], label='analytical')
        # # plt.plot(np.abs(ahatc02[0, :, 2]), z[0, :], label='analytical2')
        # plt.plot(np.abs(hatc0[0, :, 2]), z[0, :], label='numerical')
        # # plt.xlim(np.min(np.minimum(abs(ahatc0[0, :, 2]), abs(hatc0[0, :, 2])))*1.05, np.max(np.maximum(abs(ahatc0[0, :, 2]), abs(hatc0[0, :, 2])))*1.05)
        # plt.legend()
        #
        # plt.subplot(1,3,3)
        # plt.plot(np.imag(ahatc0[0, :, 2]), z[0, :], label='analytical')
        # # plt.plot(np.imag(ahatc02[0, :, 2]), z[0, :], label='analytical2')
        # plt.plot(np.imag(hatc0[0, :, 2]), z[0, :], label='numerical')
        # # plt.xlim(np.min(np.minimum(abs(ahatc0[0, :, 2]), abs(hatc0[0, :, 2])))*1.05, np.max(np.maximum(abs(ahatc0[0, :, 2]), abs(hatc0[0, :, 2])))*1.05)
        # plt.legend()
        # st.show()

        d['hatc0'] = {}
        d['hatc0']['a'] = {}
        d['hatc0']['a']['erosion'] = hatc0
        d['cMatrix'] = cMatrix
        return d

    def first_order(self, d):
        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        fmax = self.input.v('grid', 'maxIndex', 'f')
        ftot = 2 * fmax + 1
        OMEGA = self.input.v('OMEGA')

        ################################################################################################################
        # Forcing terms
        ################################################################################################################
        if 'sedadv' in self.submodulesToRun and 'sedadv_ax' not in self.submodulesToRun:
            self.submodulesToRun.append('sedadv_ax')
        # determine number of submodules
        nRHS = len(self.submodulesToRun)
        if 'erosion' in self.submodulesToRun:
            keysu1 = self.input.getKeysOf('u1')
            try:
                keysu1.remove(
                    'mixing'
                )  # flow due to 'mixing' should not be included in the erosion term
            except:
                pass
            self.submodulesToRun.remove(
                'erosion')  # move to the end of the list
            self.submodulesToRun.append('erosion')
            nRHS = nRHS - 1 + len(self.input.getKeysOf('u1'))

        F = np.zeros([jmax + 1, kmax + 1, ftot, nRHS], dtype=complex)
        Fsurf = np.zeros([jmax + 1, 1, ftot, nRHS], dtype=complex)
        Fbed = np.zeros([jmax + 1, 1, ftot, nRHS], dtype=complex)

        self.input.merge(d)
        c0 = self.input.v('hatc0', range(0, jmax + 1), range(0, kmax + 1),
                          range(0, fmax + 1))
        cx0 = self.input.d('hatc0',
                           range(0, jmax + 1),
                           range(0, kmax + 1),
                           range(0, fmax + 1),
                           dim='x')
        cz0 = self.input.d('hatc0',
                           range(0, jmax + 1),
                           range(0, kmax + 1),
                           range(0, fmax + 1),
                           dim='z')
        # 1. Erosion
        if 'erosion' in self.submodulesToRun:
            # erosion due to first-order bed shear stress
            # E = erosion(self.ws, Av, 1, self.input, self.erosion_method)                        # 24-04-2017 Obsolete
            # Fbed[:, :, fmax:, self.submodulesToRun.index('erosion')] = -E     # 24-04-2017 Obsolete
            for submod in keysu1:
                E = erosion(self.ws,
                            1,
                            self.input,
                            self.erosion_method,
                            submodule=(None, submod),
                            friction=self.frictionpar)
                Fbed[:, :, fmax:,
                     len(self.submodulesToRun) - 1 + keysu1.index(submod)] = -E

        # 2. Advection
        if 'sedadv' in self.submodulesToRun:
            u0 = self.input.v('u0', range(0, jmax + 1), range(0, kmax + 1),
                              range(0, fmax + 1))
            w0 = self.input.v('w0', range(0, jmax + 1), range(0, kmax + 1),
                              range(0, fmax + 1))

            eta = ny.complexAmplitudeProduct(
                u0, cx0, 2) + ny.complexAmplitudeProduct(w0, cz0, 2)
            F[:, :, fmax:, self.submodulesToRun.index('sedadv')] = -eta
            F[:, :, fmax:,
              self.submodulesToRun.
              index('sedadv_ax')] = -ny.complexAmplitudeProduct(u0, c0, 2)

        # 3. First-order fall velocity
        if 'fallvel' in self.submodulesToRun:
            # surface and internal terms
            ws1 = self.input.v('ws1', range(0, jmax + 1), range(0, kmax + 1),
                               range(0, fmax + 1))
            ksi = ny.complexAmplitudeProduct(ws1, c0, 2)
            ksiz = ny.derivative(ksi, 'z', self.input.slice('grid'))

            F[:, :, fmax:, self.submodulesToRun.index('fallvel')] = ksiz
            Fsurf[:, 0, fmax:,
                  self.submodulesToRun.index('fallvel')] = -ksi[:, 0, :]

            # adjustment to erosion; only if erosion depends on the settling velocity
            if self.erosion_method == 'Chernetsky':
                E = erosion(ws1,
                            0,
                            self.input,
                            self.erosion_method,
                            friction=self.frictionpar)
                Fbed[:, :, fmax:, self.submodulesToRun.index('fallvel')] = -E

        # 4. First-order eddy diffusivity
        if 'mixing' in self.submodulesToRun:
            # surface, bed and internal terms
            Kv1 = self.input.v('Kv1', range(0, jmax + 1), range(0, kmax + 1),
                               range(0, fmax + 1))
            psi = ny.complexAmplitudeProduct(Kv1, cz0, 2)
            psiz = ny.derivative(psi, 'z', self.input.slice('grid'))

            F[:, :, fmax:, self.submodulesToRun.index('mixing')] = psiz
            Fsurf[:, 0, fmax:,
                  self.submodulesToRun.index('mixing')] = -psi[:, 0, :]
            Fbed[:, 0, fmax:,
                 self.submodulesToRun.index('mixing')] = -psi[:, -1, :]

            # adjustment to erosion
            E = erosion(self.ws,
                        1,
                        self.input,
                        self.erosion_method,
                        submodule=(None, 'mixing'),
                        friction=self.frictionpar)
            Fbed[:, :, fmax:, self.submodulesToRun.index('mixing')] = -E

        # 5. No-flux surface correction
        if 'noflux' in self.submodulesToRun:
            zeta0 = self.input.v('zeta0', range(0, jmax + 1), [0],
                                 range(0, fmax + 1))
            D = np.zeros((jmax + 1, 1, fmax + 1, fmax + 1), dtype=complex)
            D[:, :, range(0, fmax + 1),
              range(0, fmax + 1)] = np.arange(0, fmax + 1) * 1j * OMEGA
            Dc0 = ny.arraydot(D, c0[:, [0], :])

            chi = ny.complexAmplitudeProduct(Dc0, zeta0, 2)
            Fsurf[:, :, fmax:, self.submodulesToRun.index('noflux')] = -chi

        ################################################################################################################
        # Solve equation
        ################################################################################################################
        cmatrix = self.input.v('cMatrix')
        if cmatrix is not None:
            c, cMatrix = cFunction(None,
                                   cmatrix,
                                   F,
                                   Fsurf,
                                   Fbed,
                                   self.input,
                                   hasMatrix=True)
        else:
            c, cMatrix = cFunction(self.ws,
                                   self.Kv,
                                   F,
                                   Fsurf,
                                   Fbed,
                                   self.input,
                                   hasMatrix=False)
        c = c.reshape((jmax + 1, kmax + 1, ftot, nRHS))
        c = ny.eliminateNegativeFourier(c, 2)

        ################################################################################################################
        # Prepare output
        ################################################################################################################
        d['hatc1'] = {}
        d['hatc1']['a'] = {}
        d['hatc1']['ax'] = {}
        for i, submod in enumerate(self.submodulesToRun):
            if submod == 'sedadv_ax':
                d['hatc1']['ax']['sedadv'] = c[:, :, :, i]
            elif submod == 'erosion':
                d['hatc1']['a']['erosion'] = {}
                for j, subsubmod in enumerate(keysu1):
                    d['hatc1']['a']['erosion'][
                        subsubmod] = c[:, :, :,
                                       len(self.submodulesToRun) - 1 + j]
            else:
                d['hatc1']['a'][submod] = c[:, :, :, i]
        if 'sedadv' not in self.submodulesToRun:
            d['hatc1']['ax'] = 0

        return d

    def second_order_river(self, d):
        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        fmax = self.input.v('grid', 'maxIndex', 'f')
        ftot = 2 * fmax + 1

        ################################################################################################################
        # Forcing terms
        ################################################################################################################
        F = np.zeros([jmax + 1, kmax + 1, ftot, 1], dtype=complex)
        Fsurf = np.zeros([jmax + 1, 1, ftot, 1], dtype=complex)
        Fbed = np.zeros([jmax + 1, 1, ftot, 1], dtype=complex)

        # erosion
        if self.input.v('u1', 'river') is not None:
            E = erosion(self.ws,
                        2,
                        self.input,
                        self.erosion_method,
                        submodule=(None, 'river', None),
                        friction=self.frictionpar)
            Fbed[:, :, fmax:, 0] = -E

            ################################################################################################################
            # Solve equation
            ################################################################################################################
            cmatrix = self.input.v('cMatrix')
            if cmatrix is not None:
                c, cMatrix = cFunction(None,
                                       cmatrix,
                                       F,
                                       Fsurf,
                                       Fbed,
                                       self.input,
                                       hasMatrix=True)
            else:
                c, cMatrix = cFunction(self.ws,
                                       self.Kv,
                                       F,
                                       Fsurf,
                                       Fbed,
                                       self.input,
                                       hasMatrix=False)
            c = c.reshape((jmax + 1, kmax + 1, ftot))
        else:
            c = np.zeros((jmax + 1, kmax + 1, ftot))

        d['hatc2'] = {}
        d['hatc2']['a'] = {}
        d['hatc2']['a']['erosion'] = {}
        d['hatc2']['a']['erosion'][
            'river_river'] = ny.eliminateNegativeFourier(c, 2)
        return d