コード例 #1
0
 def _build_process_type_list(self):
     '''Generate lists of processes organized by process type
     Currently, this can be 'diagnostic', 'explicit', 'implicit', or 'adjustment'.'''
     self.process_types = {'diagnostic': [], 'explicit': [], 'implicit': [], 'adjustment': []}
     for name, proc, level in walk_processes(self, topdown=self.topdown):
         self.process_types[proc.time_type].append(proc)
     self.has_process_type_list = True
コード例 #2
0
 def step_forward(self):
     '''new oop climlab... just loop through processes
     and add up the tendencies'''
     if not self.has_process_type_list:
         self._build_process_type_list()
     # First compute all strictly diagnostic processes
     for proc in self.process_types['diagnostic']:
         proc.compute()
     # Compute tendencies and diagnostics for all explicit processes
     for proc in self.process_types['explicit']:
         proc.compute()
     # Update state variables using all explicit tendencies
     #  Tendencies are d/dt(state) -- so just multiply by timestep for forward time
     for proc in self.process_types['explicit']:
         for varname in proc.state.keys():
             try: proc.state[varname] += (proc.tendencies[varname] *
                                          self.param['timestep'])
             except: pass
     # Now compute all implicit processes -- matrix inversions
     for proc in self.process_types['implicit']:
         proc.compute()
         for varname in proc.state.keys():
             try: proc.state[varname] += proc.adjustment[varname]
             except: pass
     # Adjustment processes change the state instantaneously
     for proc in self.process_types['adjustment']:
         proc.compute()
         for varname, value in proc.state.iteritems():
             #proc.set_state(varname, proc.adjusted_state[varname])
             try: proc.state[varname] += proc.adjustment[varname]
             except: pass
     # Gather all diagnostics
     for name, proc, level in walk_processes(self):
         self.diagnostics.update(proc.diagnostics)
         proc._update_time()
コード例 #3
0
    def _build_process_type_list(self):
        """Generates lists of processes organized by process type.

        Following object attributes are generated or updated:

        :ivar dict process_types:   a dictionary with entries:
                                    ``'diagnostic'``, ``'explicit'``,
                                    ``'implicit'`` and ``'adjustment'`` which
                                    point to a list of processes according to
                                    the process types.

        The ``process_types`` dictionary is created while walking
        through the processes with :func:`~climlab.utils.walk.walk_processes`

        """
        self.process_types = {
            'diagnostic': [],
            'explicit': [],
            'implicit': [],
            'adjustment': []
        }
        for name, proc, level in walk.walk_processes(self,
                                                     topdown=self.topdown):
            self.process_types[proc.time_type].append(proc)
        self.has_process_type_list = True
コード例 #4
0
 def step_forward(self):
     '''new oop climlab... just loop through processes
     and add up the tendencies'''
     if not self.has_process_type_list:
         self._build_process_type_list()
     # First compute all strictly diagnostic processes
     for proc in self.process_types['diagnostic']:
         proc.compute()
     # Compute tendencies and diagnostics for all explicit processes
     for proc in self.process_types['explicit']:
         proc.compute()
     # Update state variables using all explicit tendencies
     #  Tendencies are d/dt(state) -- so just multiply by timestep for forward time
     for proc in self.process_types['explicit']:
         for varname in proc.state.keys():
             try: proc.state[varname] += (proc.tendencies[varname] *
                                          self.param['timestep'])
             except: pass
     # Now compute all implicit processes -- matrix inversions
     for proc in self.process_types['implicit']:
         proc.compute()
         for varname in proc.state.keys():
             try: proc.state[varname] += proc.adjustment[varname]
             except: pass
     # Adjustment processes change the state instantaneously
     for proc in self.process_types['adjustment']:
         proc.compute()
         for varname, value in proc.state.iteritems():
             #proc.set_state(varname, proc.adjusted_state[varname])
             try: proc.state[varname] += proc.adjustment[varname]
             except: pass
     # Gather all diagnostics
     for name, proc, level in walk_processes(self):
         self.diagnostics.update(proc.diagnostics)
         proc._update_time()
