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
def lineplot(self, axis1, axis2, *args, **kwargs): """ Makes a lineplot of a variable over a certain axes Parameters: axis1: string axis plotted on the horizontal axis axis2: string variable plotted on the vertical axis args: kwargs: x, z, f: integer or range of integers plots the given range of the associated dimension subplots: string generates subplots of the physical variable over the given string: 'sublevel' or 'f'. If 'sublevel', all sublevels that are associated with the physical variable appear in a subplot. If 'f', subplots will be generated over the frequency domain sublevel: boolean show sub-level data or not plotno: integer plot number operation: python function makes an operation on the physical variable using the python function. This function could be for instance a numpy function (e.g. np.abs, np.angle, np.imag or np.real) or a nifty function (e.g. ny.scalemax) """ # determine which axis displays data and which grid information axis = [axis1, axis2] # list of both axis del axis1, axis2 gridAxisNo = [i for i, grid in enumerate(axis) if grid in self.dims][0] # number of grid axis dataAxisNo = np.mod(gridAxisNo+1, 2) # number of data axis # TODO: error if no valid axis provided # TODO: handle time axis # get all keys/subkeys to data keyList = [axis[dataAxisNo]]+[i for i in args if isinstance(i, basestring)] # key + subkeys to data # display a sub-level yes/no subplots = kwargs.get('subplots') or None # which (if any) var to display in subplots sublevel = kwargs.get('sublevel') or False # show sub-level data: True/False plotno = kwargs.get('plotno') or 1 # set plot number (default 1) looplist = [dim for dim in kwargs if dim in self.dims and dim != axis[gridAxisNo]]+['sublevel']*sublevel # list of variables to loop over: i.e. grid axis that are not one of the axis + subplots # checks: no more than two loop variables not in subplots, maximum one var in subplots # TODO ####### # determine values to loop plot over loopvalues = [None]*len(looplist) for i, loopvar in enumerate(looplist): if loopvar=='sublevel': loopvalues[i] = ny.toList(self.input.getKeysOf(*keyList)) else: loopvalues[i] = ny.toList(kwargs[loopvar]) # take all combinations of values if len(loopvalues) >= 1: permutations = itertools.product(*loopvalues) else: permutations = [None] # 13-02-2017 YMD ######### # determine number and shape of subplots numberOfSubplots = [len(loopvalues[ii]) for ii in range(0, len(looplist)) if looplist[ii] in ny.toList(subplots)] or [1] numberOfSubplots = numberOfSubplots[0] if numberOfSubplots <= 1: subplotShape = (1, 1) elif numberOfSubplots == 2: subplotShape = (1, 2) elif numberOfSubplots <= 8: subplotShape = (int(math.ceil(numberOfSubplots/2.)), 2) elif numberOfSubplots <= 15: subplotShape = (int(math.ceil(numberOfSubplots/3.)), 3) else: subplotShape = (int(math.ceil(numberOfSubplots/4.)), 4) ######### # plot loop plt.figure(plotno, dpi=cf.dpi, figsize=subplotShape) # plt.hold(True) # loop over all combinations of the data for combi in permutations: if subplots in looplist: # make subplot frame if there are subplots subplotIndex = looplist.index(subplots) subplot_number = loopvalues[subplotIndex].index(combi[subplotIndex]) plt.subplot(*(subplotShape+(subplot_number+1,))) ## load data d = {} d[axis[gridAxisNo]] = self.input.v('grid', 'axis', axis[gridAxisNo]).reshape(self.input.v('grid', 'maxIndex', axis[gridAxisNo])+1) # append keylist with current sublevel keyListTemp = copy(keyList) try: for k in range(0, len(combi)): if looplist[k] == 'sublevel': keyListTemp.append(combi[k]) else: d[looplist[k]] = combi[k] except: pass # set axes axisData = [None]*2 if not kwargs.get('der'): axisData[dataAxisNo] = self.input.v(*keyListTemp, **d) else: d['dim'] = kwargs['der'] axisData[dataAxisNo] = self.input.d(*keyListTemp, **d) d.pop('dim') axisData[gridAxisNo] = ny.dimensionalAxis(self.input.slice('grid'), axis[gridAxisNo], **d) if kwargs.get('operation'): if kwargs.get('operation') is not np.angle: axisData[dataAxisNo] = kwargs['operation'](axisData[dataAxisNo]) else: axisData[dataAxisNo] = -kwargs['operation'](axisData[dataAxisNo]) * 180 / np.pi conv_grid = cf.conversion.get(axis[gridAxisNo]) or 1. # convert size of axis depending on conversion factor in config conv_data = cf.conversion.get(keyListTemp[0]) or 1. axisData[dataAxisNo] = axisData[dataAxisNo]*conv_data axisData[gridAxisNo] = axisData[gridAxisNo]*conv_grid if sublevel and subplots is None: lab = combi[-1] try: lab = cf.names[lab] except: pass plt.plot(*axisData, label=lab) plt.legend(fontsize=cf.fontsize2) else: plt.plot(*axisData) ## Title and axis labels if numberOfSubplots > 1: if subplots == 'sublevel': title = combi[subplotIndex] else: title = subplots + ' = ' + str(combi[subplotIndex]) try: title = cf.names[title] except: pass plt.title(title, fontsize=cf.fontsize) # axis labels. Try to get from config file, else take plain name try: xname = cf.names[axis[0]] xunit = cf.units[axis[0]] except KeyError: xname = axis[0] xunit = '' try: yname = cf.names[axis[1]] yunit = cf.units[axis[1]] except KeyError: yname = axis[1] yunit = '' plt.xlabel(xname+' ('+xunit+')', fontsize=cf.fontsize) plt.ylabel(yname+' ('+yunit+')', fontsize=cf.fontsize) plt.xticks(fontsize=cf.fontsize2) plt.yticks(fontsize=cf.fontsize2) if kwargs.get('operation')==np.abs: if dataAxisNo==0: plt.xlabel('|'+xname+'|'+' ('+xunit+')', fontsize=cf.fontsize) else: plt.ylabel('|'+yname+'|'+' ('+yunit+')', fontsize=cf.fontsize) elif kwargs.get('operation')==np.angle: if dataAxisNo==0: plt.xlabel('Phase('+xname+')'+' ('+cf.units['phase']+')', fontsize=cf.fontsize) else: plt.ylabel('Phase('+yname+')'+' ('+cf.units['phase']+')', fontsize=cf.fontsize) elif kwargs.get('operation')==np.real: if dataAxisNo==0: plt.xlabel('Re('+xname+')'+' ('+xunit+')', fontsize=cf.fontsize) else: plt.ylabel('Re('+yname+')'+' ('+yunit+')', fontsize=cf.fontsize) elif kwargs.get('operation')==np.imag: if dataAxisNo==0: plt.xlabel('Im('+xname+')'+' ('+xunit+')', fontsize=cf.fontsize) else: plt.ylabel('Im('+yname+')'+' ('+yunit+')', fontsize=cf.fontsize) if kwargs.get('operation')==np.abs: if dataAxisNo==0: plt.xlabel('|'+xname+'|'+' ('+xunit+')', fontsize=cf.fontsize) else: plt.ylabel('|'+yname+'|'+' ('+yunit+')', fontsize=cf.fontsize) if axis[0] == 'x': plt.xlim(np.min(axisData[gridAxisNo]), np.max(axisData[gridAxisNo])) if kwargs.get('suptitle'): plt.suptitle(kwargs.get('suptitle'), fontsize=cf.fontsize) else: try: plt.suptitle(cf.names[axis[dataAxisNo]]+' over '+axis[gridAxisNo], fontsize=cf.fontsize) except KeyError: plt.suptitle(axis[dataAxisNo]+' over '+axis[gridAxisNo], fontsize=cf.fontsize) plt.draw() return
def transportplot_mechanisms(self, **kwargs): """ Plots the advective transport based on the physical mechanisms that force it. kwargs: sublevel: string displays underlying levels of the associated mechanisms: 'sublevel', 'subsublevel' or False plotno: integer plot number display: integer or list of strings displays the underlying mechanisms indicated. An integer plots the largest contributions up to that integer and a list of strings plots the mechanisms in that list scale: boolean scales the transport contributions to the maximum value of all contributions concentration: boolean plots the depth-mean, sub-tidal concentration in the background """ ################################################################################################################ # Extract args and/or kwargs ################################################################################################################ sublevel = kwargs.get('sublevel') or kwargs.get('subsublevel') or False # show sub-level data: True/False plotno = kwargs.get('plotno') or 1 # set plot number (default 1) display = kwargs.get('display') or 5 # display number of mechanisms (sorted in descending order) or specific mechanisms scale = kwargs.get('scale') or False # scale the transport contributions to the maximum: True/False concentration = kwargs.get('concentration') or False legend = kwargs.get('legend') if legend !='in': legend = 'out' ################################################################################################################ # Construct list of mechanisms to display and calculate these mechanisms ################################################################################################################ # get keys of the transport mechanisms to display entered by the user or all mechanism if isinstance(display, list): if set(display).issubset(self.input.getKeysOf('T')): keyList = display else: raise KnownError('Not all transport mechanisms passed with display are available.') else: keyList = self.input.getKeysOf('T') # get availability and its derivative w.r.t. x x = self.input.v('grid', 'axis', 'x') if self.input.v('f') is not None: a = self.input.v('f', x=x).reshape(len(x),) a_x = self.input.d('f', x=x, dim='x').reshape(len(x),) else: a = self.input.v('a').reshape(len(x),) a_x = -self.input.v('T') * a / self.input.v('F') # construct list with values to plot loopvalues = [[]] if sublevel: tmp_max = [] for key in keyList: if not 'diffusion' in key: T = self.input.v('T', key) if key in self.input.getKeysOf('F'): trans = T * a + self.input.v('F', key) * a_x loopvalues[0].append([trans, np.sqrt(np.mean(np.square(trans))), key]) else: trans = T * a loopvalues[0].append([trans, np.sqrt(np.mean(np.square(trans))), key]) tmp_max.append(abs(trans).max()) if sublevel == 'subsublevel' and len(self.input.slice('T', key).getAllKeys()[0]) > 2: loopvalues.append([]) tmpkeys = sorted(self.input.slice('T', key).getAllKeys(), key=itemgetter(2)) subkeys = [tmpkeys[i*3:3+i*3] for i in range(len(tmpkeys)/3)] for subkey in subkeys: tmp = np.zeros(a.shape) for subsubkey in subkey: tmp += self.input.v('T', *subsubkey) * a loopvalues[len(loopvalues)-1].append([tmp, np.sqrt(np.mean(np.square(trans))), subsubkey[-1]]) loopvalues[len(loopvalues)-1].append([trans, np.sqrt(np.mean(np.square(trans))), key]) maxT = max(tmp_max) # Sort transport mechanisms based on the value of their root-mean-square value loopvalues[0] = sorted(loopvalues[0], key=itemgetter(1), reverse=True) # Only take the largest transport contributions indicated by the display integer. If the display integer is # larger than the length of the keyList, then all contributions are taken into account if isinstance(display, int): loopvalues[0] = loopvalues[0][:min(display, len(keyList))] # Sort alphetically so that mechanisms receive the same line color for plotting loopvalues[0] = sorted(loopvalues[0], key=itemgetter(2)) else: Ttotal = ((self.input.v('T') - self.input.v('T', 'diffusion_tide') - self.input.v('T', 'diffusion_river')) * a + (self.input.v('F') - self.input.v('F', 'diffusion_tide') - self.input.v('F', 'diffusion_river') ) * a_x) loopvalues[0].append([Ttotal, np.sqrt(np.mean(np.square(Ttotal))), 'total']) maxT = abs(Ttotal).max() ################################################################################################################ # determine number and shape of subplots ################################################################################################################ numberOfSubplots = len(loopvalues) subplotShape = (numberOfSubplots, 2) ################################################################################################################ # plot ################################################################################################################ ## load grid data xdim = ny.dimensionalAxis(self.input.slice('grid'), 'x')[:, 0, 0] conv_grid = cf.conversion.get('x') or 1. # convert size of axis depending on conversion factor in config xdim = xdim * conv_grid ## plot plt.figure(plotno, dpi=cf.dpi, figsize=subplotShape) # plt.hold(True) if not sublevel: sp = plt.subplot() plt.axhline(0, color='k', linewidth=0.5) if scale: loopvalues[0][0][0] = loopvalues[0][0][0] / maxT ln = [] ln += sp.plot(xdim, loopvalues[0][0][0], label='adv. transport') if concentration: conv = cf.conversion.get('c') or 1. c = np.real(np.mean(self.input.v('c0')[:, :, 0] + self.input.v('c1')[:, :, 0] + self.input.v('c2')[:, :, 0], axis=1))*conv if scale: c = c / c.max() ln += sp.plot(xdim, c, '--', color='grey', label=r'$\langle\bar{c}\rangle$') labels = [l.get_label() for l in ln] if legend is 'out': plt.legend(ln, labels, bbox_to_anchor=(1.02, 0), loc=3, borderaxespad=0., fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4) elif legend is 'in': plt.legend(ln, labels, loc='upper left', borderaxespad=0.2, fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4, frameon=False) plt.title('Advective Transport') else: sp2 = sp.twinx() ln += sp2.plot(xdim, c, '--', color='grey', label=r'$\langle\bar{c}\rangle$') labels = [l.get_label() for l in ln] if legend is 'out': plt.legend(ln, labels, bbox_to_anchor=(1.3, 0), loc=3, borderaxespad=0., fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4) elif legend is 'in': plt.legend(ln, labels, loc='upper left', borderaxespad=0.2, fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4, frameon=False) plt.title('Advective Transport', y=1.09) else: plt.title('Advective Transport') ## Axis labels try: xname = cf.names['x'] xunit = cf.units['x'] except KeyError: xname = 'x' xunit = '' plt.xlabel(xname + ' (' + xunit + ')', fontsize = cf.fontsize) try: yunitT = cf.units['T'] if concentration: if scale: sp.set_ylabel(r'$\mathcal{T}$ / $\mathcal{T}_{max}$, $c$ / $c_{max}$ (-)', fontsize = cf.fontsize) if legend is 'in': sp.set_ylim([-1.1, 1.1]) else: sp.set_ylim([-1.1, 1.1]) else: yunitc = cf.units['c'] sp.set_ylabel(r'$\mathcal{T}$ (' + yunitT + ')', fontsize = cf.fontsize) sp2.set_ylabel(r'$c$ (' + yunitc + ')', fontsize = cf.fontsize) else: if scale: sp.set_ylabel(r'$\mathcal{T}$ / $\mathcal{T}_{max}$ (' + yunitT + ')', fontsize = cf.fontsize) if legend is 'in': sp.set_ylim([-1.1, 1.1]) else: sp.set_ylim([-1.1, 1.1]) else: sp.set_ylabel(r'$\mathcal{T}$ (' + yunitT + ')', fontsize = cf.fontsize) except KeyError: yname = [r'$\mathcal{T}$'] yunit = '' plt.ylabel(yname + ' (' + yunit + ')', fontsize = cf.fontsize) else: for subplot_number, subplot_values in enumerate(loopvalues): pos = np.unravel_index(subplot_number, subplotShape) sp = plt.subplot2grid(subplotShape, (pos[0], pos[1])) plt.axhline(0, color='k', linewidth=0.5) # loop over all combinations of the data ln = [] for i, value in enumerate(subplot_values): try: label = cf.transportlabels[value[2]] except KeyError: label = value[2] if scale: value[0] = value[0] / maxT if i == len(subplot_values)-1 and subplot_number >= 1: ln += sp.plot(xdim, value[0], 'k', label=label) else: ln += sp.plot(xdim, value[0], label=label) if concentration and subplot_number == 0: conv = cf.conversion.get('c') or 1. c = np.real(np.mean(self.input.v('c0')[:, :, 0] + self.input.v('c1')[:, :, 0] + self.input.v('c2')[:, :, 0], axis=1)) * conv if scale: c = c / c.max() ln += sp.plot(xdim, c, '--', color='grey', label=r'$\langle\bar{c}\rangle$') labels = [l.get_label() for l in ln] if legend is 'out': plt.legend(ln, labels, bbox_to_anchor=(1.02, 0), loc=3, borderaxespad=0., fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4) elif legend is 'in': plt.legend(ln, labels, loc='upper left', borderaxespad=0.2, fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4, frameon=False) if subplot_number == 0: plt.title('Advective Transport') else: title = keyList[subplot_number-1] try: title = cf.names[title] except: pass plt.title(title, fontsize=cf.fontsize) else: sp2 = sp.twinx() ln += sp2.plot(xdim, c, '--', color='grey', label=r'$\langle\bar{c}\rangle$') labels = [l.get_label() for l in ln] if legend is 'out': plt.legend(ln, labels, bbox_to_anchor=(1.3, 0), loc=3, borderaxespad=0., fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4) elif legend is 'in': plt.legend(ln, labels, loc='upper left', borderaxespad=0.2, fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4, frameon=False) if subplot_number == 0: plt.title(r'Advective Transport ', y=1.09, fontsize=cf.fontsize) else: title = keyList[subplot_number-1] try: title = cf.names[title] except: pass plt.title(title, y=1.09, fontsize=cf.fontsize) else: if legend is 'out': plt.legend(bbox_to_anchor=(1.02, 0), loc=3, borderaxespad=0., fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4) elif legend is 'in': plt.legend(ln, labels, loc='upper left', borderaxespad=0.2, fontsize=cf.fontsize2, labelspacing=0.1, handlelength=0.1, handletextpad=0.4, frameon=False) if subplot_number == 0: plt.title('Advective Transport', fontsize=cf.fontsize) else: title = keyList[subplot_number-1] try: title = cf.names[title] except: pass if concentration and subplot_number > 0: plt.title(title, y=1.09, fontsize=cf.fontsize) else: plt.title(title, fontsize=cf.fontsize) # axis labels and limits. Try to get from config file, else take plain name try: xname = cf.names['x'] xunit = cf.units['x'] except KeyError: xname = 'x' xunit = '' plt.xlabel(xname + ' (' + xunit + ')', fontsize=cf.fontsize) try: yunitT = cf.units['T'] if concentration: if scale: if subplot_number == 0: sp.set_ylabel(r'$\mathcal{T}$ / $\mathcal{T}_{max}$, $c$ / $c_{max}$ (-)', fontsize=cf.fontsize) else: sp.set_ylabel(r'$\mathcal{T}$ / $\mathcal{T}_{max}$ (-)', fontsize=cf.fontsize) if legend is 'in': sp.set_ylim([-1.1, 1.1]) else: sp.set_ylim([-1.1, 1.1]) else: yunitc = cf.units['c'] sp.set_ylabel(r'$\mathcal{T}$ (' + yunitT + ')', fontsize=cf.fontsize) sp2.set_ylabel(r'$c$ (' + yunitc + ')', fontsize=cf.fontsize) else: if scale: sp.set_ylabel(r'$\mathcal{T}$ / $\mathcal{T}_{max}$ (' + yunitT + ')', fontsize=cf.fontsize) if legend is 'in': sp.set_ylim([-1.1, 1.1]) else: sp.set_ylim([-1.1, 1.1]) else: sp.set_ylabel(r'$\mathcal{T}$ (' + yunitT + ')', fontsize=cf.fontsize) except KeyError: yname = [r'$\mathcal{T}$'] yunit = '' plt.label(yname + ' (' + yunit + ')', fontsize=cf.fontsize) plt.xlim(0, max(xdim)) plt.draw() return
def cFunctionUncoupled(ws, Kv, F, Fsurf, Fbed, data, n, hasMatrix=False): #################################################################################################################### # Init #################################################################################################################### jmax = data.v('grid', 'maxIndex', 'x') # maximum index of x grid (jmax+1 grid points incl. 0) kmax = data.v('grid', 'maxIndex', 'z') # maximum index of z grid (kmax+1 grid points incl. 0) OMEGA = data.v('OMEGA') # Init Ctd nRHS = F.shape[-1] cCoef = np.zeros((jmax + 1, kmax + 1, 1, nRHS), dtype=complex) cMatrix = np.zeros((jmax + 1, 3, kmax + 1), dtype=complex) try: z = ny.dimensionalAxis(data.slice('grid'), 'z')[:, :, 0] except: z = -np.linspace(0, 1, kmax + 1).reshape((1, kmax + 1)) * np.ones( (jmax + 1, 1)) #################################################################################################################### # build, save and solve the matrices in every water column #################################################################################################################### for j in range(0, jmax + 1): dz = z[j, 1:] - z[j, :-1] dz = dz dz_down = dz[:-1] dz_up = dz[1:] dz_av = 0.5 * (dz_up + dz_down) if not hasMatrix: A = np.zeros((3, kmax + 1), dtype=complex) ##### LEFT HAND SIDE ##### # Build matrix. # NB. can use general numerical schemes as dz < 0 a = -0.5 * (Kv[j, 0:-2, 0] + Kv[j, 1:-1, 0]) / dz_down + ws[ j, 0:-2, 0] # for k-1: from 1..kmax-1 b = 0.5 * (Kv[j, 0:-2, 0] + Kv[j, 1:-1, 0]) / dz_down + 0.5 * ( Kv[j, 2:, 0] + Kv[j, 1:-1, 0]) / dz_up - ws[ j, 1:-1, 0] # for k: from 1..kmax-1 c = -0.5 * (Kv[j, 2:, 0] + Kv[j, 1:-1, 0]) / dz_up # for k+1: from 1..kmax # add inertia later # Build matrix k=1..kmax-1 A[2, :-2] = a A[1, 1:-1] = b A[0, 2:] = c ## surface b = ws[j, 0, 0] - Kv[j, 0, 0] / dz[0] c = +Kv[j, 0, 0] / dz[0] A[1, 0] = b A[0, 1] = c ## bed a = -Kv[j, 0, 0] / dz[-1] b = Kv[j, 0, 0] / dz[-1] A[2, -2] = a A[1, -1] = b # save matrix cMatrix[j, Ellipsis] = copy(A[Ellipsis]) else: A = copy(Kv[j, Ellipsis]) A[1, 1:-1] += n * 1j * OMEGA * dz_av ################################################################################################################ # Right hand side ################################################################################################################ RHS = np.zeros([kmax + 1, nRHS], dtype=complex) RHS[1:-1, :] = F[j, 1:-1, :] * dz_up.reshape((kmax - 1, 1)) RHS[0, :] = Fsurf[j, 0, :] RHS[-1, :] += Fbed[j, 0, :] ################################################################################################################ # Solve ################################################################################################################ cstag = solve_banded((1, 1), A, RHS, overwrite_ab=True, overwrite_b=True) cCoef[j, :, 0, :] = cstag.reshape(kmax + 1, nRHS) return cCoef, cMatrix
def contourplot(self, axis1, axis2, value_label, *args, **kwargs): """ Plots 2DV contourplots of a variable over two axes Parameters: axis1: string axis plotted on the horizontal axis axis2: string axis plotted on the vertical axis value_label: string physical variable for which the controurplot needs to be made args: kwargs: x, z, f: integer or range of integers plots the given range of the associated dimension subplots: string generates subplots of the physical variable over the given string: 'sublevel' or 'f'. If 'sublevel', all sublevels that are associated with the physical variable appear in a subplot. If 'f', subplots will be generated over the frequency domain plotno: integer plot number operation: python function makes an operation on the physical variable using the python function. This function could be for instance a numpy function (e.g. np.abs, np.angle, np.imag or np.real) or a nifty function (e.g. ny.scalemax) """ # get all keys/subkeys to data keyList = [value_label]+[i for i in args if isinstance(i, basestring)] # key + subkeys to data # display a sub-level yes/no subplots = kwargs.get('subplots') or False # Variable for subplots plotno = kwargs.get('plotno') or 1 # set plot number (default 1) loopvalues = [None] # values to loop subplots over if subplots == 'sublevel': loopvalues = ny.toList(self.input.getKeysOf(*keyList)) elif subplots: loopvalues = [i for i in ny.toList(kwargs[subplots])] # determine number and shape of subplots numberOfSubplots = len(loopvalues) if numberOfSubplots <= 1: subplotShape = (1, 1) elif numberOfSubplots == 2: subplotShape = (1, 2) elif numberOfSubplots <= 8: subplotShape = (int(math.ceil(numberOfSubplots / 2.)), 2) elif numberOfSubplots <= 15: subplotShape = (int(math.ceil(numberOfSubplots / 3.)), 3) else: subplotShape = (int(math.ceil(numberOfSubplots / 4.)), 4) # load axis data for evaluating the value to be plotted d = {} # contains all axis data for evaluating the function for key in kwargs: if key in self.input.v('grid', 'dimensions'): d[key] = kwargs[key] ## load axis data axis1_axis = self.input.v('grid', 'axis', axis1).reshape(self.input.v('grid', 'maxIndex', axis1) + 1) axis2_axis = self.input.v('grid', 'axis', axis2).reshape(self.input.v('grid', 'maxIndex', axis2) + 1) d[axis1] = axis1_axis d[axis2] = axis2_axis ######### # plot loop plt.figure(plotno, figsize=subplotShape) # plt.hold(True) # loop over all combinations of the data for subplot_number, sub in enumerate(loopvalues): plt.subplot(*(subplotShape+(subplot_number+1,))) # append keylist with current sublevel keyListTemp = copy(keyList) if subplots=='sublevel': keyListTemp.append(sub) elif subplots: d[subplots] = sub # load dimensional axes and the value to be plotted value = self.input.v(*keyListTemp, **d) axis1_dim = ny.dimensionalAxis(self.input.slice('grid'), axis1, **d) axis2_dim = ny.dimensionalAxis(self.input.slice('grid'), axis2, **d) if kwargs.get('operation'): if kwargs.get('operation') is not np.angle: value = kwargs['operation'](value) else: value = -kwargs['operation'](value) * 180 / np.pi else: value = np.real(value) conv = cf.conversion.get(axis1) or 1. # convert size of axis depending on conversion factor in config axis1_dim = axis1_dim*conv conv = cf.conversion.get(axis2) or 1. # convert size of axis depending on conversion factor in config axis2_dim = axis2_dim*conv conv = cf.conversion.get(value_label) or 1. # convert size of axis depending on conversion factor in config value = value*conv # set cmap if 'c' in value_label: cmap = 'YlOrBr' normalisecolor = mpl.colors.Normalize(vmin=0, vmax=np.amax(np.abs(value))) else: if np.amax(np.abs(value))==0: cmap = 'RdBu_r' normalisecolor = mpl.colors.Normalize(vmin=0, vmax=0) elif np.amin(value) >= 0: normalisecolor = mpl.colors.Normalize(vmin=0, vmax=np.amax(np.abs(value))) cmap = 'Reds' elif np.amax(value) <= 0: normalisecolor = mpl.colors.Normalize(vmin=np.amin(value), vmax=0) cmap = 'Blues_r' else: normalisecolor = mpl.colors.Normalize(vmin=-np.amax(np.abs(value)), vmax=np.amax(np.abs(value))) cmap = 'RdBu_r' # plot plt.pcolormesh(axis1_dim, axis2_dim, value, norm=normalisecolor, cmap=cmap, shading='gouraud') #, cmap='YlOrBr' plt.plot(axis1_dim[:,1], axis2_dim[:,-1], 'k-', linewidth=0.2) plt.plot(axis1_dim[:,0], axis2_dim[:,0], 'k-', linewidth=0.2) plt.plot(axis1_dim[-1,:], axis2_dim[-1,:], 'k-', linewidth=0.2) plt.plot(axis1_dim[0,:], axis2_dim[0,:], 'k-', linewidth=0.2) if int(mpl.__version__.split('.')[0])>1: plt.gca().set_facecolor([.75, .75, .75]) else: plt.gca().set_axis_bgcolor([.75, .75, .75]) cb = plt.colorbar() plt.xlim(np.min(axis1_dim), np.max(axis1_dim)) plt.ylim(np.min(axis2_dim), np.max(axis2_dim)) ## Title and axis labels if numberOfSubplots > 1: if subplots == 'sublevel': title = sub else: title = subplots + ' = ' + str(sub) try: title = cf.names[title] except: pass plt.title(title, fontsize=cf.fontsize) # axis labels. Try to get from config file, else take plain name try: xname = cf.names[axis1] xunit = cf.units[axis1] except KeyError: xname = axis1 xunit = '' try: yname = cf.names[axis2] yunit = cf.units[axis2] except KeyError: yname = axis2 yunit = '' plt.xlabel(xname+' ('+xunit+')', fontsize=cf.fontsize) plt.ylabel(yname+' ('+yunit+')', fontsize=cf.fontsize) plt.xticks(fontsize=cf.fontsize2) plt.yticks(fontsize=cf.fontsize2) try: value_name = cf.names[value_label] value_unit = cf.units[value_label] except: value_name = value_label value_unit = '' if numberOfSubplots > 1: if kwargs.get('operation')==np.abs or kwargs.get('operation')==abs: plt.suptitle('|'+value_name+'|'+' ('+value_unit+')', fontsize=cf.fontsize) elif kwargs.get('operation')==np.angle: plt.suptitle('Phase('+value_name+')'+' ('+cf.units['phase']+')', fontsize=cf.fontsize) elif kwargs.get('operation')==np.real: plt.suptitle('Re('+value_name+')'+' ('+value_unit+')', fontsize=cf.fontsize) elif kwargs.get('operation')==np.imag: plt.suptitle('Im('+value_name+')'+' ('+value_unit+')', fontsize=cf.fontsize) else: plt.suptitle(value_name+' ('+value_unit+')', fontsize=cf.fontsize) else: if kwargs.get('operation')==np.abs or kwargs.get('operation')==abs: plt.title('|'+value_name+'|'+' ('+value_unit+')', fontsize=cf.fontsize) elif kwargs.get('operation')==np.angle: plt.title('Phase('+value_name+')'+' ('+cf.units['phase']+')', fontsize=cf.fontsize) elif kwargs.get('operation')==np.real: plt.title('Re('+value_name+')'+' ('+value_unit+')', fontsize=cf.fontsize) elif kwargs.get('operation')==np.imag: plt.title('Im('+value_name+')'+' ('+value_unit+')', fontsize=cf.fontsize) else: plt.title(value_name+' ('+value_unit+')', fontsize=cf.fontsize) plt.draw() return
def run(self): """Run function to initiate the calculation of the first order water level and velocities Returns: Dictionary with results. At least contains the variables listed as output in the registry """ self.logger.info('Running module HydroFirst') # Initiate variables self.submodule = self.input.v('submodules') self.OMEGA = self.input.v('OMEGA') self.G = self.input.v('G') self.BETA = self.input.v('BETA') 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] kmax = self.input.v('grid', 'maxIndex', 'z') 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('Av', x=self.x / self.L, z=0, f=0).reshape(len(self.x), 1) self.Av0x = self.input.d('Av', x=self.x / self.L, z=0, f=0, dim='x').reshape(len(self.x), 1) self.sf = self.input.v('Roughness', x=self.x / self.L, z=0, f=0).reshape(len(self.x), 1) self.sfx = self.input.d('Roughness', x=self.x / self.L, z=0, f=0, dim='x').reshape(len(self.x), 1) self.r = np.sqrt(2. * 1j * self.OMEGA / self.Av0).reshape( len(self.x), 1) self.H = self.input.v('H', x=self.x / self.L).reshape(len( self.x), 1) + self.input.v('R', x=self.x / self.L).reshape( len(self.x), 1) # YMD added reference level 15-08-17 self.alpha = (self.sf / (self.r * self.Av0 * np.sinh(self.r * self.H) + self.sf * np.cosh(self.r * self.H))).reshape( len(self.x), 1) self.B = self.input.v('B', x=self.x / self.L).reshape(len(self.x), 1) self.Bx = self.input.d('B', x=self.x / self.L, dim='x').reshape(len(self.x), 1).reshape(len(self.x), 1) self.u0 = self.input.v('zeta0', 'tide', range(0, len(self.x)), 0, 1) self.u0x = self.input.d('u0', 'tide', range(0, len(self.x)), 0, 1, dim='x') self.u0z = self.input.d('u0', 'tide', range(0, len(self.x)), 0, 1, dim='z') self.u0zz = self.input.d('u0', 'tide', range(0, len(self.x)), 0, 1, dim='zz') self.M = ((self.alpha * np.sinh(self.r * self.H) / self.r) - self.H) * (self.G / (2 * 1j * self.OMEGA)) * self.B self.bca = ny.amp_phase_input(self.input.v('A1'), self.input.v('phase1'), (3, ))[2] self.__bc = np.zeros(4) self.__F = [] # compute and save results d = dict() d['zeta1'] = {} d['u1'] = {} for mod in self.submodule: # Compute results zeta, u = getattr(self, mod)() # save in dictionary nfz = NumericalFunctionWrapper(zeta[0], self.input.slice('grid')) nfz.addDerivative(zeta[1], dim='x') nfu = NumericalFunctionWrapper(u[0], self.input.slice('grid')) d['zeta1'][mod] = nfz.function d['u1'][mod] = nfu.function self.input.merge(d) return d
def availability(self, F, T, G, alpha1, alpha2): """Calculates the solution to the bed-evolution equation: the erodibility and availability of sediment Parameters: F - diffusive coefficient in the availability equation that goes with a_x T - coefficient (advective, diffusive and stokes) in the availability equation that goes with a Returns: a - availability of sediment f - erodibility of sediment """ ################################################################################################################ ## Init ################################################################################################################ jmax = self.input.v('grid', 'maxIndex', 'x') B = self.input.v('B', range(0, jmax + 1), [0], [0]) x = ny.dimensionalAxis(self.input, 'x')[:, 0, 0] dx = x[1:] - x[:-1] ################################################################################################################ ## Solution to bed-evolution equation ################################################################################################################ ## analytical solution if np.all(G == 0): P = np.zeros(jmax + 1) else: P = integrate.cumtrapz( G / (F - 10**-6) * np.exp(integrate.cumtrapz(T / F, dx=dx, axis=0, initial=0)), dx=dx, axis=0, initial=0) exponent = np.exp(-integrate.cumtrapz(T / F, dx=dx, axis=0, initial=0)) # Boundary conditions (analytical solution) # BC 1: total amount of sediment in the system if self.input.v('sedbc') == 'astar': astar = self.input.v('astar') k = (astar * np.trapz(B, dx=dx, axis=0) / np.trapz(B * exponent, dx=dx, axis=0)) # BC 2: concentration at the seaward boundary elif self.input.v('sedbc') == 'csea': csea = self.input.v('csea') c000 = alpha1[0] k = csea / c000 * (self.input.v('grid', 'low', 'z', 0) - self.input.v('grid', 'high', 'z', 0)) # BC 3: incorrect boundary description else: from src.util.diagnostics.KnownError import KnownError raise KnownError( 'incorrect seaward boundary type (sedbc) for sediment module') # final solution (analytical) f0uncap = (k - P) * exponent ## Check if f<1 everywhere, # if not compute numerical solution instead with a time-stepping routine that maximises f at 1. if all(f0uncap < 1): f0 = f0uncap else: f0, Smod = self.availability_numerical(np.real(T), np.real(F), np.real(f0uncap), k, alpha1, alpha2, G) ## compute derivative if np.all(G == 0) and all(f0uncap < 1): f0x = -T / F * f0uncap # only use analytical derivative in case with no fluvial source of sediment and f<1; else not reliable. else: f0x = ny.derivative(f0, 'x', self.input.slice('grid')) return f0uncap, f0, f0x
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 + 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
def run(self): st.configure() data = self.input.getKeysOf('experimentdata') var1 = 'ws0' var2 = 'Q1' v2 = [] v1 = [] for dat in data: dc = self.input.v('experimentdata', dat) v1.append(dc.v(var1)) v2.append(dc.v(var2)) v1 = list(set(v1)) v2 = list(set(v2)) v1.sort() v2.sort() x = dc.v('grid', 'axis', 'x') xdim = ny.dimensionalAxis(dc.slice('grid'), 'x')[:, 0, 0] ETMloc = np.nan * np.ones((len(v1), len(v2))) maxc = np.nan * np.ones((len(v1), len(v2))) for q, dat in enumerate(data): print q dc = self.input.v('experimentdata', dat) i = v1.index(dc.v(var1)) j = v2.index(dc.v(var2)) c = dc.v('c', x=x, z=1, f=0) if c is None: c = dc.v('c0', x=x, z=1, f=0) + dc.v('c2', x=x, z=1, f=0) maxc[i, j] = np.max(c) try: # loc = ny.toList(self.findETM(xdim, T, Tx)) loc = ny.toList(self.findETM(xdim, c)) ETMloc[i, j] = np.asarray(loc) except: print 'no etm' plt.figure(1, figsize=(1, 1)) log1 = 'True' log2 = 'False' if log1 == 'True': v1 = np.log10(np.asarray(v1)) if log2 == 'True': v2 = np.log10(np.asarray(v2)) x_up_round = np.ceil(max(xdim) / 10000.) * 10. ETMloc[np.where(ETMloc >= x_up_round * 1000.)] = x_up_round * 1000. levels = np.linspace(0., x_up_round, x_up_round / 2 + 1) plt.contourf(np.asarray(v1), np.asarray(v2), ETMloc.T / 1000., levels=levels) plt.title('ETM location (km)') if log1 == 'True': xmin = np.min(np.asarray(v1)) xmax = np.max(np.asarray(v1)) xtick = np.arange(np.ceil(xmin), np.floor(xmax) + 1) plt.xticks(xtick, [10.**i for i in xtick]) plt.xlabel('$\log_{10} w_s$ (m/s)') plt.ylabel('Q $(m^3/s)$') plt.colorbar() # ## Fig 2 # plt.figure(2, figsize=(1,1)) # plt.contourf(np.asarray(v1), np.asarray(v2), maxc.T/1000., 40) # plt.title('Maximum near-bed\nconcentration (g/l)') # if log1 == 'True': # xmin = np.min(np.asarray(v1)) # xmax = np.max(np.asarray(v1)) # xtick = np.arange(np.ceil(xmin),np.floor(xmax)+1) # plt.xticks(xtick, [10.**i for i in xtick]) # plt.xlabel('$\log_{10} w_s$ (m/s)') # # plt.ylabel('Q $(m^3/s)$') # plt.colorbar() st.show() d = {} return d
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.timer.tic() self.logger.info('Running module Sediment Capacity') ################################################################################################################ ## 1. Initiate variables ################################################################################################################ self.SIGMA = self.input.v('OMEGA') self.RHOS = self.input.v('RHOS') self.RHO0 = self.input.v('RHO0') self.DS = self.input.v('DS') self.GPRIME = self.input.v('G') * ( self.RHOS - self.input.v('RHO0')) / self.input.v('RHO0') # self.L = self.input.v('L') self.x = self.input.v('grid', 'axis', 'x') * self.input.v('L') jmax = self.input.v('grid', 'maxIndex', 'x') kmax = self.input.v('grid', 'maxIndex', 'z') 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.WS = self.input.v('ws0', range(0, jmax + 1), [0], 0) self.WSx = self.input.d('ws0', range(0, jmax + 1), [0], 0, dim='x') self.Kv0 = self.input.v('Kv', range(0, jmax + 1), 0, 0).reshape(jmax + 1, 1) self.Kv0x = self.input.d('Kv', range(0, jmax + 1), 0, 0, dim='x').reshape(jmax + 1, 1) self.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)) self.Hx = self.input.d('H', range(0, jmax + 1), dim='x').reshape( (jmax + 1, 1)) if self.input.v('friction') is not None: self.sf = self.input.v(self.input.v('friction'), range(0, jmax + 1), 0, 0).reshape(jmax + 1, 1) self.sfx = self.input.d(self.input.v('friction'), range(0, jmax + 1), 0, 0, dim='x').reshape(jmax + 1, 1) else: 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) self.finf = self.input.v('finf') self.finfx = self.input.d('finf', dim='x') # Initiate dictionary to save results d = {} ################################################################################################################ ## 2. Calculate leading, first and second order concentration amplitudes hatc0, hatc1 and hatc2 ################################################################################################################ # Initiate variables 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() # self.timer.toc() # self.timer.disp('time sediment capacity') # self.timer.reset() return d