Пример #1
0
class Fluid2d(object):
    def __init__(self, param, grid):

        # let's first check that no param is obviously incorrect
        param.checkall()

        # copy the launch script into 'expname.py' to allow
        # for experiment reproducibility
        launchscript = sys.argv[0]
        param.datadir = param.datadir.replace('~', os.getenv("HOME"))
        param.expdir = '%s/%s' % (param.datadir, param.expname)
        if param.myrank == 0:
            if os.path.isdir(param.expdir):
                pass
            else:
                os.makedirs(param.expdir)
            savedscript = '%s/%s.py' % (param.expdir, param.expname)
            outfile = '%s/output.txt' % param.expdir
            if os.path.exists(outfile):
                print(
                    'Warning: this experiment has already been ran, output.txt already exists'
                )
                print('dummy.txt will be used instead')
                outfile = '%s/dummy.txt' % param.expdir

            sys.stdout = Logger(outfile)

            if os.path.exists(savedscript):
                print('Warning: the python script already exists in %s' %
                      param.expdir)
                print('the script won' 't be copied')
                pass
            else:
                self.savedscript = savedscript
                call(['cp', launchscript, savedscript])

        self.list_param = [
            'modelname', 'tend', 'adaptable_dt', 'dt', 'cfl', 'dtmax',
            'myrank', 'nprint', 'exacthistime', 'rescaledtime', 'noslip',
            'geometry', 'diag_fluxes', 'print_param', 'enforce_momentum',
            'forcing', 'decay', 'plotting_module', 'freq_save', 'freq_plot',
            'plot_interactive', 'nbproc', 'isisland', 'npx', 'npy', 'nx', 'ny'
        ]

        param.copy(self, self.list_param)

        self.dt0 = self.dt

        grid.finalize_msk()
        # print('momentum=',self.enforce_momentum)
        self.list_grid = ['dx', 'dy', 'nh', 'msk', 'xr0', 'yr0', 'x2', 'y2']
        grid.copy(self, self.list_grid)

        if param.modelname == 'euler':
            if self.geometry not in ['closed', 'disc']:
                self.enforce_momentum = False
            from euler import Euler
            self.model = Euler(param, grid)
        else:
            # not yet implemented in other models
            self.enforce_momentum = False

        if param.modelname == 'advection':
            from advection import Advection
            self.model = Advection(param, grid)

        if param.modelname == 'boussinesq':
            from boussinesq import Boussinesq
            self.model = Boussinesq(param, grid)

        if param.modelname == 'boussinesqTS':
            from boussinesqTS import BoussinesqTS
            self.model = BoussinesqTS(param, grid)

        if param.modelname == 'quasigeostrophic':
            from quasigeostrophic import QG
            self.model = QG(param, grid)

        if param.modelname == 'thermalwind':
            from thermalwind import Thermalwind
            self.model = Thermalwind(param, grid)

        if self.modelname == 'quasigeostrophic':
            self.enstrophyname = 'pv2'
        else:
            self.enstrophyname = 'enstrophy'

        if self.isisland:
            grid.island.finalize(self.model.ope.mskp)
            self.model.ope.rhsp = grid.island.rhsp
            self.model.ope.psi = grid.island.psi
            # self.diag = Diag(param,grid)

        if self.diag_fluxes:
            self.flx = Flx.Fluxes(param, grid, self.model.ope)
            flxlist = self.flx.fullflx_list
        else:
            flxlist = None

        if self.plot_interactive:
            try:
                p = import_module(self.plotting_module)
                # print(self.plotting_module)
            except ImportError:
                print('problem with the interactive plotting')
                print('this might be due to a backend issue')
                print('try to rerun the code with')
                print('param.plot_interactive = False')
                exit(0)

            self.plotting = p.Plotting(param, grid, self.model.var,
                                       self.model.diags)

        self.tracer_list = param.tracer_list
        # here's a shortcut to the model state
        self.state = self.model.var.state

        self.t = 0.
        self.kt = 0

        self.output = Output(param, grid, self.model.diags, flxlist=flxlist)
        self.print_config(param, start=True)

    def print_config(self, param, start=True):
        outputfiles = [self.output.hisfile, self.output.diagfile]
        if self.diag_fluxes:
            outputfiles += [self.output.flxfile]
        if self.plot_interactive:
            if hasattr(self.plotting, 'mp4file'):
                outputfiles += [self.plotting.mp4file]

        if hasattr(self, 'savedscript'):
            outputfiles += [self.savedscript]

        if self.myrank == 0:
            if start:
                print('-' * 50)
                print(' Fluid2d summary:')
                print('-' * 50)
                print('  - model equations: %s' % self.modelname)
                print('  - grid size: %i x %i' % (self.nx, self.ny))
                print('  - integration time: %.2f' % self.tend)
                print('  - advection schemes applied to:')
                for trac in self.tracer_list:
                    print('    - %s' % trac)
            else:
                print(' Output files:')
                print('-' * 50)
                for f in outputfiles:
                    print('  - %s' % f)
                print('-' * 50)
                print(
                    ' You may recover all the experiment parameters by doing')
                print(' ncdump -h %s' % self.output.hisfile)
                print('')
                print(' or browse the history file by doing')
                print(' ncview %s' % self.output.hisfile)
                print('-' * 50)

        if self.print_param and (self.myrank == 0) and start:
            print('-' * 50)
            print(' Extended list of all parameters')
            print('-' * 50)
            param.printvalues()

    def loop(self, joinhis=True, keepplotalive=False):
        """Fluid2d time loop"""
        if self.myrank == 0:
            print('-' * 50)
            print(' Starting the time loop')
            if self.decay and (self.modelname == 'euler'):
                print('   in this simulation the kinetic energy is expected')
                print('   to be decreasing, the code will issue a warning msg')
                print('   during the integration if ke increases')
            print('-' * 50)

        self.model.diagnostics(self.model.var, self.t)
        self.model.diags['dkedt'] = 0.
        self.model.diags['dvdt'] = 0.
        data = {'his': self.model.var.state, 'diag': self.model.diags}
        if self.diag_fluxes:
            data['flx'] = self.flx.flx
            # it is important to set dt (in the case of 'adaptable_dt')
            # because otherwise this first diagnostic can go crazy
            # and for an unknown reason this can spoil the whole file
            self.set_dt(self.kt)
            self.flx.diag_fluxes(self.model.var.state, self.t, self.dt)

        self.output.do(data, self.t, self.kt)

        if self.plot_interactive:
            if hasattr(self.plotting, 'fig'):
                pass
            else:
                self.plotting.create_fig(self.t)

        nh = self.nh
        self.z2d = self.model.var.state[0][nh:-nh, nh:-nh]

        def signal_handler(signal, frame):
            if self.myrank == 0:
                print('\n hit ctrl-C, stopping', end='')
            self.stop = True

        signal.signal(signal.SIGINT, signal_handler)

        self.stop = False

        kt0 = 0
        t0 = clock()
        reduce = 0
        while (self.t < self.tend and not (self.stop)):

            self.set_dt(self.kt)

            # reduce the time step to arrive right at the desired
            # next history time when param.exacthistime == True (default)
            # this occurs when param.adaptable_dt == True
            #
            # to avoid having suddenly a very small time step, which breaks
            # the smoothness of the time integration, the time step is
            # adjusted 8 time steps ahead of time.
            if self.exacthistime and self.adaptable_dt:
                if (self.t + 8 * self.dt > self.output.tnexthis) and (reduce
                                                                      == 0):
                    reduce = 8
                if (reduce > 0):
                    self.dt = (self.output.tnexthis - self.t) / (reduce * 0.95)
                    reduce -= 1
                if (self.t + self.dt > self.output.tnexthis):
                    dt = self.dt
                    reduce = 0
                    self.dt = self.output.tnexthis - self.t

            self.model.step(self.t, self.dt)

            if self.rescaledtime == 'enstrophy':
                self.t += self.dt * np.sqrt(self.model.diags['enstrophy'])

            else:
                self.t += self.dt

            self.kt += 1
            ke_old = self.model.diags['ke']
            ens_old = self.model.diags[self.enstrophyname]
            self.model.diagnostics(self.model.var, self.t)

            if self.enforce_momentum:
                self.enforce_zero_momentum()
                self.model.diagnostics(self.model.var, self.t)

            ke = self.model.diags['ke']
            ens = self.model.diags[self.enstrophyname]
            dkedt = (ke - ke_old) / self.dt
            dvdt = (ens - ens_old) / self.dt
            self.model.diags['dkedt'] = dkedt
            self.model.diags['dvdt'] = dvdt

            if ((ke > ke_old) and (self.myrank == 0) and (self.decay)
                    and (self.modelname == 'euler')):
                dke = (ke - ke_old) / ke

                warning = '\033[0;32;40m' + 'WARNING dlog(ke)'
                white = '\033[0m'
                print('\rkt=%-4i %s = %.2g%s' % (self.kt, warning, dke, white),
                      end='')

            if self.diag_fluxes and (self.t >= self.output.tnexthis):
                # this is a costly diagnostic, do it only before writing it
                self.flx.diag_fluxes(self.model.var.state, self.t, self.dt)

            self.output.do(data, self.t, self.kt)

            if self.dt == self.dtmax:
                flag = '*'
            else:
                flag = ''

            if (self.myrank == 0) and (self.kt % self.nprint == 0)\
               or (self.t >= self.tend):
                print('\rkt=%-4i / t=%-7.3f %s / dt=%-7.3f ' %
                      (self.kt, self.t, flag, self.dt),
                      end='')

            if (self.kt % self.freq_plot == 0) and self.plot_interactive:
                self.plotting.update_fig(self.t, self.dt, self.kt)

            # check for blow-up
            if self.model.diags['maxspeed'] > 1e3:
                self.stop = True
                if self.myrank == 0:
                    print()
                    print('max|u| > 1000, blow-up detected, stopping')

        if self.myrank == 0:
            print('\ndone')

        if self.plot_interactive and not (keepplotalive):
            self.plotting.finalize()

        if hasattr(self.model, 'timers'):
            if (self.myrank == 0):
                print('-' * 50)
                print(' A few model performances metrics')
                print('-' * 50)
                self.model.timers._print()

            if self.myrank == 0:
                dt = clock() - t0
                nkt = (self.kt - kt0)
                gamma = dt * self.npx * self.npy / (nkt * self.nx * self.ny)
                print()
                print('  - Wall  time      : %f s' % dt)
                print('  - Nb of iterations: %i' % nkt)
                print('  - Time per ite    : %5.3f s' % (dt / nkt))
                print('  - Rescaled time   : %5.3e s (per ite, per dof)' %
                      gamma)
                print('-' * 50)

        if (self.myrank == 0) and (joinhis):
            self.output.dump_diag()

            if self.nbproc <= 64:
                self.output.join()

            else:
                print('too many cores will be idle ' +
                      'join the history files manually')
        self.print_config(None, start=False)

    def enforce_zero_momentum(self):
        if self.enforce_momentum:
            vor = self.model.var.get('vorticity')
            px = self.model.diags['px'] / self.x2
            py = self.model.diags['py'] / self.y2
            vor[:] -= (self.xr0 * px + self.yr0 * py)
            x = self.model.var.state
            self.model.ope.invert_vorticity(x, flag='fast')

    def relaunch(self, duration=0):
        t, dt, kt, tnextdiag, tnexthis = self.restart.read(self.model.var)
        self.t = t
        self.dt = dt
        self.kt = kt
        self.output.tnextdiag = tnextdiag
        self.output.tnexthis = tnexthis

        self.tend += duration

        print('t = %f / kt = %i / nextdiag = %f / nexthist =%f' %
              (t, kt, tnextdiag, tnexthis))

        self.model.set_psi_from_vorticity()
        self.loop()

    def set_dt(self, kt):

        if ((self.adaptable_dt) & (self.model.diags['maxspeed'] != 0)):
            dt = self.cfl * min(self.dx, self.dy) / \
                self.model.diags['maxspeed']
            # filter in time, change the filter_coef
            if dt > 0.8 * self.dt:
                self.filter_coef = 0.05
            else:
                # time step decreases too fast
                # don't filter, otherwise the model blows up
                self.filter_coef = 1.
            self.dt = (1. - self.filter_coef) * self.dt + self.filter_coef * dt
            if self.dt > self.dtmax:
                self.dt = self.dtmax

        else:
            self.dt = self.dt0

        # transfer this information to the advection scheme
        self.model.ope.cst[3] = self.model.diags['maxspeed']