コード例 #5
0
 def _build_process_type_list(self):
     '''Generate lists of processes organized by process type
     Currently, this can be 'diagnostic', 'explicit', 'implicit', or 'adjustment'.'''
     self.process_types = {'diagnostic': [], 'explicit': [], 'implicit': [], 'adjustment': []}        
     for name, proc, level in walk_processes(self, topdown=self.topdown):
         self.process_types[proc.time_type].append(proc)
     self.has_process_type_list = True
コード例 #6
0
    def step_forward(self):
        '''Call the compute() method to get current tendencies, then
        apply them to update state variables.'''
        self.compute()
        #  Total tendency is applied as an explicit forward timestep
        # (already accounting properly for order of operations in compute() )
        for name, var in self.state.iteritems():
            var += self.tendencies[name] * self.param['timestep']

        # Update all time counters for this and all subprocesses in the tree
        for name, proc, level in walk_processes(self):
            proc._update_time()
コード例 #7
0
    def step_forward(self):
        '''Call the compute() method to get current tendencies, then
        apply them to update state variables.'''
        self.compute()
        #  Total tendency is applied as an explicit forward timestep
        # (already accounting properly for order of operations in compute() )
        for name, var in self.state.iteritems():
            var += self.tendencies[name] * self.param['timestep']

        # Update all time counters for this and all subprocesses in the tree
        for name, proc, level in walk_processes(self):
            proc._update_time()
コード例 #8
0
    def compute_diagnostics(self, num_iter=3):
        """Compute all tendencies and diagnostics, but don't update model state.
        By default it will call compute() 3 times to make sure all
        subprocess coupling is accounted for. The number of iterations can
        be changed with the input argument.

        """
        for n in range(num_iter):
            self.compute()
        #  Pass diagnostics up the process tree
        for name, proc, level in walk_processes(self, ignoreFlag=True):
            for diagname, value in proc.diagnostics.items():
                self.__setattr__(diagname, value)
コード例 #9
0
    def compute_diagnostics(self, num_iter=3):
        """Compute all tendencies and diagnostics, but don't update model state.
        By default it will call compute() 3 times to make sure all
        subprocess coupling is accounted for. The number of iterations can
        be changed with the input argument.

        """
        for n in range(num_iter):
            self.compute()
        #  Pass diagnostics up the process tree
        for name, proc, level in walk_processes(self, ignoreFlag=True):
            for diagname, value in proc.diagnostics.iteritems():
                self.__setattr__(diagname, value)
コード例 #10
0
    def _build_process_type_list(self):
        """Generates lists of processes organized by process type.

        Following object attributes are generated or updated:

        :ivar dict process_types:   a dictionary with entries:
                                    ``'diagnostic'``, ``'explicit'``,
                                    ``'implicit'`` and ``'adjustment'`` which
                                    point to a list of processes according to
                                    the process types.

        The ``process_types`` dictionary is created while walking
        through the processes with :func:`~climlab.utils.walk.walk_processes`

        """
        self.process_types = {'diagnostic': [], 'explicit': [], 'implicit': [], 'adjustment': []}
        for name, proc, level in walk_processes(self, topdown=self.topdown):
            self.process_types[proc.time_type].append(proc)
        self.has_process_type_list = True
コード例 #11
0
    def step_forward(self):
        """Updates state variables with computed tendencies.

        Calls the :func:`compute` method to get current tendencies for all
        process states. Multiplied with the timestep and added up to the state
        variables is updating all model states.

        :Example:

            ::

                >>> import climlab
                >>> model = climlab.EBM()

                >>> # checking time step counter
                >>> model.time['steps']
                0

                >>> # stepping the model forward
                >>> model.step_forward()

                >>> # step counter increased
                >>> model.time['steps']
                1

        """
        self.compute()
        #  Total tendency is applied as an explicit forward timestep
        # (already accounting properly for order of operations in compute() )
        for name, var in self.state.items():
            var += self.tendencies[name] * self.timestep

        # Update all time counters for this and all subprocesses in the tree
        #  Also pass diagnostics up the process tree
        for name, proc, level in walk.walk_processes(self, ignoreFlag=True):
            if proc.time['active_now']:
                proc._update_time()
                for diagname, value in proc.diagnostics.items():
                    self.__setattr__(diagname, value)
