def test_multidim_tendencies(): # Same test just repeated in two parallel columns num_lat = 2 state = climlab.column_state(num_lev=num_lev, num_lat=num_lat) state['q'] = state.Tatm * 0. #+ Q state['U'] = state.Tatm * 0. #+ U state['V'] = state.Tatm * 0. #+ V for i in range(num_lat): state.Tatm[i,:] = T state['q'][i,:] += Q state['U'][i,:] += U state['V'][i,:] += V assert hasattr(state, 'Tatm') assert hasattr(state, 'q') assert hasattr(state, 'U') assert hasattr(state, 'V') conv = emanuel_convection.EmanuelConvection(state=state, timestep=DELT) conv.step_forward() # Did we get all the correct output? assert np.all(conv.IFLAG == 1) # relative tolerance for these tests ... tol = 1E-5 assert np.all(conv.CBMF == pytest.approx(3.10377218E-02, rel=tol)) tend = conv.tendencies assert np.tile(FT,(num_lat,1)) == pytest.approx(tend['Tatm'], rel=tol) assert np.tile(FQ,(num_lat,1)) == pytest.approx(tend['q'], rel=tol) assert np.tile(FU,(num_lat,1)) == pytest.approx(tend['U'], rel=tol) assert np.tile(FV,(num_lat,1)) == pytest.approx(tend['V'], rel=tol)
def test_latitude(): ''' Run a radiative equilibrum model with RRTMG radiation out to equilibrium with an annual mean insolation profile as a function of latitude. ''' num_lat = 8 # State variables (Air and surface temperature) state = climlab.column_state(num_lev=30, num_lat=num_lat, water_depth=1.) # insolation #sol = climlab.radiation.AnnualMeanInsolation(domains=model.Ts.domain) sol = climlab.radiation.AnnualMeanInsolation(name='Insolation', domains=state.Ts.domain) # radiation module with insolation as input # Set icld=0 for clear-sky only (no need to call cloud overlap routine) rad = climlab.radiation.RRTMG(name='Radiation', state=state, icld=0, S0=sol.S0, insolation=sol.insolation, coszen=sol.coszen) # Couple everything together model = rad + sol # Run out to equilibrium model.integrate_years(2.) # Test for energy balance assert np.all(np.abs(model.ASR - model.OLR) < 0.1) # Test for reasonable surface temperature gradient # reversal of gradient at equator grad = np.diff(model.Ts, axis=0) assert np.all(grad[0:(int(num_lat/2)-1)] > 0.) assert np.all(grad[int(num_lat/2):] < 0.)
def test_rcm_emanuel(): num_lev = 30 water_depth = 5. # Temperatures in a single column state = climlab.column_state(num_lev=num_lev, water_depth=water_depth) # Initialize a nearly dry column (small background stratospheric humidity) state['q'] = np.ones_like(state.Tatm) * 5.E-6 # ASYNCHRONOUS COUPLING -- the radiation uses a much longer timestep short_timestep = climlab.constants.seconds_per_hour # The top-level model model = climlab.TimeDependentProcess(name='Radiative-Convective Model', state=state, timestep=short_timestep) # Radiation coupled to water vapor rad = climlab.radiation.RRTMG(name='Radiation', state=state, specific_humidity=state.q, albedo=0.3, timestep=24*short_timestep) # Convection scheme -- water vapor is a state variable conv = climlab.convection.EmanuelConvection(name='Convection', state=state, timestep=short_timestep) # Surface heat flux processes shf = climlab.surface.SensibleHeatFlux(name='SHF', state=state, Cd=0.5E-3, timestep=climlab.constants.seconds_per_hour) lhf = climlab.surface.LatentHeatFlux(name='LHF', state=state, Cd=0.5E-3, timestep=short_timestep) # Couple all the submodels together for proc in [rad, conv, shf, lhf]: model.add_subprocess(proc.name, proc) model.step_forward() to_xarray(model)
def test_large_grid(): num_lev = 50; num_lat=90 state = climlab.column_state(num_lev=num_lev, num_lat=num_lat, water_depth=10.) rad1 = climlab.radiation.CAM3(state=state) rad1.step_forward() rad2 = climlab.radiation.RRTMG(state=state) rad2.step_forward()
def build_rcm(num_lev=30, water_depth=2.5): # Temperatures in a single column state = climlab.column_state(num_lev=num_lev, water_depth=water_depth) # Initialize a nearly dry column (small background stratospheric humidity) state['q'] = np.ones_like(state.Tatm) * 5.E-6 # ASYNCHRONOUS COUPLING -- the radiation uses a much longer timestep short_timestep = climlab.constants.seconds_per_hour # Radiation coupled to water vapor rad = climlab.radiation.RRTMG(name='Radiation', state=state, specific_humidity=state.q, albedo=0.2, timestep=24*short_timestep) # Convection scheme -- water vapor is a state variable conv = climlab.convection.EmanuelConvection(name='Convection', state=state, timestep=short_timestep, ALPHA=0.1,) # Surface heat flux processes shf = climlab.surface.SensibleHeatFlux(name='SHF', state=state, Cd=0.5E-3, U=10., timestep=short_timestep) lhf = climlab.surface.LatentHeatFlux(name='LHF', state=state, Cd=0.5E-3, U=10., timestep=short_timestep) # Couple all the submodels together turb = climlab.couple([shf,lhf], name='Turbulent') model = climlab.couple([rad, conv, turb], name='RadiativeConvectiveModel') for proc in [rad, conv, shf, lhf]: model.add_subprocess(proc.name, proc) return model
def test_latitude(): ''' Run a radiative equilibrum model with RRTMG radiation out to equilibrium with an annual mean insolation profile as a function of latitude. ''' num_lat = 8 # State variables (Air and surface temperature) state = climlab.column_state(num_lev=30, num_lat=num_lat, water_depth=1.) # insolation #sol = climlab.radiation.AnnualMeanInsolation(domains=model.Ts.domain) sol = climlab.radiation.AnnualMeanInsolation(name='Insolation', domains=state.Ts.domain) # radiation module with insolation as input # Set icld=0 for clear-sky only (no need to call cloud overlap routine) rad = climlab.radiation.RRTMG(name='Radiation', state=state, icld=0, S0=sol.S0, insolation=sol.insolation, coszen=sol.coszen) # Couple everything together model = rad + sol # Run out to equilibrium model.integrate_years(2.) # Test for energy balance assert np.all(np.abs(model.ASR - model.OLR) < 0.1) # Test for reasonable surface temperature gradient # reversal of gradient at equator grad = np.diff(model.Ts, axis=0) assert np.all(grad[0:(int(num_lat / 2) - 1)] > 0.) assert np.all(grad[int(num_lat / 2):] < 0.)
def test_radiative_forcing(): '''Run a single-column radiative-convective model with RRTMG radiation out to equilibrium. Clone the model, double CO2 and measure the instantaneous change in TOA flux. It should be positive net downward flux.''' # State variables (Air and surface temperature) state = climlab.column_state(num_lev=30, water_depth=1.) # Fixed relative humidity h2o = climlab.radiation.ManabeWaterVapor(name='WaterVapor', state=state) # Couple water vapor to radiation # Set icld=0 for clear-sky only (no need to call cloud overlap routine) rad = climlab.radiation.RRTMG(name='Radiation', state=state, specific_humidity=h2o.q, icld=0) # Convective adjustment conv = climlab.convection.ConvectiveAdjustment(name='Convection', state=state, adj_lapse_rate=6.5) # Couple everything together rcm = climlab.couple([rad, h2o, conv], name='Radiative-Convective Model') rcm.integrate_years(5.) assert np.abs(rcm.ASR - rcm.OLR) < 0.1 # close to energy balance rcm2 = climlab.process_like(rcm) rcm2.subprocess['Radiation'].absorber_vmr['CO2'] *= 2. rcm2.compute_diagnostics() assert (rcm2.ASR - rcm2.OLR) > 1. # positive radiative forcing # Test the xarray interface to_xarray(rcm2)
def test_radiative_forcing(): '''Run a single-column radiative-convective model with CAM3 radiation out to equilibrium. Clone the model, double CO2 and measure the instantaneous change in TOA flux. It should be positive net downward flux.''' # State variables (Air and surface temperature) state = climlab.column_state(num_lev=30, water_depth=1.) # Parent model process rcm = climlab.TimeDependentProcess(state=state) # Fixed relative humidity h2o = climlab.radiation.ManabeWaterVapor(state=state) # Couple water vapor to radiation rad = climlab.radiation.RRTMG(state=state, h2ovmr=h2o.q) # Convective adjustment conv = climlab.convection.ConvectiveAdjustment(state=state, adj_lapse_rate=6.5) # Couple everything together rcm.add_subprocess('Radiation', rad) rcm.add_subprocess('WaterVapor', h2o) rcm.add_subprocess('Convection', conv) rcm.integrate_years(5.) #assert np.abs(rcm.ASR - rcm.OLR) < 0.1 # close to energy balance # There is currently a problem with energy conservation in the RRTM module, need to look into this. rcm2 = climlab.process_like(rcm) rcm2.subprocess['Radiation'].co2vmr *= 2. rcm2.compute_diagnostics()
def test_latitude(): ''' Run a radiative equilibrum model with RRTMG radiation out to equilibrium with an annual mean insolation profile as a function of latitude. ''' num_lat = 8 # State variables (Air and surface temperature) state = climlab.column_state(num_lev=30, num_lat=num_lat, water_depth=1.) # Parent model process model = climlab.TimeDependentProcess(state=state) # insolation sol = climlab.radiation.AnnualMeanInsolation(domains=model.Ts.domain) # radiation module with insolation as input rad = climlab.radiation.RRTMG(state=state, S0=sol.S0, insolation=sol.insolation) # Couple everything together model.add_subprocess('Radiation', rad) model.add_subprocess('Insolation', sol) # Run out to equilibrium model.integrate_years(2.) # Test for energy balance assert np.all(np.abs(model.ASR - model.OLR) < 0.1) # Test for reasonable surface temperature gradient # reversal of gradient at equator grad = np.diff(model.Ts, axis=0) assert np.all(grad[0:(int(num_lat/2)-1)] > 0.) assert np.all(grad[int(num_lat/2):] < 0.)
def test_radiative_forcing(): '''Run a single-column radiative-convective model with RRTMG radiation out to equilibrium. Clone the model, double CO2 and measure the instantaneous change in TOA flux. It should be positive net downward flux.''' # State variables (Air and surface temperature) state = climlab.column_state(num_lev=30, water_depth=1.) # Fixed relative humidity h2o = climlab.radiation.ManabeWaterVapor(name='WaterVapor', state=state) # Couple water vapor to radiation # Set icld=0 for clear-sky only (no need to call cloud overlap routine) rad = climlab.radiation.RRTMG(name='Radiation', state=state, specific_humidity=h2o.q, icld=0) # Convective adjustment conv = climlab.convection.ConvectiveAdjustment(name='Convection', state=state, adj_lapse_rate=6.5) # Couple everything together rcm = climlab.couple([rad,h2o,conv], name='Radiative-Convective Model') rcm.integrate_years(5.) assert np.abs(rcm.ASR - rcm.OLR) < 0.1 # close to energy balance rcm2 = climlab.process_like(rcm) rcm2.subprocess['Radiation'].absorber_vmr['CO2'] *= 2. rcm2.compute_diagnostics() assert (rcm2.ASR - rcm2.OLR) > 1. # positive radiative forcing # Test the xarray interface to_xarray(rcm2)
def test_multidim_tendencies(): # Same test just repeated in two parallel columns num_lat = 2 state = climlab.column_state(num_lev=num_lev, num_lat=num_lat) state['q'] = state.Tatm * 0. #+ Q state['U'] = state.Tatm * 0. #+ U state['V'] = state.Tatm * 0. #+ V for i in range(num_lat): state.Tatm[i, :] = T state['q'][i, :] += Q state['U'][i, :] += U state['V'][i, :] += V assert hasattr(state, 'Tatm') assert hasattr(state, 'q') assert hasattr(state, 'U') assert hasattr(state, 'V') conv = emanuel_convection.EmanuelConvection(state=state, timestep=DELT) conv.step_forward() # Did we get all the correct output? assert np.all(conv.IFLAG == 1) # relative tolerance for these tests ... tol = 1E-5 assert np.all(conv.CBMF == pytest.approx(CBMF, rel=tol)) tend = conv.tendencies assert np.tile(FT, (num_lat, 1)) == pytest.approx(tend['Tatm'], rel=tol) assert np.tile(FQ, (num_lat, 1)) == pytest.approx(tend['q'], rel=tol) assert np.tile(FU, (num_lat, 1)) == pytest.approx(tend['U'], rel=tol) assert np.tile(FV, (num_lat, 1)) == pytest.approx(tend['V'], rel=tol)
def test_cloud(): '''Put a high cloud layer in a radiative model. The all-sky ASR should be lower than clear-sky ASR. The all-sky OLR should be lower than clear-sky OLR.''' # State variables (Air and surface temperature) state = climlab.column_state(num_lev=50, water_depth=1.) lev = state.Tatm.domain.axes['lev'].points # Define some local cloud characteristics cldfrac = 0.5 # layer cloud fraction r_liq = 14. # Cloud water drop effective radius (microns) clwp = 60. # in-cloud liquid water path (g/m2) # The cloud fraction is a Gaussian bump centered at level i i = 25 mycloud = { 'cldfrac': cldfrac * np.exp(-(lev - lev[i])**2 / (2 * 25.)**2), 'clwp': np.zeros_like(state.Tatm) + clwp, 'r_liq': np.zeros_like(state.Tatm) + r_liq, } # Test both RRTMG and CAM3: #for module in [climlab.radiation.RRTMG, climlab.radiation.CAM3]: # Apparently clouds in CAM3 are not working. Save this for later for module in [climlab.radiation.RRTMG]: rad = module(state=state, **mycloud) rad.compute_diagnostics() assert (rad.ASR - rad.ASRclr < 0.) assert (rad.OLR - rad.OLRclr < 0.)
def test_re_radiative_forcing(): state = climlab.column_state(num_lev=num_lev) rad = climlab.radiation.CAM3(state=state) rad.integrate_years(2) assert np.abs(rad.ASR - rad.OLR) < 0.1 # close to energy balance rad2 = climlab.process_like(rad) rad2.absorber_vmr['CO2'] *= 2. rad2.compute_diagnostics() assert (rad2.ASR - rad2.OLR) > 1. # positive radiative forcing
def test_thermo_domain(): '''Can we call qsat, etc on a multi-dim climlab state temperature object?''' state = climlab.column_state(num_lev = 30, num_lat=3) T = state.Tatm p = T.domain.lev.points thermo.clausius_clapeyron(T) thermo.qsat(T, p) thermo.pseudoadiabat(T, p) thermo.blackbody_emission(T)
def test_multidim(): state = climlab.column_state(num_lev=40, num_lat=3, water_depth=5.) rad = climlab.radiation.RRTMG_LW(state=state) # are the transformations reversible? assert np.all(_rrtm_to_climlab(_climlab_to_rrtm(rad.Ts)) == rad.Ts) assert np.all(_rrtm_to_climlab(_climlab_to_rrtm(rad.Tatm)) == rad.Tatm) # Can we integrate? rad.step_forward() assert rad.OLR.shape == rad.Ts.shape
def test_fixed_insolation(): '''Make sure that we can run a model forward with specified time-invariant insolation''' num_lat = 4; num_lev = 20 # grid size day_of_year = 80. # days since Jan 1 lat = np.linspace(-80., 80., num_lat) state = climlab.column_state(num_lev=num_lev, lat=lat) insolation = climlab.solar.insolation.daily_insolation(lat=lat, day=day_of_year) ins_array = insolation.values rad = climlab.radiation.RRTMG(name='Radiation', state=state, insolation=ins_array) rad.step_forward()
def test_large_grid(): num_lev = 50 num_lat = 90 state = climlab.column_state(num_lev=num_lev, num_lat=num_lat, water_depth=10.) rad1 = climlab.radiation.CAM3(state=state) rad1.step_forward() rad2 = climlab.radiation.RRTMG(state=state) rad2.step_forward()
def make_real_column(tempArray, presArray, num_lev=100): # Set up a column state state = climlab.column_state(num_lev=num_lev, num_lat=1) # Extract the pressure levels plevs = state['Tatm'].domain.axes['lev'].points # Set the SST surfInd = np.argmax(presArray) state['Ts'][:] = tempArray[surfInd] # Set the atmospheric profile state['Tatm'][:] = np.interp(plevs, presArray, tempArray) return state, plevs
def test_rrtm_creation(): # initial state (temperatures) state = climlab.column_state(num_lev=num_lev, num_lat=1, water_depth=5.) # Create a RRTM radiation model rad = climlab.radiation.RRTMG(state=state) rad.step_forward() assert type(rad.subprocess['LW']) is climlab.radiation.RRTMG_LW assert type(rad.subprocess['SW']) is climlab.radiation.RRTMG_SW assert hasattr(rad, 'OLR') assert hasattr(rad, 'OLRclr') assert hasattr(rad, 'ASR') assert hasattr(rad, 'ASRclr')
def test_swap_component(): # initial state (temperatures) state = climlab.column_state(num_lev=num_lev, num_lat=1, water_depth=5.) # Create a RRTM radiation model rad = climlab.radiation.RRTMG(state=state) rad.step_forward() # Swap out the longwave model for CAM3 rad.remove_subprocess('LW') rad.step_forward() rad.add_subprocess('LW', climlab.radiation.CAM3_LW(state=state)) rad.step_forward() assert hasattr(rad, 'OLR')
def test_swap_component(): # initial state (temperatures) state = climlab.column_state(num_lev=num_lev, num_lat=1, water_depth=5.) # Create a RRTM radiation model rad = climlab.radiation.RRTMG(state=state) rad.step_forward() # Swap out the longwave model for CAM3 rad.remove_subprocess('LW') rad.step_forward() rad.add_subprocess('LW', climlab.radiation.CAM3Radiation_LW(state=state)) rad.step_forward() assert hasattr(rad, 'OLR')
def make_idealized_column(SST, num_lev=100, Tstrat=200): # Set up a column state state = climlab.column_state(num_lev=num_lev, num_lat=1) # Extract the pressure levels plevs = state['Tatm'].domain.axes['lev'].points # Set the SST state['Ts'][:] = SST # Set the atmospheric profile to be our idealized profile state['Tatm'][:] = generate_idealized_temp_profile(SST=SST, plevs=plevs, Tstrat=Tstrat) return state
def test_no_ozone(): '''When user gives None as the ozone_file, the model is initialized with zero ozone. This should work on arbitrary grids.''' ps = 1060. num_lev = 4000 state = climlab.column_state(num_lev=num_lev, num_lat=1, water_depth=5.) lev = state.Tatm.domain.lev lev.bounds = np.linspace(0., ps, num_lev + 1) lev.points = lev.bounds[:-1] + np.diff(lev.bounds) / 2. lev.delta = np.abs(np.diff(lev.bounds)) # Create a RRTM radiation model rad = climlab.radiation.RRTMG(state=state, ozone_file=None) assert np.all(rad.absorber_vmr['O3'] == 0.)
def test_no_ozone(): '''When user gives None as the ozone_file, the model is initialized with zero ozone. This should work on arbitrary grids.''' ps = 1060. num_lev=4000 state = climlab.column_state(num_lev=num_lev, num_lat=1, water_depth=5.) lev = state.Tatm.domain.lev lev.bounds = np.linspace(0., ps, num_lev+1) lev.points = lev.bounds[:-1] + np.diff(lev.bounds)/2. lev.delta = np.abs(np.diff(lev.bounds)) # Create a RRTM radiation model rad = climlab.radiation.RRTMG(state=state, ozone_file=None) assert np.all(rad.absorber_vmr['O3']==0.)
def test_rrtm_creation(): # initial state (temperatures) state = climlab.column_state(num_lev=num_lev, num_lat=1, water_depth=5.) # Create a RRTM radiation model rad = climlab.radiation.RRTMG(state=state) rad.step_forward() assert type(rad.subprocess['LW']) is climlab.radiation.RRTMG_LW assert type(rad.subprocess['SW']) is climlab.radiation.RRTMG_SW assert hasattr(rad, 'OLR') assert hasattr(rad, 'OLRclr') assert hasattr(rad, 'ASR') assert hasattr(rad, 'ASRclr') # Test the xarray interface to_xarray(rad)
def rcm(): # initial state (temperatures) state = climlab.column_state(num_lev=40, num_lat=1, water_depth=5.) ## Create individual physical process models: # fixed relative humidity h2o = climlab.radiation.ManabeWaterVapor(state=state, name='H2O') # Hard convective adjustment convadj = climlab.convection.ConvectiveAdjustment(state=state, name='ConvectiveAdjustment', adj_lapse_rate=6.5) # RRTMG radiation with default parameters and interactive water vapor rad = climlab.radiation.RRTMG(state=state, albedo=0.2, specific_humidity=h2o.q, name='Radiation') # Couple the models rcm = climlab.couple([h2o,convadj,rad], name='RCM') return rcm
def test_fixed_insolation(): '''Make sure that we can run a model forward with specified time-invariant insolation''' num_lat = 4 num_lev = 20 # grid size day_of_year = 80. # days since Jan 1 lat = np.linspace(-80., 80., num_lat) state = climlab.column_state(num_lev=num_lev, lat=lat) insolation = climlab.solar.insolation.daily_insolation(lat=lat, day=day_of_year) ins_array = insolation.values rad = climlab.radiation.RRTMG(name='Radiation', state=state, insolation=ins_array) rad.step_forward()
def test_large_grid(): num_lev = 50 num_lat = 90 state = climlab.column_state(num_lev=num_lev, num_lat=num_lat, water_depth=10.) rad1 = climlab.radiation.CAM3(state=state) rad1.step_forward() rad2 = climlab.radiation.RRTMG(state=state) rad2.step_forward() # Spectral OLR test # check that the spectrally decomposed TOA flux adds up to the normal OLR output rad3 = climlab.radiation.RRTMG(state=state, return_spectral_olr=True) rad3.step_forward() assert np.all(np.abs(rad3.OLR - rad3.OLR_spectral.sum(axis=-1)) < 0.1) # Test the xarray interface to_xarray(rad3)
def make_column(lev=None, ps=1013, tmp=None, ts=None): state = climlab.column_state(lev=lev) num_lev = np.array(lev).size lev = state.Tatm.domain.lev lev_values = lev.points lev_dfs = np.zeros(num_lev) lev_dfs[1:] = np.diff(lev_values) lev_dfs[0] = lev_values[0] lev_dfs = lev_dfs / 2. lev.bounds = np.full(num_lev + 1, ps) lev.bounds[:-1] = lev_values - lev_dfs lev.delta = np.abs(np.diff(lev.bounds)) sfc, atm = domain.single_column(lev=lev) state['Ts'] = Field(ts, domain=sfc) state['Tatm'] = Field(tmp, domain=atm) return state
def rcm(): # initial state (temperatures) state = climlab.column_state(num_lev=num_lev, num_lat=1, water_depth=5.) # Create a parent process rcm = climlab.TimeDependentProcess(state=state) ## Create individual physical process models: # fixed relative humidity h2o = climlab.radiation.ManabeWaterVapor(state=state) # Hard convective adjustment convadj = climlab.convection.ConvectiveAdjustment(state=state, adj_lapse_rate=6.5) # CAM3 radiation with default parameters and interactive water vapor #rad = climlab.radiation.CAM3(state=state, albedo=alb, specific_humidity=h2o.q) rad = climlab.radiation.CAM3(state=state, albedo=alb) # Couple the models rcm.add_subprocess('Radiation', rad) rcm.add_subprocess('ConvectiveAdjustment', convadj) rcm.add_subprocess('H2O', h2o) return rcm
def test_convective_adjustment_multidim(): # can we do convective adjustment on a multidimensional grid? num_lev = 3 state = climlab.column_state(num_lev=num_lev, num_lat=2) conv = climlab.convection.ConvectiveAdjustment(state=state) # test non-scalar critical lapse rate conv.adj_lapse_rate = np.linspace(5., 8., num_lev+1) conv.step_forward() # Test two flags for dry adiabatic adjustment conv.adj_lapse_rate = 'DALR' conv.step_forward() conv.adj_lapse_rate = 'dry adiabat' conv.step_forward() # test pseudoadiabatic critical lapse rate conv.adj_lapse_rate = 'pseudoadiabat' conv.step_forward() conv.adj_lapse_rate = 'MALR' conv.step_forward() conv.adj_lapse_rate = 'moist adiabat' conv.step_forward()
def test_convect_tendencies(): # Temperatures in a single column state = climlab.column_state(num_lev=num_lev) state.Tatm[:] = T state['q'] = state.Tatm * 0. + Q state['U'] = state.Tatm * 0. + U state['V'] = state.Tatm * 0. + V assert hasattr(state, 'Tatm') assert hasattr(state, 'q') assert hasattr(state, 'U') assert hasattr(state, 'V') conv = emanuel_convection.EmanuelConvection(state=state, timestep=DELT) conv.step_forward() # Did we get all the correct output? assert conv.IFLAG == 1 # relative tolerance for these tests ... tol = 1E-5 assert conv.CBMF == pytest.approx(CBMF, rel=tol) tend = conv.tendencies assert FT == pytest.approx(tend['Tatm'], rel=tol) assert FQ == pytest.approx(tend['q'], rel=tol) assert FU == pytest.approx(tend['U'], rel=tol) assert FV == pytest.approx(tend['V'], rel=tol)
def test_convect_tendencies(): # Temperatures in a single column state = climlab.column_state(num_lev=num_lev) state.Tatm[:] = T state['q'] = state.Tatm * 0. + Q state['U'] = state.Tatm * 0. + U state['V'] = state.Tatm * 0. + V assert hasattr(state, 'Tatm') assert hasattr(state, 'q') assert hasattr(state, 'U') assert hasattr(state, 'V') conv = emanuel_convection.EmanuelConvection(state=state, timestep=DELT) conv.step_forward() # Did we get all the correct output? assert conv.IFLAG == 1 # relative tolerance for these tests ... tol = 1E-5 assert conv.CBMF == pytest.approx(3.10377218E-02, rel=tol) tend = conv.tendencies assert FT == pytest.approx(tend['Tatm'], rel=tol) assert FQ == pytest.approx(tend['q'], rel=tol) assert FU == pytest.approx(tend['U'], rel=tol) assert FV == pytest.approx(tend['V'], rel=tol)
def test_cloud(): '''Put a high cloud layer in a radiative model. The all-sky ASR should be lower than clear-sky ASR. The all-sky OLR should be lower than clear-sky OLR.''' # State variables (Air and surface temperature) state = climlab.column_state(num_lev=50, water_depth=1.) lev = state.Tatm.domain.axes['lev'].points # Define some local cloud characteristics cldfrac = 0.5 # layer cloud fraction r_liq = 14. # Cloud water drop effective radius (microns) clwp = 60. # in-cloud liquid water path (g/m2) # The cloud fraction is a Gaussian bump centered at level i i = 25 mycloud = {'cldfrac': cldfrac*np.exp(-(lev-lev[i])**2/(2*25.)**2), 'clwp': np.zeros_like(state.Tatm) + clwp, 'r_liq': np.zeros_like(state.Tatm) + r_liq,} # Test both RRTMG and CAM3: #for module in [climlab.radiation.RRTMG, climlab.radiation.CAM3]: # Apparently clouds in CAM3 are not working. Save this for later for module in [climlab.radiation.RRTMG]: rad = module(state=state, **mycloud) rad.compute_diagnostics() assert(rad.ASR - rad.ASRclr < 0.) assert(rad.OLR - rad.OLRclr < 0.)
def test_cam3_multidim(): state = climlab.column_state(num_lev=40, num_lat=3, water_depth=5.) rad = climlab.radiation.CAM3(state=state) # Can we integrate? rad.step_forward() assert rad.OLR.shape == rad.Ts.shape
def test_rrtmg_lw_creation(): state = climlab.column_state(num_lev=num_lev, water_depth=5.) rad = climlab.radiation.RRTMG_LW(state=state) # are the transformations reversible? assert np.all(_rrtm_to_climlab(_climlab_to_rrtm(rad.Ts)) == rad.Ts) assert np.all(_rrtm_to_climlab(_climlab_to_rrtm(rad.Tatm)) == rad.Tatm)
def compute(): # Values on a 1x1 degree grid lats = np.flip([float(i) for i in np.arange(-90, 91, 1)]) lons = np.array([float(i) for i in np.arange(0, 360, 1)]) # Import Data, ignoring 2000 because it starts in March data_t = xr.open_dataset('./Data/ERA5/era5_t_2000_2020.nc').sel( latitude=lats, longitude=lons).sel(time=slice("2001-01-01", "2020-12-30")) data_ts = xr.open_dataset('./Data/ERA5/era5_t2m_2000_2020.nc').sel( latitude=lats, longitude=lons, expver=1).sel(time=slice("2001-01-01", "2020-12-30")) data_q = xr.open_dataset('./Data/ERA5/era5_q_2000_2020.nc').sel( latitude=lats, longitude=lons).sel(time=slice("2001-01-01", "2020-12-30")) data_rh = xr.open_dataset('./Data/ERA5/era5_rh_2000_2020.nc').sel( latitude=lats, longitude=lons).sel(time=slice("2001-01-01", "2020-12-30")) data_sp = xr.open_dataset('./Data/ERA5/era5_sp_2000_2020.nc').sel( latitude=lats, longitude=lons, expver=1).sel(time=slice("2001-01-01", "2020-12-30")) levels = data_t.level.values month_list = np.arange(1, 13) olr_monav = [] ts_monav = [] for i_mon in range(len(month_list)): times_list = data_t.sel( time=data_t['time.month'] == month_list[i_mon]).time.values olr_list = [] for j in range(len(times_list)): # Get the correct pressure levels, when surface pressure is < 1000 mBar surf_p = data_sp.sel(latitude=latval, longitude=lonval, time=times_list[j]).sp.values[()] / 100 levels_correct = data_t.sel(level=slice(0, surf_p)).level.values # Create a column state with the correct pressure levels state = climlab.column_state(lev=levels_correct) # Correct lowest pressure level from 1000 mbar set by default state.Tatm.domain.lev.bounds[-1] = surf_p state.Tatm.domain.lev.delta[-1] = state.Tatm.domain.lev.bounds[ -1] - state.Tatm.domain.lev.bounds[-2] # Temperatures state.Tatm[:] = data_t.sel(latitude=latval, longitude=lonval, time=times_list[j], level=slice(0, surf_p)).t.values state.Ts[:] = data_ts.sel(latitude=latval, longitude=lonval, time=times_list[j]).t2m.values # Humidities h2o = climlab.radiation.water_vapor.ManabeWaterVapor(state=state) # h2o.q = data_q.sel(latitude=latval, longitude=lonval, time=times_list[j], level=slice(0,surf_p)).q.values # Taking the mean values of RH rh_vals = data_rh.r.sel( latitude=latval, longitude=lonval, level=slice(0, surf_p), time=data_rh['time.year'] == data_rh.sel( time=times_list[j])['time.year'].values[()]).mean( dim='time').values # Calculate q values from these constant RH values t_vals = data_t.sel(latitude=latval, longitude=lonval, time=times_list[j], level=slice(0, surf_p)).t.values q_vals = [] for k in range(len(rh_vals)): q_vals.append( q_from_rh(rh=rh_vals[k], T=t_vals[k], p=levels_correct[k])) # Set the humidities h2o.q = np.array(q_vals) # Couple water vapor to radiation rad = climlab.radiation.RRTMG(state=state, specific_humidity=h2o.q) # Run the model rad.compute() # Save output olr_list.append(rad.OLR[0]) olr_monav.append(np.mean(olr_list)) ts_monav.append( np.mean( data_ts.sel(latitude=latval, longitude=lonval, time=data_ts['time.month'] == month_list[i_mon]).t2m.values)) # Empty arrays to put data in ts_input = np.zeros((1, 1, 12)) olr_input = np.zeros((1, 1, 12)) for i in range(len(ts_input[0, 0, :])): ts_input[0, 0, i] = ts_monav[i] olr_input[0, 0, i] = olr_monav[i] ts_data = xr.DataArray(ts_input, dims=('lat', 'lon', 'month'), coords={ 'lat': [latval], 'lon': [lonval], 'month': month_list }) olr_data = xr.DataArray(olr_input, dims=('lat', 'lon', 'month'), coords={ 'lat': [latval], 'lon': [lonval], 'month': month_list }) h = xr.Dataset({'ts': ts_data, 'olr_calc': olr_data}) # A unique identifier for the output file, for later concatenation h_index = lat_lon_index(latval, lonval, lats, lons) h.to_netcdf('./Output_Data_ceres_const_rh/' + str(h_index) + '.nc') return