Пример #2
0
class Fluid2d(Param):
    def __init__(self, param, grid):

        self.list_param = [
            'modelname', 'tend', 'fixed_dt', 'dt', 'cfl', 'plot_var', 'cax',
            'colorscheme', 'plot_interactive', 'fixed_dt', 'dtmax',
            'freq_save', 'freq_plot'
        ]

        param.copy(self, self.list_param)

        self.list_grid = ['dx', 'nh', 'msk']
        grid.copy(self, self.list_grid)

        if param.modelname == 'euler':
            from euler import Euler
            self.model = Euler(param, grid)

        if param.modelname == 'advection':
            from advection import Advection
            self.model = Advection(param, grid)

        if param.modelname == 'boussinesq':
            from boussinesq import Boussinesq
            self.model = Boussinesq(param, grid)

        if param.modelname == 'quasigeostrophic':
            from quasigeostrophic import QG
            self.model = QG(param, grid)

        self.diag = Diag(param, grid)
        self.plotting = Plotting(param)

        # here's a shortcut to the model state
        self.state = self.model.var.state

        self.t = 0.
        self.kt = 0

        self.output = Output(param, grid, self.diag)

    def update_fig(self, *args):
        self.diag.integrals(self.model.var)
        #        print(self.diag.ke)
        self.set_dt()
        self.model.step(self.t, self.dt)
        self.kt += 1
        self.t = self.t + self.dt
        #        print(self.t,self.dt)
        if (self.kt % self.freq_plot) == 0:  #self.plot_freq)==0:
            self.z2d[self.plotting_msk == 0] = 0.
            #            self.cax=self.get_cax(self.z2d)
            self.set_cax(self.z2d)
            self.im.set_array(self.z2d)
            self.im.set_clim(vmin=self.cax[0], vmax=self.cax[1])

        #self.output.do(self.model.var.state,self.diag,self.t,self.kt)

        return self.im,

    def update_fig2(self, *args):
        self.diag.integrals(self.model.var)
        #        print(self.diag.ke)
        self.set_dt()
        self.model.step(self.t, self.dt)
        self.kt += 1
        self.t = self.t + self.dt
        #        print(self.t,self.dt)
        if (self.kt % self.freq_plot) == 0:  #self.plot_freq)==0:
            self.z2d[self.plotting_msk == 0] = 0.
            self.set_cax(self.z2d)
            self.im.set_array(self.z2d)
            self.im.set_clim(vmin=self.cax[0], vmax=self.cax[1])

        self.output.do(self.model.var.state, self.diag, self.t, self.kt)
        self.ti.label = '%f4.2' % self.t
        #print(self.ti.label)

        return self.im, self.ti,

    def loop(self):
        nh = self.nh
        self.plotting_msk = self.msk[nh:-nh, nh:-nh]
        self.z2d = self.model.var.get(self.plot_var)[nh:-nh, nh:-nh]

        import matplotlib.pyplot as plt
        import matplotlib.animation as animation
        if not (self.plot_interactive):

            fig = plt.figure()
            self.ti = plt.title('')
            self.ti.animated = True
            self.im = plt.imshow(self.z2d,
                                 vmin=self.cax[0],
                                 vmax=self.cax[1],
                                 cmap=plt.get_cmap('jet'),
                                 origin='lower',
                                 interpolation='nearest')

            plt.colorbar()
            ani = animation.FuncAnimation(fig,
                                          self.update_fig,
                                          interval=0.0000001,
                                          blit=True)
            plt.show()
            self.plotting.set_im(self.z2d,
                                 self.plotting_msk,
                                 self.cax,
                                 ani=True,
                                 update=self.update_fig)

        else:
            self.diag.integrals(self.model.var)
            time_str = 'time = %-6.2f'

            fig = plt.figure(figsize=(10, 8))
            ax1 = fig.add_subplot(1, 1, 1)
            ax1.cla()
            ax1.hold(True)

            ax1.set_title(time_str % self.t)
            ax1.set_xlabel('X')
            ax1.set_ylabel('Y')

            # ax2 = fig.add_subplot(1, 2, 2)
            # ax2.cla()
            # ax2.hold(True)
            # ax2.set_title( 'integral quantities')
            # ax2.set_xlabel('t')
            # ax2.set_ylabel('Ke')

            def on_press(event):
                print('stop')
                if self.ion:
                    plt.ioff()
                else:
                    plt.ion()
                plt.pause(1)

            self.ion = True

            #plt.ion()
            #plt.show()#False)
            im = ax1.imshow(self.z2d,
                            vmin=self.cax[0],
                            vmax=self.cax[1],
                            cmap=plt.get_cmap('jet'),
                            origin='lower',
                            interpolation='nearest')

            time = [0]

            z = self.diag.ke
            y = [z]

            #line1, = ax2.plot(time, y, '.-', alpha=0.8, color="gray", markerfacecolor="red")
            cb = plt.colorbar(im)

            fig.show()
            fig.canvas.draw()
            background1 = fig.canvas.copy_from_bbox(ax1.bbox)

            cid = fig.canvas.mpl_connect('button_press_event', on_press)
            fig.canvas.key_press_event = on_press

            #background2 = fig.canvas.copy_from_bbox(ax2.bbox)
            self.output.do(self.model.var.state, self.diag, self.t, self.kt)

            while (self.t < self.tend):
                self.diag.integrals(self.model.var)
                self.set_dt()
                self.model.step(self.t, self.dt)
                self.t += self.dt
                self.kt += 1
                self.output.do(self.model.var.state, self.diag, self.t,
                               self.kt)

                #print(self.t)
                if self.kt % self.freq_plot == 0:
                    time.append(self.t)
                    y.append(self.diag.ke)

                    if len(time) > 1000:
                        del time[0]
                        del y[0]

                    #line1.set_xdata(time)
                    #line1.set_ydata(y)

                    im.set_array(self.z2d)
                    ti = ax1.title
                    ax1.set_title(time_str % self.t)
                    self.set_cax(self.z2d)

                    im.set_clim(vmin=self.cax[0], vmax=self.cax[1])
                    if False:
                        fig.canvas.restore_region(
                            background1)  # restore background
                        ax1.draw_artist(im)  # redraw just the points
                        #ax1.draw_artist(ti)                   # redraw just the points
                        fig.canvas.blit(ax1.bbox)  # fill in the axes rectangle

                        ax2.axis([min(time), max(time), min(y), max(y)])
                        fig.canvas.restore_region(
                            background2)  # restore background
                        ax2.draw_artist(line1)
                        fig.canvas.blit(ax2.bbox)  # fill in the axes rectangle
                    else:
                        fig.canvas.draw()

    def set_dt(self):

        if ((self.fixed_dt == 0) & (self.diag.maxspeed != 0)):
            dt = self.cfl * self.dx / self.diag.maxspeed
            # filter in time
            self.filter_coef = 1.
            self.dt = (1. - self.filter_coef) * self.dt + self.filter_coef * dt
            if self.dt > self.dtmax:
                #                print('dt=%g'%self.dt)
                self.dt = self.dtmax
