Skip to content

Commit 69d1e5d

Browse files
authored
Merge pull request #108 from lkluft/random
Fix MCICA for RRTMG
2 parents ddc6530 + dbb0bf2 commit 69d1e5d

13 files changed

+61
-17
lines changed

HISTORY.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
History
33
=======
44

5+
v.0.16.4
6+
--------
7+
8+
* Fix MCICA for the shortwave component of RRTMG
9+
* Revise random number generation for MCICA
10+
* Improvement of the user interface to control MCICA
11+
512
v.0.16.3
613
-------
714

climt/_components/rrtmg/lw/component.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
from numpy import pi as PI
99
from ..rrtmg_common import (
1010
rrtmg_cloud_overlap_method_dict, rrtmg_cloud_props_dict,
11-
rrtmg_cloud_ice_props_dict, rrtmg_cloud_liquid_props_dict)
11+
rrtmg_cloud_ice_props_dict, rrtmg_cloud_liquid_props_dict,
12+
rrtmg_random_number_dict)
1213
import logging
1314
try:
1415
from . import _rrtmg_lw
@@ -166,7 +167,7 @@ def __init__(
166167
cloud_liquid_water_properties='radius_dependent_absorption',
167168
calculate_interface_temperature=True,
168169
mcica=False,
169-
random_number_generator=0,
170+
random_number_generator='mersenne_twister',
170171
**kwargs):
171172
"""
172173
@@ -227,10 +228,10 @@ def __init__(
227228
* mcica = True: use the McICA version of the longwave component of RRTMG
228229
* mcica = False: use the nomcica version of the longwave component of RRTMG
229230
230-
random_number_generator (int):
231+
random_number_generator (string):
231232
Different methods of generating random numbers for McICA.
232-
* random_number_generator = 0: kissvec
233-
* random_number_generator = 1: Mersenne Twister
233+
* :code:`kissvec`
234+
* :code:`mersenne_twister`
234235
235236
.. _[Ebert and Curry 1992]:
236237
http://onlinelibrary.wiley.com/doi/10.1029/91JD02472/abstract
@@ -251,7 +252,8 @@ def __init__(
251252
self._mcica = mcica
252253
if mcica:
253254
self._permute_seed = None
254-
self._random_number_generator = random_number_generator
255+
self._random_number_generator = rrtmg_random_number_dict[
256+
random_number_generator.lower()]
255257
if type(cloud_overlap_method) is str:
256258
if cloud_overlap_method.lower() == 'clear_only':
257259
logging.info(
@@ -368,7 +370,15 @@ def array_call(self, state):
368370
# radiation is called, with the same state / input properties,
369371
# a different result is obtained, because the wavelengths which
370372
# see cloud differ between each call.
371-
self._permute_seed = np.random.randint(0, 500)
373+
if self._random_number_generator == 0:
374+
# KISS algorithm: The seed determines the number of times
375+
# the random number generator is called iteratively to create a
376+
# new random number. The value range of the seed is limited to
377+
# avoid a performance decrease.
378+
self._permute_seed = np.random.randint(0, 1024)
379+
elif self._random_number_generator == 1:
380+
# Mersenne Twister: Use random seed from the full 32bit range.
381+
self._permute_seed = np.random.randint(0, 2**31 - 1)
372382

373383
_rrtmg_lw.initialise_rrtm_radiation_mcica(
374384
self._Cpd,

climt/_components/rrtmg/rrtmg_common.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,13 @@
5353
'ecmwf': 6,
5454
'all_aerosol_properties': 10
5555
}
56+
57+
"""
58+
Dictionary mapping input options of RRTMG radiative
59+
components to integers accepted by the RRTMG fortran
60+
code
61+
"""
62+
rrtmg_random_number_dict = {
63+
'kissvec': 0,
64+
'mersenne_twister': 1
65+
}

climt/_components/rrtmg/sw/component.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
from ..rrtmg_common import (
1111
rrtmg_cloud_overlap_method_dict, rrtmg_cloud_props_dict,
1212
rrtmg_cloud_ice_props_dict, rrtmg_cloud_liquid_props_dict,
13-
rrtmg_aerosol_input_dict)
13+
rrtmg_aerosol_input_dict,
14+
rrtmg_random_number_dict,
15+
)
1416
import logging
1517
try:
1618
from . import _rrtmg_sw
@@ -202,8 +204,8 @@ def __init__(
202204
solar_variability_by_band=None,
203205
aerosol_type='no_aerosol',
204206
mcica=False,
205-
random_number_generator=0,
206-
permute_seed=112, **kwargs):
207+
random_number_generator='mersenne_twister',
208+
**kwargs):
207209
"""
208210
Args:
209211
@@ -312,10 +314,10 @@ def __init__(
312314
* mcica = True: use the McICA version for the shortwave component of RRTMG
313315
* mcica = False: use the nomcica version for the shortwave component of RRTMG
314316
315-
random_number_generator (int):
317+
random_number_generator (string):
316318
Different methods of generating random numbers for McICA.
317-
* random_number_generator = 0: kissvec
318-
* random_number_generator = 1: Mersenne Twister
319+
* :code:`kissvec`
320+
* :code:`mersenne_twister`
319321
320322
.. _[Ebert and Curry 1992]:
321323
http://onlinelibrary.wiley.com/doi/10.1029/91JD02472/abstract
@@ -330,7 +332,8 @@ def __init__(
330332

331333
if mcica:
332334
self._permute_seed = None
333-
self._random_number_generator = random_number_generator # TODO: make dictionary
335+
self._random_number_generator = rrtmg_random_number_dict[
336+
random_number_generator.lower()]
334337
if type(cloud_overlap_method) is str:
335338
if cloud_overlap_method.lower() == 'clear_only':
336339
logging.info(
@@ -502,7 +505,15 @@ def array_call(self, state):
502505
# radiation is called, with the same state / input properties,
503506
# a different result is obtained, because the wavelengths which
504507
# see cloud differ between each call.
505-
self._permute_seed = np.random.randint(0, 500)
508+
if self._random_number_generator == 0:
509+
# KISS algorithm: The seed determines the number of times
510+
# the random number generator is called iteratively to create a
511+
# new random number. The value range of the seed is limited to
512+
# avoid a performance decrease.
513+
self._permute_seed = np.random.randint(0, 1024)
514+
elif self._random_number_generator == 1:
515+
# Mersenne Twister: Use random seed from the full 32bit range.
516+
self._permute_seed = np.random.randint(0, 2**31 - 1)
506517

507518
_rrtmg_sw.initialise_rrtm_radiation_mcica(
508519
self._Cpd,
@@ -515,8 +526,8 @@ def array_call(self, state):
515526
self._liq_props,
516527
self._aerosol_type,
517528
self._solar_var_flag,
518-
self._random_number_generator,
519-
self._permute_seed)
529+
self._permute_seed,
530+
self._random_number_generator)
520531

521532
_rrtmg_sw.rrtm_calculate_shortwave_fluxes_mcica(
522533
self.rrtm_iplon,
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)