コード例 #12
0
    def step_forward(self):
        """Updates state variables with computed tendencies.

        Calls the :func:`compute` method to get current tendencies for all
        process states. Multiplied with the timestep and added up to the state
        variables is updating all model states.

        :Example:

            ::

                >>> import climlab
                >>> model = climlab.EBM()

                >>> # checking time step counter
                >>> model.time['steps']
                0

                >>> # stepping the model forward
                >>> model.step_forward()

                >>> # step counter increased
                >>> model.time['steps']
                1

        """
        self.compute()
        #  Total tendency is applied as an explicit forward timestep
        # (already accounting properly for order of operations in compute() )
        for name, var in self.state.iteritems():
            var += self.tendencies[name] * self.timestep

        # Update all time counters for this and all subprocesses in the tree
        #  Also pass diagnostics up the process tree
        for name, proc, level in walk_processes(self, ignoreFlag=True):
            proc._update_time()
            for diagname, value in proc.diagnostics.iteritems():
                self.__setattr__(diagname, value)
コード例 #13
0
    def compute(self):
        """Computes the tendencies for all state variables given current state
        and specified input.

        The function first computes all diagnostic processes. They don't produce
        any tendencies directly but they may affect the other processes (such as
        change in solar distribution). Subsequently, all tendencies and
        diagnostics for all explicit processes are computed.

        Tendencies due to implicit and adjustment processes need to be
        calculated from a state that is already adjusted after explicit
        alteration. For that reason the explicit tendencies are applied to the
        states temporarily. Now all tendencies from implicit processes are
        calculated by matrix inversions and similar to the explicit tendencies,
        the implicit ones are applied to the states temporarily. Subsequently,
        all instantaneous adjustments are computed.

        Then the changes that were made to the states from explicit and implicit
        processes are removed again as this
        :class:`~climlab.process.time_dependent_process.TimeDependentProcess.compute()`
        function is supposed to calculate only tendencies and not apply them
        to the states.

        Finally, all calculated tendencies from all processes are collected
        for each state, summed up and stored in the dictionary
        ``self.tendencies``, which is an attribute of the time-dependent-process
        object, for which the
        :class:`~climlab.process.time_dependent_process.TimeDependentProcess.compute()`
        method has been called.


        **Object attributes** \n

        During method execution following object attributes are modified:

        :ivar dict tendencies:  dictionary that holds tendencies for all states
                                is calculated for current timestep through
                                adding up tendencies from explicit, implicit and
                                adjustment processes.
        :ivar dict diagnostics: process diagnostic dictionary is updated
                                by diagnostic dictionaries of subprocesses
                                after computation of tendencies.

        """
        if not self.has_process_type_list:
            self._build_process_type_list()
        # First compute all strictly diagnostic processes
        ignored = self._compute_type('diagnostic')
        # Compute tendencies and diagnostics for all explicit processes
        tendencies_explicit = self._compute_type('explicit')
        #  Tendencies due to implicit and adjustment processes need to be
        #  calculated from a state that is already adjusted after explicit stuff
        #  So apply the tendencies temporarily and then remove them again
        for name, var in self.state.items():
            var += tendencies_explicit[name] * self.timestep
        # Now compute all implicit processes -- matrix inversions
        tendencies_implicit = self._compute_type('implicit')
        for name, var in self.state.items():
            var += tendencies_implicit[name] * self.timestep
        # Finally compute all instantaneous adjustments
        adjustments = self._compute_type('adjustment')
        #  The adjustment is actually ignored here because it is stored
        #  in proc.tendencies and applied later as if it were an explicit forward step
        #  Now remove the changes from the model state
        for name, var in self.state.items():
            var -= ((tendencies_implicit[name] + tendencies_explicit[name]) *
                    self.timestep)
        #  Walk the subprocess tree and sum up all tendencies from subprocesses
        #   By walking with topdown=False we ensure that we don't miss anything
        for (name, proc, level) in walk_processes(self, topdown=False):
            for subname, subproc in proc.subprocess.items():
                for varname in subproc.tendencies:
                    proc.tendencies[varname] += subproc.tendencies[varname]