#            else:
#                print(self.dt)
        else:
            pass
        # transfer this information to the advection scheme
        self.model.ope.cst[2] = self.diag.maxspeed
#        print('dt=%g / cfl=%g'%(self.dt,self.cfl))

    def set_cax(self, z):
        if self.colorscheme == 'minmax':
            self.cax = [min(z.ravel()), max(z.ravel())]
        if self.colorscheme == 'symmetric':
            mm = max(abs(z.ravel()))
            self.cax = [-mm, +mm]
        if self.colorscheme == 'imposed':
            #self.cax is already defined
            pass
Пример #3
0
class Fluid2d(Param):
    def __init__(self, param, grid):

        self.list_param = [
            'modelname', 'tend', 'adaptable_dt', 'dt', 'cfl', 'dtmax',
            'myrank', 'nprint', 'rescaledtime', 'noslip', 'geometry',
            'enforce_momentum', 'forcing', 'plotting_module', 'freq_save',
            'freq_plot', 'plot_interactive', 'nbproc', 'isisland'
        ]

        param.copy(self, self.list_param)

        grid.finalize_msk()
        #print('momentum=',self.enforce_momentum)
        self.list_grid = ['dx', 'nh', 'msk', 'xr0', 'yr0', 'x2', 'y2']
        grid.copy(self, self.list_grid)

        if param.modelname == 'euler':
            if not (self.geometry in ['square', 'disc']):
                self.enforce_momentum = False
            from euler import Euler
            self.model = Euler(param, grid)
        else:
            # not yet implemented in other models
            self.enforce_momentum = False

        if param.modelname == 'advection':
            from advection import Advection
            self.model = Advection(param, grid)

        if param.modelname == 'boussinesq':
            from boussinesq import Boussinesq
            self.model = Boussinesq(param, grid)

        if param.modelname == 'quasigeostrophic':
            from quasigeostrophic import QG
            self.model = QG(param, grid)

        if self.isisland:
            grid.island.finalize(self.model.ope.mskp)
            self.model.ope.rhsp = grid.island.rhsp
            self.model.ope.psi = grid.island.psi
