Source code for climlab.radiation.boltzmann

from __future__ import division
from climlab import constants as const
from climlab.process.energy_budget import EnergyBudget


[docs] class Boltzmann(EnergyBudget): r"""A class for black body radiation. Implements a radiation subprocess which computes longwave radiation with the Stefan-Boltzmann law for black/grey body radiation. According to the Stefan Boltzmann law the total power radiated from an object with surface area :math:`A` and temperature :math:`T` (in unit Kelvin) can be written as .. math:: P = A \varepsilon \sigma T^4 where :math:`\varepsilon` is the emissivity of the body. As the :class:`~climlab.process.energy_budget.EnergyBudget` of the Energy Balance Model is accounted in unit :math:`\textrm{energy} / \textrm{area}` (:math:`\textrm{W}/ \textrm{m}^2`) the energy budget equation looks like this: .. math:: C \frac{dT}{dt} = R\downarrow - R\uparrow - H \n The :class:`Boltzmann` radiation subprocess represents the outgoing radiation :math:`R\uparrow` which then can be written as .. math:: R\uparrow = \varepsilon \sigma T^4 with state variable :math:`T`. **Initialization parameters** \n An instance of ``Boltzmann`` is initialized with the following arguments: :param float eps: emissivity of the planet's surface which is the effectiveness in emitting energy as thermal radiation [default: 0.65] :param float tau: transmissivity of the planet's atmosphere which is the effectiveness in transmitting the longwave radiation emitted from the surface [default: 0.95] **Object attributes** \n During initialization both arguments described above are created as object attributes which calls their setter function (see below). :ivar float eps: calls the setter function of :func:`eps` :ivar float tau: calls the setter function of :func:`tau` :ivar dict diagnostics: the subprocess's diagnostic dictionary ``self.diagnostic`` is initialized through calling ``self.add_diagnostic('OLR', 0. * self.Ts)`` :ivar Field OLR: the subprocess attribute ``self.OLR`` is created with correct dimensions :Example: Replacing an the regular AplusBT subprocess in an energy balance model:: >>> import climlab >>> from climlab.radiation.Boltzmann import Boltzmann >>> # creating EBM model >>> model = climlab.EBM() >>> print model .. code-block:: none :emphasize-lines: 7 climlab Process of type <class 'climlab.model.ebm.EBM'>. State variables and domain shapes: Ts: (90, 1) The subprocess tree: top: <class 'climlab.model.ebm.EBM'> diffusion: <class 'climlab.dynamics.diffusion.MeridionalDiffusion'> LW: <class 'climlab.radiation.AplusBT.AplusBT'> albedo: <class 'climlab.surface.albedo.StepFunctionAlbedo'> iceline: <class 'climlab.surface.albedo.Iceline'> cold_albedo: <class 'climlab.surface.albedo.ConstantAlbedo'> warm_albedo: <class 'climlab.surface.albedo.P2Albedo'> insolation: <class 'climlab.radiation.insolation.P2Insolation'> :: >>> # creating and adding albedo feedback subprocess >>> LW_boltz = Boltzmann(eps=0.69, tau=0.98, state=model.state, **model.param) >>> # overwriting old 'LW' subprocess with same name >>> model.add_subprocess('LW', LW_boltz) >>> print model .. code-block:: none :emphasize-lines: 7 climlab Process of type <class 'climlab.model.ebm.EBM'>. State variables and domain shapes: Ts: (90, 1) The subprocess tree: top: <class 'climlab.model.ebm.EBM'> diffusion: <class 'climlab.dynamics.diffusion.MeridionalDiffusion'> LW: <class 'climlab.radiation.Boltzmann.Boltzmann'> albedo: <class 'climlab.surface.albedo.StepFunctionAlbedo'> iceline: <class 'climlab.surface.albedo.Iceline'> cold_albedo: <class 'climlab.surface.albedo.ConstantAlbedo'> warm_albedo: <class 'climlab.surface.albedo.P2Albedo'> insolation: <class 'climlab.radiation.insolation.P2Insolation'> """ # implemented by m-kreuzer def __init__(self, eps= 0.65, tau=0.95, **kwargs): super(Boltzmann, self).__init__(**kwargs) self.eps = eps self.tau = tau self.add_diagnostic('OLR', 0. * self.Ts) @property def eps(self): """Property of emissivity parameter. :getter: Returns the albedo value which is stored in attribute ``self._eps`` :setter: * sets the emissivity which is addressed as ``self._eps`` to the new value * updates the parameter dictionary ``self.param['eps']`` :type: float """ return self._eps @eps.setter def eps(self, value): self._eps = value self.param['eps'] = value @property def tau(self): """Property of the transmissivity parameter. :getter: Returns the albedo value which is stored in attribute ``self._tau`` :setter: * sets the emissivity which is addressed as ``self._tau`` to the new value * updates the parameter dictionary ``self.param['tau']`` :type: float """ return self._tau @tau.setter def tau(self, value): self._tau = value self.param['tau'] = value # def emission(self): # """Calculates the Outgoing Longwave Radiation (OLR) of the Boltzmann # radiation subprocess. # # **Object attributes** \n # # During method execution following object attribute is modified: # # :ivar float OLR: the described formula is calculated and the # result stored in the project attribute ``self.OLR`` # :ivar dict diagnostics: the same result is written in ``diagnostics`` # dictionary with the key ``'OLR'`` # # .. warning:: # # This currently works only for a single state variable! # # """ # for varname, value in self.state.iteritems(): # flux = self.eps * self.tau * const.sigma * (value + const.tempCtoK)**4. # self.OLR = flux # self.diagnostics['OLR'] = self.OLR def _compute_emission(self): for varname, value in self.state.items(): flux = self.eps * self.tau * const.sigma * (value + const.tempCtoK)**4. self.OLR[:] = flux def _compute_heating_rates(self): """Computes energy flux convergences to get heating rates in :math:`W/m^2`. """ self._compute_emission() for varname, value in self.state.items(): self.heating_rate[varname] = -self.OLR