Example #1
0
 def __loadConfig(self):
     import src.config as cf
     configvars = [var for var in dir(cf) if not var.startswith('__')]
     d = {}
     for var in configvars:
         exec('d[var] = cf.' + var)
     return DataContainer(d)
    def __init__(self, value, gridData, gridName='grid'):
        # if grid data is a dictionary, first convert to datacontainer
        if isinstance(gridData, dict):
            from src.DataContainer import DataContainer
            dc = DataContainer()
            dc.addData(gridName, gridData)
            gridData = dc
            del dc

        # check if a grid is provided in DC data
        dimensions = gridData.v(gridName, 'dimensions')
        dimNames = [dimensions[i] for i in range(0, len(value.shape))]
        NumericalFunctionBase.__init__(self, dimNames)

        # add grid (with name 'grid') and value
        self.addGrid(gridData)
        self.addValue(value)
        return
    def run(self):
        # self.timers[0].tic()
        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')

        L = self.input.v('L')
        self.x = self.input.v('grid', 'axis', 'x')
        self.zarr = ny.dimensionalAxis(self.input.slice('grid'), 'z')[:, :, 0]-self.input.v('R', x=self.x/L).reshape((len(self.x), 1))      #YMD 22-8-17 includes reference level; note that we take a reference frame z=[-H-R, 0]

        c00 = np.real(self.input.v('hatc0', 'a', range(0, jmax+1), range(0, kmax+1), 0))
        c04 = np.abs(self.input.v('hatc0', 'a', range(0, jmax+1), range(0, kmax+1), 2))
        # c20 = np.real(self.input.v('hatc2', 'a', range(0, jmax+1), range(0, kmax+1), 0))       # NB. do not include hatc2 in the definition of alpha1 here
        alpha1 = ny.integrate(c00, 'z', kmax, 0, self.input.slice('grid'))[:, 0]
        alpha1[-1] += alpha1[-2]                                                                 # correct alpha1 at last point to prevent zero value
        alpha2 = ny.integrate(c04, 'z', kmax, 0, self.input.slice('grid'))[:, 0]/(alpha1+1e-10) + 1.e-3
        # self.timers[0].toc()

        ################################################################################################################
        ## Compute T and F
        ################################################################################################################
        # self.timers[1].tic()
        d = self.compute_transport()
        G = self.compute_source()
        # self.timers[1].toc()

        ################################################################################################################
        ## 4. Calculate availability
        ################################################################################################################
        # self.timers[2].tic()
        # Add all mechanisms to datacontainer
        dctrans = DataContainer(d)

        # Calculate availability
        a, f0, f0x = self.availability(dctrans.v('F', range(0, jmax+1)), dctrans.v('T', range(0, jmax+1)), G, alpha1, alpha2)
        f0 = f0.reshape(jmax+1, 1)
        f0x = f0x.reshape(jmax+1, 1)

        d['a'] = a
        nfu = ny.functionTemplates.NumericalFunctionWrapper(f0[:, 0], self.input.slice('grid'))
        nfu.addDerivative(f0x[:, 0], 'x')
        d['f'] = nfu.function
        # self.timers[2].toc()

        ################################################################################################################
        # 5. Calculate concentrations, i.e. a*hatc(a) + ax*hatc(ax)
        ################################################################################################################
        # self.timers[3].tic()
        d['c0'] = {}
        d['c1'] = {}
        d['c2'] = {}

        # Calculate c0=f*hatc0
        for submod in self.input.getKeysOf('hatc0', 'a'):
            c0_comp = self.input.v('hatc0', 'a', submod, range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
            d['c0'][submod] = {}
            tmp = f0[:, None] * c0_comp
            d['c0'][submod] = tmp

        # Calculate c1 = f*hatc1_f + fx*hatc1_fx
        for submod in self.input.getKeysOf('hatc1', 'a'):
            if submod == 'erosion':
                for subsubmod in self.input.getKeysOf('hatc1', 'a', 'erosion'):
                    c1_comp = self.input.v('hatc1', 'a', 'erosion', subsubmod, range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
                    d['c1'] = self.dictExpand(d['c1'], 'erosion', subsubmod)
                    tmp = f0[:, None] * c1_comp
                    d['c1']['erosion'][subsubmod] = tmp

            elif submod == 'sedadv':
                c1_comp_a = self.input.v('hatc1', 'a', 'sedadv', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
                c1_comp_ax = self.input.v('hatc1', 'ax', 'sedadv', range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
                d['c1'][submod] = {}
                tmp = f0[:, None] * c1_comp_a + f0x[:, None] * c1_comp_ax
                d['c1'][submod] = tmp

            else:
                c1_comp = self.input.v('hatc1', 'a', submod, range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
                d['c1'][submod] = {}
                tmp = f0[:, None] * c1_comp
                d['c1'][submod] = tmp

        # Calculate c2 = f*hatc2
        for subsubmod in self.input.getKeysOf('hatc2', 'a', 'erosion'):
            c2_comp = self.input.v('hatc2', 'a', 'erosion', subsubmod, range(0, jmax+1), range(0, kmax+1), range(0, fmax+1))
            d['c2'] = self.dictExpand(d['c2'], 'erosion', subsubmod)
            tmp = f0[:, None] * c2_comp
            d['c2']['erosion'][subsubmod] = tmp

        # self.timers[3].toc()
        # self.timers[0].disp('time availability - init')
        # self.timers[1].disp('time availability - T, F')
        # self.timers[2].disp('time availability - a, f')
        # self.timers[3].disp('time availability - to dict')
        # self.timers[4].disp('time availability - cap')
        # self.timers[5].disp('time availability - trap')
        # [self.timers[i].reset() for i in range(0, len(self.timers))]

        return d
Example #4
0
import json
import datetime
import os
from src.DataContainer import DataContainer
from src.globalVar import module_path

if __name__ == '__main__':
    if not os.path.exists(module_path + "/result"):
        os.mkdir(module_path + "/result")
    time = datetime.datetime.now()
    curr_year = time.year
    f = open(module_path + "/settings.json", "r")
    settings = json.load(f)
    company_list = settings['company']
    startyear = settings['start year']
    finalyear = settings['final year']
    season = settings['season']
    pickleload = settings['load from file']
    pickledump = settings['write to file']
    platform = DataContainer(company_list, startyear, finalyear, season,
                             curr_year, pickleload, pickledump)
    platform.calculate()
    platform.write()
Example #5
0
    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
Example #6
0
    def run(self):
        """Run function to initiate the calculation of the sediment transport

         Returns:
             Dictionary with results. At least contains the variables listed as output in the registry
         """
        self.logger.info('Running module Sediment')

        # Initiate variables
        self.SIGMA = self.input.v('OMEGA')
        self.RHOS = self.input.v('RHOS')
        self.DS = self.input.v('DS')
        self.GPRIME = self.input.v('G') * (self.RHOS - self.input.v('RHO0')) / self.input.v('RHO0')    #
        self.ASTAR = self.input.v('astar')
        self.WS = self.input.v('ws0')
        self.KH = self.input.v('Kh')
        self.L = self.input.v('L')
        self.x = self.input.v('grid', 'axis', 'x') * self.input.v('L')
        self.dx = self.x[1:]-self.x[:-1]
        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        fmax = self.input.v('grid', 'maxIndex', 'f')
        self.z = self.input.v('grid', 'axis', 'z', 0, range(0, kmax+1))
        self.zarr = ny.dimensionalAxis(self.input.slice('grid'), 'z')[:, :, 0]-self.input.v('R', x=self.x/self.L).reshape((len(self.x), 1))      #YMD 22-8-17 includes reference level; note that we take a reference frame z=[-H-R, 0]
        self.Av0 = self.input.v('Kv', range(0, jmax+1), 0, 0).reshape(jmax+1, 1)
        self.Av0x = self.input.d('Kv', range(0, jmax+1), 0, 0, dim='x').reshape(jmax+1, 1)
        self.H = (self.input.v('H', range(0, jmax+1)).reshape(jmax+1, 1) +
                  self.input.v('R', range(0, jmax+1)).reshape(jmax+1, 1))
        self.Hx = (self.input.d('H', range(0, jmax+1), dim='x').reshape(jmax+1, 1) +
                   self.input.d('R', range(0, jmax+1), dim='x').reshape(jmax+1, 1))
        self.B = self.input.v('B', range(0, jmax+1))
        self.Bx = self.input.d('B', range(0, jmax+1), dim='x').reshape(jmax+1, 1)
        self.sf = self.input.v('Roughness', range(0, jmax+1), 0, 0).reshape(jmax+1, 1)
        self.sfx = self.input.d('Roughness', range(0, jmax+1), 0, 0, dim='x').reshape(jmax+1, 1)
        self.submodules_hydro = self.input.data['u1'].keys()
        self.submodules_sed = self.input.v('submodules')
        # Extract leading order surface elevation and horizontal and vertical velocities
        self.zeta0 = self.input.v('zeta0', 'tide', range(0, jmax+1), 0, 1).reshape(jmax+1, 1)
        self.u0 = self.input.v('u0', 'tide', range(0, jmax+1), range(0, kmax+1), 1)
        self.w0 = self.input.v('w0', 'tide', range(0, jmax+1), range(0, kmax+1), 1)
        # Initiate dictionary to save results
        d = {}

        ################################################################################################################
        ## Calculate leading, first and second order concentration amplitudes hatc0, hatc1 and hatc2
        ################################################################################################################
        # Allocate space
        d['hatc0'] = {}
        d['hatc1'] = {'a': {}, 'ax': {}}
        d['hatc2'] = {}
        # Calculate leading order concentration amplitudes
        d['hatc0'] = self.erosion_lead()
        # Calculate first order concentration amplitudes
        for sedmod in self.submodules_sed:
            hatc1 = getattr(self, sedmod)()
            for k in hatc1.keys():
                d['hatc1'][k].update(hatc1[k])
        # Calculate second order concentration amplitudes
        d['hatc2'] = self.erosion_second()

        ################################################################################################################
        ## Calculate Transport function T and diffusion function F
        ################################################################################################################
        # Allocate space
        d['T'] = {}
        d['F'] = {}
        ## Transport T #################################################################################################
        # Transport terms that are a function of the first order velocity, i.e. u1*c0 terms.
        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)])
            # calculate residual Transport terms
            for n in (0, 2):
                tmp = u1_comp[:, :, n]
                if n==0:
                    if submod == 'stokes':
                        tmp = np.real(np.trapz(tmp * self.c00, x=-self.zarr, axis=1))
                        if any(tmp) > 10**-14:
                            d['T'][submod] = self.dictExpand(d['T'][submod], 'TM0', ['return', 'drift'])
                            d['T'][submod]['TM0']['return'] += tmp
                    else:
                        tmp = np.real(np.trapz(tmp * self.c00, x=-self.zarr, axis=1))
                        if any(tmp) > 10**-14:
                            d['T'][submod]['TM' + str(2 * n)] += tmp
                elif n==2:
                    if submod == 'stokes':
                        tmp = np.real(np.trapz((tmp * np.conj(self.c04) + np.conj(tmp) * self.c04) / 4., x=-self.zarr, axis=1))
                        if any(tmp) > 10**-14:
                            d['T'][submod] = self.dictExpand(d['T'][submod], 'TM4', ['return', 'drift'])
                            d['T'][submod]['TM4']['return'] += tmp
                    else:
                        tmp = np.real(np.trapz((tmp * np.conj(self.c04) + np.conj(tmp) * self.c04) / 4., x=-self.zarr, axis=1))
                        if any(tmp) > 10**-14:
                            d['T'][submod]['TM' + str(2 * n)] += tmp

        # Transport terms that are a function of the first order concentration, i.e. u0*c1 terms.
        for submod in d['hatc1']['a'].keys():
            if submod == 'erosion':
                for subsubmod in d['hatc1']['a'][submod].keys():
                    c1_comp = d['hatc1']['a'][submod][subsubmod]
                    d['T'] = self.dictExpand(d['T'], subsubmod, ['TM' + str(2 * n) for n in range(0, fmax + 1)])
                    tmp = c1_comp[:, :, 1]
                    tmp = np.real(np.trapz((self.u0 * np.conj(tmp) + np.conj(self.u0) * tmp) / 4., x=-self.zarr, axis=1))
                    if subsubmod == 'stokes':
                        if any(tmp) > 10**-14:
                            d['T'][subsubmod] = self.dictExpand(d['T'][subsubmod], 'TM2', ['return', 'drift'])
                            d['T'][subsubmod]['TM2']['return'] += tmp
                    else:
                        if any(tmp) > 10**-14:
                            d['T'][subsubmod]['TM2'] += tmp
            else:
                c1_comp = d['hatc1']['a'][submod]
                d['T'] = self.dictExpand(d['T'], submod, ['TM' + str(2 * n) for n in range(0, fmax + 1)])
                tmp = c1_comp[:, :, 1]
                tmp = np.real(np.trapz((self.u0 * np.conj(tmp) + np.conj(self.u0) * tmp) / 4., x=-self.zarr, axis=1))
                if any(tmp) > 10**-14:
                    d['T'][submod]['TM2'] += tmp

        # Transport terms that are related to diffusion, i.e. K_h*c0 or K_h*c2
        d['T'] = self.dictExpand(d['T'], 'diffusion_tide', ['TM' + str(2 * n) for n in range(0, fmax + 1)])
        d['T']['diffusion_tide']['TM0'] = np.real(-np.trapz(self.KH * self.c00x, x=-self.zarr, axis=1))
        d['T'] = self.dictExpand(d['T'], 'diffusion_river', ['TM' + str(2 * n) for n in range(0, fmax + 1)])
        tmp = d['hatc2']['a']['erosion']['river_river'][:, :, 0]
        tmp, __ = np.gradient(tmp, self.x[1], edge_order=2)
        tmp = np.real(-np.trapz(self.KH * tmp, x=-self.zarr, axis=1))
        if any(tmp) > 10**-14:
            d['T']['diffusion_river']['TM0'] = tmp

        # Transport terms that are related to Stokes drift, i.e. u0*c0*zeta0
        if 'stokes' in self.submodules_hydro:
            for n in (0, 2):
                u0s = self.u0[:, 0]
                tmp = d['hatc0']['a']['erosion'][:, 0, n]
                if n==0:
                    tmp = np.real(np.conj(u0s) * tmp * self.zeta0[:, 0] + u0s * tmp * np.conj(self.zeta0[:, 0])) / 4
                elif n==2:
                    tmp = np.real(u0s * np.conj(tmp) * self.zeta0[:, 0] + np.conj(u0s) * tmp * np.conj(self.zeta0[:, 0])) / 8
                if any(tmp) > 10**-14:
                    d['T']['stokes']['TM' + str(2 * n)]['drift'] = tmp


        # Transport term that is related to the river-river interaction u1river*c2river
        d['T'] = self.dictExpand(d['T'], 'river_river', ['TM' + str(2 * n) for n in range(0, fmax + 1)])
        if self.input.v('u1', 'river') is not None:
            u1_comp = self.input.v('u1', 'river', range(0, jmax+1), range(0, kmax+1), 0)
            tmp = d['hatc2']['a']['erosion']['river_river'][:, :, 0]
            d['T']['river_river']['TM0'] = np.real(np.trapz(u1_comp * tmp, x=-self.zarr, axis=1))

        ## Diffusion F #################################################################################################
        # Diffusive part, i.e. Kh*c00 and Kh*c20
        d['F'] = self.dictExpand(d['F'], 'diffusion_tide', ['FM' + str(2 * n) for n in range(0, fmax + 1)])
        d['F']['diffusion_tide']['FM0'] = np.real(-np.trapz(self.KH * self.c00, x=-self.zarr, axis=1))
        d['F'] = self.dictExpand(d['F'], 'diffusion_river', ['FM' + str(2 * n) for n in range(0, fmax + 1)])
        tmp = d['hatc2']['a']['erosion']['river_river'][:, :, 0]
        tmp = np.real(-np.trapz(self.KH * tmp, x=-self.zarr, axis=1))
        d['F']['diffusion_river']['FM0'] = tmp

        # Part of F that is related to sediment advection, i.e. u0*c1sedadv
        for submod in d['hatc1']['ax'].keys():
            c1_comp = d['hatc1']['ax'][submod]
            d['F'] = self.dictExpand(d['F'], submod, ['FM' + str(2 * n) for n in range(0, fmax + 1)])
            tmp = c1_comp[:, :, 1]
            tmp = np.real(np.trapz((self.u0 * np.conj(tmp) + np.conj(self.u0) * tmp) / 4., x=-self.zarr, axis=1))
            if any(tmp) > 10**-14:
                d['F']['sedadv']['FM2'] += tmp

        ################################################################################################################
        # Calculate availability
        ################################################################################################################
        # Add all mechanisms to datacontainer
        dctrans = DataContainer(d)
        # Calculate availability
        d['a'] = {}
        d['a'] = self.availability(dctrans.v('F'), dctrans.v('T')).reshape(len(self.x), 1)
        ax = np.gradient(d['a'][:, 0], self.x[1], edge_order=2).reshape(len(self.x), 1)

        ################################################################################################################
        # Calculate concentrations, i.e. a*hatc(a) + ax*hatc(ax)
        ################################################################################################################
        d['c0'] = {}
        d['c1'] = {}
        d['c2'] = {}
        # Calculate a*c0(a)
        for submod in d['hatc0']['a'].keys():
            c0_comp = d['hatc0']['a'][submod]
            d['c0'][submod] = {}
            tmp = d['a'][:, None] * c0_comp
            d['c0'][submod] = tmp

        # Calculate a*c1(a) + ax*c1(ax)
        for submod in d['hatc1']['a'].keys():
            if submod == 'erosion':
                for subsubmod in d['hatc1']['a'][submod].keys():
                    c1_comp = d['hatc1']['a'][submod][subsubmod]
                    d['c1'] = self.dictExpand(d['c1'], submod, subsubmod)
                    tmp = d['a'][:, None] * c1_comp
                    d['c1'][submod][subsubmod] = tmp
            elif submod == 'sedadv':
                c1_comp_a = d['hatc1']['a'][submod]
                c1_comp_ax = d['hatc1']['ax'][submod]
                d['c1'][submod] = {}
                tmp = d['a'][:, None] * c1_comp_a + ax[:, None] * c1_comp_ax
                d['c1'][submod] = tmp
            else:
                c1_comp = d['hatc1']['a'][submod]
                d['c1'][submod] = {}
                tmp = d['a'][:, None] * c1_comp
                d['c1'][submod] = tmp

        # Calculate a*c2(a)
        for submod in d['hatc2']['a']['erosion'].keys():
            c2_comp = d['hatc2']['a']['erosion'][submod]
            d['c2'] = self.dictExpand(d['c2'], 'erosion', submod)
            tmp = d['a'][:, None] * c2_comp
            d['c2']['erosion'][submod] = tmp
        return d
Example #7
0
 def __init__(self, dimNames):
     FunctionBase.__init__(self, dimNames)
     self.dataContainer = DataContainer()
     self.valueSize = 0
     return
Example #8
0
    def run(self):
        d = {}
        d['Scheldt_measurements'] = {}

        ################################################################################################################
        # data
        ################################################################################################################
        # Stations (optional)
        station_names = [
            'Vlissingen', 'Terneuzen', 'Hansweert', 'Bath', 'Prosperpolder',
            'Liefkenshoek', 'Antwerpen', 'Temse', 'St. Amands', 'Dendermonde',
            'Schoonaarde', 'Wetteren', 'Melle'
        ]
        x_station = np.asarray([
            0., 18.5, 33.8, 49.8, 54, 61.1, 75.6, 97.3, 106.8, 119.8, 130.6,
            142.7, 148.8
        ]) * 1000.
        river_sections = {
            'Western Scheldt': [0, 1, 2, 3],
            'Lower Sea Scheldt': [4, 5, 6],
            'Upper Sea Scheldt': [7, 8, 9, 10, 11, 12]
        }

        # Stations (optional)
        L = 160000.

        # Water Level Measurements (mandatory)
        x_waterlevel = np.asarray([
            0., 18.5, 33.8, 49.8, 54, 61.1, 75.6, 97.3, 106.8, 119.8, 130.6,
            142.7, 148.8
        ]) * 1000.  # x-coordinate of the measurement locations (in m)
        phaseM2mouth = 0.  # Phase of the M2 tidal water level at the mouth (x=0).

        M2amp = np.asarray([
            1.77, 1.98, 2.03, 2.18, 2.19, 2.26, 2.31, 2.28, 2.22, 1.69, 1.31,
            1.09, 1.02
        ])  # M2 amplitude (in m)
        M2phase = np.asarray([
            0, 10.4, 20.5, 31.1, 33.1, 35.6, 44.3, 62.7, 73.4, 93.3, 116.4,
            143.4, 157.4
        ]) - phaseM2mouth  # M2 phase (in deg)
        M4amp = np.asarray([
            0.14, 0.12, 0.11, 0.11, 0.12, 0.12, 0.13, 0.16, 0.24, 0.25, 0.24,
            0.21, 0.22
        ])  # M4 amplitude (in m)
        M4phase = np.asarray([
            -1.3, 12.3, 39.4, 58.7, 62.2, 65.1, 74.6, 88.2, 101.7, 128.7,
            164.3, 212.6, 242.9
        ]) - 2 * phaseM2mouth  # M4 amplitude (in m)

        # Velocity measurements (optional)
        x_station_vel = np.asarray(
            [17, 28, 40, 41, 63, 74, 85, 102, 120, 132, 140]) * 1000.
        M0vel = np.asarray([
            -0.096, -0.09, -0.011, -0.040, -0.007, -0.1, 0.005, -0.011, 0.117,
            -0.144, 0.037
        ])  # subtidal velocity
        M2velamp = np.asarray([
            1., 1.096, 0.785, 0.818, 0.332, 0.813, 0.56, 0.627, 0.798, 0.680,
            0.190
        ])
        M2velphase = np.asarray([
            301, 285, 164, 176, 243, 298, 344, 291, 103, 283, 98
        ]) - phaseM2mouth
        M4velamp = np.asarray([
            0.109, 0.069, 0.112, 0.066, 0.033, 0.079, 0.085, 0.154, 0.226,
            0.254, 0.084
        ])
        M4velphase = np.asarray([
            311, 281, 69, 67, 234, 28, 329, 248, 27, 221, 22
        ]) - 2 * phaseM2mouth

        ################################################################################################################
        # process data
        ################################################################################################################
        water_level = np.zeros((len(x_waterlevel), 3), dtype=complex)
        water_level[:, 0] = np.nan
        water_level[:, 1] = M2amp * np.exp(-M2phase / 180. * np.pi * 1j)
        water_level[:, 2] = M4amp * np.exp(-M4phase / 180. * np.pi * 1j)

        u_comp = np.zeros((len(x_station_vel), 3), dtype=complex)
        u_comp[:, 0] = M0vel
        u_comp[:, 1] = M2velamp * np.exp(-M2velphase / 180. * np.pi * 1j)
        u_comp[:, 2] = M4velamp * np.exp(-M4velphase / 180. * np.pi * 1j)

        ################################################################################################################
        # grid
        ################################################################################################################
        grid = {}
        grid['gridtype'] = 'Regular'
        grid['dimensions'] = ['x', 'f']
        grid['axis'] = {}
        grid['maxIndex'] = {}
        grid['low'] = {}
        grid['high'] = {}
        grid['contraction'] = [[], []]

        grid['high']['x'] = L
        grid['low']['x'] = 0.
        grid['high']['f'] = None
        grid['low']['f'] = None
        grid['axis']['f'] = np.asarray([0, 1, 2]).reshape((1, 3))
        grid['maxIndex']['f'] = 2

        grid_waterlevel = grid
        grid_velocity = copy.deepcopy(grid)

        grid_waterlevel['axis']['x'] = x_waterlevel / grid['high']['x']
        grid_waterlevel['maxIndex']['x'] = len(x_waterlevel) - 1
        grid_velocity['axis']['x'] = x_station_vel / grid['high']['x']
        grid_velocity['maxIndex']['x'] = len(x_station_vel) - 1

        grid_waterlevel = DataContainer({'grid': grid_waterlevel})
        grid_velocity = DataContainer({'grid': grid_velocity})

        ################################################################################################################
        # load to dictionary
        ################################################################################################################
        # stations
        d['Scheldt_measurements']['x_stations'] = x_station
        d['Scheldt_measurements']['stations'] = station_names
        d['Scheldt_measurements']['sections'] = river_sections

        # water level
        nf = nifty.functionTemplates.NumericalFunctionWrapper(
            water_level, grid_waterlevel)
        d['Scheldt_measurements']['zeta'] = nf.function
        d['Scheldt_measurements']['x_waterlevel'] = x_waterlevel

        # velocity
        nfu2 = nifty.functionTemplates.NumericalFunctionWrapper(
            u_comp, grid_velocity)  # now saved without phase data
        d['Scheldt_measurements']['x_velocity'] = x_station_vel
        d['Scheldt_measurements']['u_comp'] = nfu2.function

        return d
Example #9
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
    def run(self):
        """Run function to initiate the calculation of the sediment concentration based on dynamic erodibility. Hereby,
        we solve the following three equations:

        S_t = - [Flux_x + Flux * (B_x/B)]                    (1)

        Flux = T*f + F*f_x                                   (2)

        f = f(Stilde)                                        (3)

        with:

        S      = sediment stock, which is the total amount of sediment in the water column and the erodible bottom
        Flux   = sediment transport
        f      = relative sediment erodibility
        B      = estuary width
        T      = transport function
        F      = diffusion function
        Stilde = S / Chat, with Chat is the subtidal carrying capacity

         Returns:
             Dictionary with results. At least contains the variables listed as output in the registry
         """
        self.logger.info('Running module DynamicAvailability')

        ## Initiate variables
        # general variables
        self.RHOS = self.input.v('RHOS')
        self.DS = self.input.v('DS')
        self.WS = self.input.v('ws0')
        self.GPRIME = self.input.v('G') * (
            self.RHOS - self.input.v('RHO0')) / self.input.v('RHO0')
        self.Mhat = self.input.v('Mhat')
        self.CSEA = self.input.v('csea')
        self.FCAP = self.input.v('fcap')
        self.P = self.input.v('p')
        self.TOL = self.input.v('tol')
        self.ASTAR = self.input.v('astar')
        self.Kh = self.input.v('Kh')
        self.L = self.input.v('L')
        self.x = self.input.v('grid', 'axis', 'x') * self.L
        self.dx = (self.x[1:] - self.x[:-1]).reshape(len(self.x) - 1, 1)
        jmax = self.input.v('grid', 'maxIndex', 'x')
        kmax = self.input.v('grid', 'maxIndex', 'z')
        fmax = self.input.v('grid', 'maxIndex', 'f')
        self.z = self.input.v('grid', 'axis', 'z', 0, range(0, kmax + 1))
        self.zarr = ny.dimensionalAxis(self.input.slice('grid'), 'z')[:, :, 0]
        self.H = (self.input.v('H', range(0, jmax + 1)).reshape(jmax + 1, 1) +
                  self.input.v('R', range(0, jmax + 1)).reshape(jmax + 1, 1))
        self.Hx = (self.input.d('H', range(0, jmax + 1), dim='x').reshape(
            jmax + 1, 1) + self.input.d('R', range(0, jmax + 1),
                                        dim='x').reshape(jmax + 1, 1))
        self.B = self.input.v('B', range(0, jmax + 1)).reshape(jmax + 1, 1)
        self.Bx = self.input.d('B', range(0, jmax + 1),
                               dim='x').reshape(jmax + 1, 1)
        self.sf = self.input.v('Roughness', range(0, jmax + 1), 0,
                               0).reshape(jmax + 1, 1)
        self.Av0 = self.input.v('Av', range(0, jmax + 1), 0,
                                0).reshape(jmax + 1, 1)

        # velocity
        self.u1river = np.real(
            self.input.v('u1', 'river', range(0, jmax + 1), range(0, kmax + 1),
                         0))
        self.Q_fromhydro = -np.trapz(self.u1river[-1, :],
                                     x=-self.zarr[-1, :]) * self.B[-1]

        # c hat
        self.c00 = np.real(
            self.input.v('hatc0', range(0, jmax + 1), range(0, kmax + 1), 0))
        self.c04 = self.input.v('hatc0', range(0, jmax + 1),
                                range(0, kmax + 1), 2)

        ## Compute transport (in superclass)
        d = self.compute_transport()
        dc = DataContainer(d)
        self.Fc = (dc.v('F', range(0, jmax + 1)) -
                   dc.v('F', 'diffusion_river', range(0, jmax + 1))).reshape(
                       jmax + 1, 1)
        self.Tc = (dc.v('T') -
                   (dc.v('T', 'river', range(0, jmax + 1)) +
                    dc.v('T', 'river_river', range(0, jmax + 1)) +
                    dc.v('T', 'diffusion_river', range(0, jmax + 1)))).reshape(
                        len(self.x), 1)
        self.TQ = dc.v('T', 'river', range(0, jmax + 1)).reshape(
            jmax + 1, 1) / self.Q_fromhydro

        ## User input
        #TODO: make a consistent and effective script that handles user input of the discharge time series or any other time-dependent variable
        #load time serie Q
        self.dt = self.interpretValues(self.input.v('dt'))
        if self.input.v('t') is not None:
            self.t = self.interpretValues(self.input.v('t'))
        self.Q = self.interpretValues(self.input.v('Q'))

        ## Run
        self.logger.info('Running time-integrator')
        vars = self.implicit()

        ## Collect output
        d = {}
        for key, value in vars.iteritems():
            d[key] = value
        return d
Example #11
0
    def run(self):
        """invoke the saveData() method to save by using Pickle.

        Returns:
            Empty dictionary.
        """
        self.logger.info('Saving output')

        ################################################################################################################
        # Make all variables from config, input and modules available (note, config not available in output module, see Program.py)
        ################################################################################################################
        # read input file
        reader = Reader()
        reader.open(self.input.v('inputFile'))
        data = reader.read('module')
        reader.close()

        # merge the datacontainers of all modules & make the module tags into a list of modules
        inputvars = DataContainer()
        module = []
        for d in data:
            module.append(d.v('module'))
            inputvars.merge(d)
        inputvars.addData('module', module)

        # merge input vars with self.input in hierarchy config, input, input for this module, vars calculated in other modules (low - high)
        # + make a list of all keys of input and config vars; these are saved always and later appended by selected module calc. vars.
        data = self.__loadConfig()
        data.merge(inputvars)
        outputKeys = self.__checkInputOverrides(
            data
        )  # checks if input is overwritten and provides the keys of not or correctly overwritten input vars
        data.merge(self.input)
        del inputvars, reader
        # now all variables from config, input and modules are in 'data'

        ################################################################################################################
        # Isolate part of DC to write; put this in saveData
        ################################################################################################################
        saveData = DataContainer()

        # vars to save
        outputVariables = toList(self.input.v('requirements'))
        outputKeys = list(
            set(outputKeys + self.__getSubmoduleRequirements(outputVariables))
        )  # convert the requested output variables to key tuples including submodule requirements
        for key in outputKeys:
            if len(key) > 1:
                saveData.merge({key[0]: data.slice(*key).data})
            else:
                saveData.merge(data.slice(*key))

        # add grid and outputgrid if available; needed for interpolating data to outputgrid later
        saveData.merge(self.input.slice('grid'))
        saveData.merge(self.input.slice(self.outputgridName))

        # add reference level to outputgrid
        if self.input.v('R') is not None:
            self.input.merge({
                self.outputgridName: {
                    'low': {
                        'z':
                        self.input.v('R',
                                     x=self.input.v(self.outputgridName,
                                                    'axis', 'x'))
                    }
                }
            })  # add reference level to outputgrid

        # make a deepcopy of the data to be saved
        # NB. very memory inefficient, but needed not to overwrite existing data
        saveData = deepcopy(saveData)

        ################################################################################################################
        # Convert data using output grid (if this is provided)
        ################################################################################################################
        grid = saveData.slice('grid')
        outputgrid = saveData.slice(self.outputgridName)
        saveAnalytical = toList(self.input.v('saveAnalytical')) or []
        dontConvert = toList(self.input.v('dontConvert')) or []
        if 'all' in saveAnalytical:
            saveAnalytical = outputVariables
        if 'all' in dontConvert:
            dontConvert = outputVariables
        self._convertData(saveData, grid, outputgrid, saveAnalytical,
                          dontConvert)

        # rename the outputgrid to grid and replace the original grid in saveData
        saveData.addData('grid', saveData.data[self.outputgridName])
        saveData.data.pop(self.outputgridName)

        ################################################################################################################
        # Make the output directory if it doesnt exist
        ################################################################################################################
        cwdpath = cfm.CWD  # path to working directory
        self.path = os.path.join(cwdpath, self.input.v('path'))
        if not self.path[-1] == '/':
            self.path += '/'
        if not os.path.exists(self.path):
            os.makedirs(self.path)

        ################################################################################################################
        # set file name and save data
        ################################################################################################################
        filename = self.__makeFileName()

        # write
        filepath = (self.path + filename + self.ext)
        try:
            with open(filepath, 'wb') as fp:
                pickle.dump(saveData.data,
                            fp,
                            protocol=pickle.HIGHEST_PROTOCOL)
        except:
            raise

        ################################################################################################################
        # return
        ################################################################################################################
        d = {}
        d['outputDirectory'] = self.path
        return d