def __init__( self, atmosphere, timestep='6h', max_duration='500d', outfile=None, experiment='RCE', writeevery='24h', delta=0.0, delta2=0.0, post_count=365, radiation=None, ozone=None, humidity=None, surface=None, cloud=None, convection=None, lapserate=None, upwelling=None, diurnal_cycle=False, co2_adjustment_timescale=np.nan, logevery=None, timestep_adjuster=None, ): """Set-up a radiative-convective model. Parameters: atmosphere: :py:class:`konrad.atmosphere.Atmosphere`. timestep (float, str or timedelta): Model time step * If float, time step in days. * If str, a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). * A `timedelta` object is directly used as timestep. max_duration (float, str or timedelta): Maximum duration. The duration is given in model time * If float, maximum duration in days. * If str, a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). * A `timedelta` object is directly used as timestep. outfile (str): netCDF4 file to store output. experiment (str): Experiment description (stored in netCDF output). writeevery (float, str or timedelta): Set output frequency. * float: Every nth day in model time * str: a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). * A `timedelta` object is directly used as timestep. * Note: Setting a value of `"0h"` will write after every iteration. delta (float): First stop criterion. If the change in top-of-the-atmosphere radiative balance is smaller than this threshold, skip further iterations. Values are given in W/m^2/day. delta2 (float): Second stop criterion. If the second-derivative of the top-of-the-atmosphere radiative balance is smaller than this threshold, skip further iterations. Values are given in W/m^2/day^2. post_count (float): Numbers of days that the convergence criterion (see `delta` and `delta2`) has to be fulfilled to stop the simulation. radiation (konrad.radiation): Radiation model. Defaults to :class:`konrad.radiation.RRTMG`. ozone (konrad.ozone): Ozone model. Defaults to :class:`konrad.ozone.OzonePressure`. humidity (konrad.humidity): Humidity model. Defaults to :class:`konrad.humidity.FixedRH`. surface (konrad.surface): Surface model. Defaults to :class:`konrad.surface.SlabOcean`. cloud (konrad.cloud): Cloud model. Defaults to :class:`konrad.cloud.ClearSky`. convection (konrad.convection): Convection scheme. Defaults to :class:`konrad.convection.HardAdjustment`. lapserate (konrad.lapserate): Lapse rate handler. Defaults to :class:`konrad.lapserate.MoistLapseRate`. upwelling (konrad.upwelling): Upwelling model. Defaults to :class:`konrad.upwelling.NoUpwelling`. diurnal_cycle (bool): Toggle diurnal cycle of solar angle. co2_adjustment_timescale (int/float): Adjust CO2 concentrations towards an equilibrium state following Romps 2020. To be used with :class:`konrad.surface.FixedTemperature`. Recommended value is 7 (1 week). Defaults to no CO2 adjustment, with `np.nan`. logevery (int): Log the model progress at every nth iteration. Default is no logging. This keyword only affects the frequency with which the log messages are generated. You have to enable the logging by using the :py:mod:`logging` standard library or the `konrad.enable_logging()` convenience function. timestep_adjuster (callable): A callable object, that takes the current timestep and the temperature change as input to calculate a new timestep (`f(timestep, deltaT)`). Default (`None`) is keeping the given timestep fixed. """ # Sub-model initialisation # Atmosphere self.atmosphere = atmosphere # Radiation if radiation is None: self.radiation = RRTMG() else: self.radiation = radiation # Ozone self.ozone = utils.return_if_type(ozone, 'ozone', Ozone, OzonePressure()) # Humidity self.humidity = FixedRH() if humidity is None else humidity # Surface self.surface = utils.return_if_type(surface, 'surface', Surface, SlabOcean()) # Cloud self.cloud = utils.return_if_type( cloud, 'cloud', Cloud, ClearSky(self.atmosphere['plev'].size)) # Convection self.convection = utils.return_if_type(convection, 'convection', Convection, HardAdjustment()) # Critical lapse-rate self.lapserate = utils.return_if_type(lapserate, 'lapserate', LapseRate, MoistLapseRate()) # Stratospheric upwelling self.upwelling = utils.return_if_type(upwelling, 'upwelling', Upwelling, NoUpwelling()) # Diurnal cycle self.diurnal_cycle = diurnal_cycle # Time, timestepping and duration attributes self.timestep = utils.parse_fraction_of_day(timestep) self.time = datetime.datetime(1, 1, 1) # Start model run at 0001/1/1 self.max_duration = utils.parse_fraction_of_day(max_duration) self.niter = 0 self.timestep_adjuster = timestep_adjuster # Output writing attributes self.writeevery = utils.parse_fraction_of_day(writeevery) self.last_written = self.time self.outfile = outfile self.nchandler = None self.experiment = experiment # Logging attributes self.logevery = logevery # Attributes used by the is_converged() method self.delta = delta if delta != 0.0 and delta2 == 0.0: self.delta2 = delta / 100 else: self.delta2 = delta2 self.oldN = 0 self.oldDN = 0 self.newDN = 0 self.newDDN = 0 self.counteq = datetime.timedelta(microseconds=0) self.post_count = utils.parse_fraction_of_day(post_count) self.converged = False # Attributes used by the time-step adjuster self.oldT = 0 self.deltaT = 0 # Attributes for experiments with varying carbon dioxide following # Romps (2020) self.co2_adjustment_timescale = co2_adjustment_timescale if not np.isnan(co2_adjustment_timescale) and not isinstance( surface, FixedTemperature): raise TypeError("Runs with adjusting CO2 concentration " "require a fixed surface temperature.") logging.info('Created Konrad object:\n{}'.format(self))
def __init__( self, atmosphere, timestep='6h', max_duration='500d', outfile=None, experiment='RCE', writeevery='24h', writefor=None, delta=0.0, radiation=None, ozone=None, humidity=None, surface=None, cloud=None, convection=None, lapserate=None, upwelling=None, diurnal_cycle=False, co2_adjustment_timescale=np.nan, logevery=None, timestep_adjuster=None, ): """Set-up a radiative-convective model. Parameters: atmosphere: :py:class:`konrad.atmosphere.Atmosphere`. timestep (float, str or timedelta): Model time step * If float, time step in days. * If str, a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). * A `timedelta` object is directly used as timestep. max_duration (float, str or timedelta): Maximum duration. The duration is given in model time * If float, maximum duration in days. * If str, a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). * A `timedelta` object is directly used as timestep. outfile (str): netCDF4 file to store output. experiment (str): Experiment description (stored in netCDF output). writeevery (float, str or timedelta): Set output frequency. * float: Every nth day in model time * str: a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). * A `timedelta` object is directly used as timestep. * Note: Setting a value of `"0h"` will write after every iteration. writefor (None, float, str or timedelta): whenever the writing function is triggered because of 'writeevery', it will also be triggered for the next 'writefor' days * None: disable this functionality * float: for n days * str: a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). * A `timedelta` object is directly used as timestep. Defaults to None delta (float): Stop criterion. If the heating rate is below this threshold for all levels, skip further iterations. Values are given in K/day. radiation (konrad.radiation): Radiation model. Defaults to :class:`konrad.radiation.RRTMG`. ozone (konrad.ozone): Ozone model. Defaults to :class:`konrad.ozone.OzonePressure`. humidity (konrad.humidity): Humidity model. Defaults to :class:`konrad.humidity.FixedRH`. surface (konrad.surface): Surface model. Defaults to :class:`konrad.surface.SlabOcean`. cloud (konrad.cloud): Cloud model. Defaults to :class:`konrad.cloud.ClearSky`. convection (konrad.convection): Convection scheme. Defaults to :class:`konrad.convection.HardAdjustment`. lapserate (konrad.lapserate): Lapse rate handler. Defaults to :class:`konrad.lapserate.MoistLapseRate`. upwelling (konrad.upwelling): Upwelling model. Defaults to :class:`konrad.upwelling.NoUpwelling`. diurnal_cycle (bool): Toggle diurnal cycle of solar angle. co2_adjustment_timescale (int/float): Adjust CO2 concentrations towards an equilibrium state following Romps 2020. To be used with :class:`konrad.surface.FixedTemperature`. Recommended value is 7 (1 week). Defaults to no CO2 adjustment, with `np.nan`. logevery (int): Log the model progress at every nth iteration. Default is no logging. This keyword only affects the frequency with which the log messages are generated. You have to enable the logging by using the :py:mod:`logging` standard library or the `konrad.enable_logging()` convenience function. timestep_adjuster (callable): A callable object, that takes the current timestep and the temperature change as input to calculate a new timestep (`f(timestep, deltaT)`). Default (`None`) is keeping the given timestep fixed. """ # Sub-models. self.atmosphere = atmosphere if radiation is None: self.radiation = RRTMG() else: self.radiation = radiation self.ozone = utils.return_if_type(ozone, 'ozone', Ozone, OzonePressure()) self.humidity = FixedRH() if humidity is None else humidity self.surface = utils.return_if_type(surface, 'surface', Surface, SlabOcean()) self.cloud = utils.return_if_type(cloud, 'cloud', Cloud, ClearSky(self.atmosphere['plev'].size) ) self.convection = utils.return_if_type(convection, 'convection', Convection, HardAdjustment()) self.lapserate = utils.return_if_type(lapserate, 'lapserate', LapseRate, MoistLapseRate()) self.upwelling = utils.return_if_type(upwelling, 'upwelling', Upwelling, NoUpwelling()) self.diurnal_cycle = diurnal_cycle self.timestep = utils.parse_fraction_of_day(timestep) self.time = datetime.datetime(1, 1, 1) # Start model run at 0001/1/1 self.max_duration = utils.parse_fraction_of_day(max_duration) self.niter = 0 self.writeevery = utils.parse_fraction_of_day(writeevery) self.last_written = self.time self.writefor = utils.parse_fraction_of_day(writefor) self.logevery = logevery self.delta = delta self.deltaT = None self.converged = False self.outfile = outfile self.nchandler = None self.experiment = experiment self.co2_adjustment_timescale = co2_adjustment_timescale if not np.isnan(co2_adjustment_timescale) and not isinstance( surface, FixedTemperature): raise TypeError( "Runs with adjusting CO2 concentration " "require a fixed surface temperature." ) self.timestep_adjuster = timestep_adjuster logging.info('Created Konrad object:\n{}'.format(self))
def __init__(self, atmosphere, timestep='3h', max_duration='5000d', outfile=None, experiment='RCE', writeevery='1d', delta=1e-4, radiation=None, ozone=None, humidity=None, surface=None, cloud=None, convection=None, lapserate=None, upwelling=None, diurnal_cycle=False, co2_adjustment_timescale=np.nan): """Set-up a radiative-convective model. Parameters: atmosphere: :py:class:`konrad.atmosphere.Atmosphere`. timestep (float or str): Model time step (per iteration) * If float, time step in days. * If str, a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). max_duration (float or str): Maximum duration of the simulation The duration is given in model time * If float, maximum duration in days. * If str, a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). outfile (str): netCDF4 file to store output. experiment (str): Experiment description (stored in netCDF output). writeevery (int, float or str): Set output frequency. * int: Every nth iteration * float: Every nth day in model time * str: a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). delta (float): Stop criterion. If the heating rate is below this threshold for all levels, skip further iterations. Values are given in K/day. radiation (konrad.radiation): Radiation model. Defaults to :class:`konrad.radiation.RRTMG`. ozone (konrad.ozone): Ozone model. Defaults to :class:`konrad.ozone.OzonePressure`. humidity (konrad.humidity): Humidity model. Defaults to :class:`konrad.humidity.FixedRH`. surface (konrad.surface): Surface model. Defaults to :class:`konrad.surface.SurfaceHeatCapacity`. cloud (konrad.cloud): Cloud model. Defaults to :class:`konrad.cloud.ClearSky`. convection (konrad.convection): Convection scheme. Defaults to :class:`konrad.convection.HardAdjustment`. lapserate (konrad.lapserate): Lapse rate handler. Defaults to :class:`konrad.lapserate.MoistLapseRate`. upwelling (konrad.upwelling): Upwelling model. Defaults to :class:`konrad.upwelling.NoUpwelling`. diurnal_cycle (bool): Toggle diurnal cycle of solar angle. co2_adjustment_timescale (int/float): Adjust CO2 concentrations towards an equilibrium state following Romps 2020. To be used with :class:`konrad.surface.FixedTemperature`. Recommended value is 7 (1 week). Defaults to no CO2 adjustment, with `np.nan`. """ # Sub-models. self.atmosphere = atmosphere if radiation is None: self.radiation = RRTMG() else: self.radiation = radiation self.ozone = utils.return_if_type(ozone, 'ozone', Ozone, OzonePressure()) self.humidity = FixedRH() if humidity is None else humidity self.surface = utils.return_if_type(surface, 'surface', Surface, SlabOcean()) self.cloud = utils.return_if_type( cloud, 'cloud', Cloud, ClearSky(self.atmosphere['plev'].size)) self.convection = utils.return_if_type(convection, 'convection', Convection, HardAdjustment()) self.lapserate = utils.return_if_type(lapserate, 'lapserate', LapseRate, MoistLapseRate()) self.upwelling = utils.return_if_type(upwelling, 'upwelling', Upwelling, NoUpwelling()) self.diurnal_cycle = diurnal_cycle self.max_duration = utils.parse_fraction_of_day(max_duration) self.timestep = utils.parse_fraction_of_day(timestep) self.writeevery = utils.parse_fraction_of_day(writeevery) self.max_iterations = np.ceil(self.max_duration / self.timestep) self.niter = 0 self.delta = delta self.deltaT = None self.converged = False self.outfile = outfile self.nchandler = None self.experiment = experiment self.co2_adjustment_timescale = co2_adjustment_timescale if not np.isnan(co2_adjustment_timescale) and not isinstance( surface, FixedTemperature): raise TypeError("Runs with adjusting CO2 concentration " "require a fixed surface temperature.") logging.info('Created Konrad object:\n{}'.format(self))
def __init__(self, atmosphere, timestep='3h', max_duration='5000d', outfile=None, experiment='RCE', writeevery='1d', delta=1e-4, radiation=None, ozone=None, humidity=None, surface=None, cloud=None, convection=None, lapserate=None, upwelling=None): """Set-up a radiative-convective model. Parameters: atmosphere: :py:class:`konrad.atmosphere.Atmosphere`. timestep (float or str): Model time step (per iteration) * If float, time step in days. * If str, a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). max_duration (float or str): Maximum duration of the simulation The duration is given in model time * If float, maximum duration in days. * If str, a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). outfile (str): netCDF4 file to store output. experiment (str): Experiment description (stored in netCDF output). writeevery (int, float or str): Set output frequency. * int: Every nth iteration * float: Every nth day in model time * str: a timedelta string (see :func:`konrad.utils.parse_fraction_of_day`). delta (float): Stop criterion. If the heating rate is below this threshold for all levels, skip further iterations. Values are given in K/day. radiation (konrad.radiation): Radiation model. Defaults to :class:`konrad.radiation.RRTMG`. ozone (konrad.ozone): Ozone model. Defaults to :class:`konrad.ozone.OzonePressure`. humidity (konrad.humidity): Humidity model. Defaults to :class:`konrad.humidity.FixedRH`. surface (konrad.surface): Surface model. Defaults to :class:`konrad.surface.SurfaceHeatCapacity`. cloud (konrad.cloud): Cloud model. Defaults to :class:`konrad.cloud.ClearSky`. convection (konrad.convection): Convection scheme. Defaults to :class:`konrad.convection.HardAdjustment`. lapserate (konrad.lapserate): Lapse rate handler. Defaults to :class:`konrad.lapserate.MoistLapseRate`. upwelling (konrad.upwelling): Upwelling model. Defaults to :class:`konrad.upwelling.NoUpwelling`. """ # Sub-models. self.atmosphere = atmosphere if radiation is None: self.radiation = RRTMG() else: self.radiation = radiation self.ozone = utils.return_if_type(ozone, 'ozone', Ozone, OzonePressure()) self.humidity = FixedRH() if humidity is None else humidity self.surface = utils.return_if_type(surface, 'surface', Surface, SurfaceHeatCapacity()) self.cloud = utils.return_if_type( cloud, 'cloud', Cloud, ClearSky(self.atmosphere['plev'].size)) self.convection = utils.return_if_type(convection, 'convection', Convection, HardAdjustment()) self.lapserate = utils.return_if_type(lapserate, 'lapserate', LapseRate, MoistLapseRate()) self.upwelling = utils.return_if_type(upwelling, 'upwelling', Upwelling, NoUpwelling()) self.max_duration = utils.parse_fraction_of_day(max_duration) self.timestep = utils.parse_fraction_of_day(timestep) self.writeevery = utils.parse_fraction_of_day(writeevery) self.max_iterations = np.ceil(self.max_duration / self.timestep) self.niter = 0 self.delta = delta self.deltaT = None self.converged = False self.outfile = outfile self.nchandler = None self.experiment = experiment logging.info('Created Konrad object:\n{}'.format(self))