#        self.diag = Diag(param,grid)

        if self.plot_interactive:
            try:
                p = import_module(self.plotting_module)
            except:
                print('module %s for plotting cannot be found' %
                      self.plotting_module)
                print('make sure file **%s.py** exists' % self.plotting_module)
                exit(0)

            self.plotting = p.Plotting(param, grid, self.model.var,
                                       self.model.diags)

        # here's a shortcut to the model state
        self.state = self.model.var.state

        self.t = 0.
        self.kt = 0

        self.output = Output(param, grid, self.model.diags)

    def loop(self, joinhis=True):
        if self.myrank == 0:
            print('starting the time loop')

        self.model.diagnostics(self.model.var, self.t)
        self.model.diags['dkedt'] = 0.
        self.output.do(self.model.var.state, self.model.diags, self.t, self.kt)

        if self.plot_interactive:
            self.plotting.create_fig(self.t)

        nh = self.nh
        self.z2d = self.model.var.state[0][nh:-nh, nh:-nh]

        def signal_handler(signal, frame):
            if self.myrank == 0:
                print('\nstop requested', end='')
            self.stop = True

        signal.signal(signal.SIGINT, signal_handler)

        self.stop = False
        while (self.t < self.tend and not (self.stop)):

            self.set_dt()
            self.model.step(self.t, self.dt)
            if self.rescaledtime == 'enstrophy':
                self.t += self.dt * sqrt(self.model.diags['enstrophy'])
            else:
                self.t += self.dt
            self.kt += 1
            ke_old = self.model.diags['ke']
            self.model.diagnostics(self.model.var, self.t)

            self.enforce_zero_momentum()
            if self.enforce_momentum:
                self.model.diagnostics(self.model.var, self.t)

            ke = self.model.diags['ke']
            dkedt = -(ke - ke_old) / self.dt
            self.model.diags['dkedt'] = dkedt
            #            if(ke>ke_old) and self.myrank==0:
            #                print('kt = %i / ke is increasing dke/dt = %.2g'%(self.kt,-dkedt))

            self.output.do(self.model.var.state, self.model.diags, self.t,
                           self.kt)

            flag = ''
            if self.dt == self.dtmax:
                flag = '*'
            if (self.myrank == 0) and (self.kt % self.nprint == 0):
                print('\rkt = %-4i  /  t=%-7.3f %s' % (self.kt, self.t, flag),
                      end='')
            if (self.kt % self.freq_plot == 0) and self.plot_interactive:
                self.plotting.update_fig(self.t, self.dt, self.kt)
        if self.myrank == 0:
            print('\ndone')

        if self.plot_interactive:
            self.plotting.finalize()

        if (self.myrank == 0) and (joinhis):
            self.output.dump_diag()
            if self.nbproc <= 8:
                self.output.join()
            else:
                print(
                    'to many cores will be idle, join the history files manually'
                )

    def enforce_zero_momentum(self):
        if self.enforce_momentum:
            vor = self.model.var.get('vorticity')
            px = self.model.diags['px'] / self.x2
            py = self.model.diags['py'] / self.y2
            vor[:] -= (self.xr0 * px + self.yr0 * py)
            x = self.model.var.state
            self.model.ope.invert_vorticity(x, flag='fast')

    def relaunch(self, duration=0):
        t, dt, kt, tnextdiag, tnexthis = self.restart.read(self.model.var)
        self.t = t
        self.dt = dt
        self.kt = kt
        self.output.tnextdiag = tnextdiag
        self.output.tnexthis = tnexthis

        self.tend += duration

        print('t = %f / kt = %i / nextdiag = %f / nexthist =%f' %
              (t, kt, tnextdiag, tnexthis))

        self.model.set_psi_from_vorticity()
        self.loop()

    def set_dt(self):

        if ((self.adaptable_dt) & (self.model.diags['maxspeed'] != 0)):
            dt = self.cfl * self.dx / self.model.diags['maxspeed']
            # filter in time, change the filter_coef
            self.filter_coef = 1.
            self.dt = (1. - self.filter_coef) * self.dt + self.filter_coef * dt
            if self.dt > self.dtmax:
                self.dt = self.dtmax
        else:
            pass

        # transfer this information to the advection scheme
        self.model.ope.cst[2] = self.model.diags['maxspeed']