forked from ESCOMP/CAM
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathradiation.F90
More file actions
1876 lines (1508 loc) · 81.4 KB
/
Copy pathradiation.F90
File metadata and controls
1876 lines (1508 loc) · 81.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
module radiation
!---------------------------------------------------------------------------------
!
! CAM interface to RRTMGP radiation parameterization.
!
!---------------------------------------------------------------------------------
use shr_kind_mod, only: r8=>shr_kind_r8, cl=>shr_kind_cl
use spmd_utils, only: masterproc
use ppgrid, only: pcols, pver, pverp, begchunk, endchunk
use ref_pres, only: pref_edge
use physics_types, only: physics_state, physics_ptend
use phys_control, only: phys_getopts
use physics_buffer, only: physics_buffer_desc, pbuf_add_field, dtype_r8, pbuf_get_index, &
pbuf_set_field, pbuf_get_field, pbuf_old_tim_idx
use camsrfexch, only: cam_out_t, cam_in_t
use physconst, only: cappa, cpair, gravit, stebol
use time_manager, only: get_nstep, is_first_step, is_first_restart_step, &
get_curr_calday, get_step_size
use radiative_aerosol_definitions, only: N_DIAG, active_calls
use rad_constituents, only: rad_cnst_out
!REMOVECAM
use aerosol_mmr_cam, only: rad_aer_diag_out
!REMOVECAM_END
use radconstants, only: nradgas, gasnamelength, nswbands, nlwbands, &
gaslist, radconstants_init
use cospsimulator_intr, only: docosp, cospsimulator_intr_init, &
cospsimulator_intr_run, cosp_nradsteps
use scamMod, only: scm_crm_mode, single_column, have_cld, cldobs
use cam_history, only: addfld, add_default, horiz_only, outfld, hist_fld_active
use radiation_data, only: rad_data_register, rad_data_init
use ioFileMod, only: getfil
use cam_pio_utils, only: cam_pio_openfile
use pio, only: file_desc_t, var_desc_t, &
pio_int, pio_double, PIO_NOERR, &
pio_seterrorhandling, PIO_BCAST_ERROR, &
pio_inq_dimlen, pio_inq_dimid, pio_inq_varid, &
pio_def_var, pio_put_var, pio_get_var, &
pio_put_att, PIO_NOWRITE, pio_closefile
use ccpp_gas_concentrations, only: ty_gas_concs_ccpp
use ccpp_gas_optics_rrtmgp, only: ty_gas_optics_rrtmgp_ccpp
use ccpp_optical_props, only: ty_optical_props_1scl_ccpp, ty_optical_props_2str_ccpp
use ccpp_source_functions, only: ty_source_func_lw_ccpp
use ccpp_fluxes, only: ty_fluxes_broadband_ccpp
use ccpp_fluxes_byband, only: ty_fluxes_byband_ccpp
use mo_rte_kind, only: wl
use string_utils, only: to_lower
use cam_abortutils, only: endrun, handle_allocate_error
use cam_logfile, only: iulog
use rrtmgp_pre, only: radiation_do_ccpp
implicit none
private
save
public :: &
radiation_readnl, &! read namelist variables
radiation_do, &! query which radiation calcs are done this timestep
radiation_register, &! registers radiation physics buffer fields
radiation_init, &! initialization
radiation_define_restart, &! define variables for restart
radiation_write_restart, &! write variables to restart
radiation_read_restart, &! read variables from restart
radiation_tend, &! compute heating rates and fluxes
rad_out_t ! type for diagnostic outputs
integer,public, allocatable :: cosp_cnt(:) ! counter for cosp
integer,public :: cosp_cnt_init = 0 !initial value for cosp counter
real(r8), public, protected :: nextsw_cday ! future radiation calday for surface models
type rad_out_t
real(r8) :: solin(pcols) ! Solar incident flux
real(r8) :: qrsc(pcols,pver)
real(r8) :: fsnsc(pcols) ! Clear sky surface abs solar flux
real(r8) :: fsntc(pcols) ! Clear sky total column abs solar flux
real(r8) :: fsdsc(pcols) ! Clear sky surface downwelling solar flux
real(r8) :: fsntoa(pcols) ! Net solar flux at TOA
real(r8) :: fsntoac(pcols) ! Clear sky net solar flux at TOA
real(r8) :: fsutoa(pcols) ! upwelling solar flux at TOA
real(r8) :: fsnirt(pcols) ! Near-IR flux absorbed at toa
real(r8) :: fsnrtc(pcols) ! Clear sky near-IR flux absorbed at toa
real(r8) :: fsnirtsq(pcols) ! Near-IR flux absorbed at toa >= 0.7 microns
real(r8) :: fsn200(pcols) ! Net SW flux interpolated to 200 mb
real(r8) :: fsn200c(pcols) ! Net clear-sky SW flux interpolated to 200 mb
real(r8) :: fsnr(pcols) ! Net SW flux interpolated to tropopause
real(r8) :: flux_sw_up(pcols,pverp) ! upward shortwave flux on interfaces
real(r8) :: flux_sw_clr_up(pcols,pverp) ! upward shortwave clearsky flux
real(r8) :: flux_sw_dn(pcols,pverp) ! downward flux
real(r8) :: flux_sw_clr_dn(pcols,pverp) ! downward clearsky flux
real(r8) :: flux_lw_up(pcols,pverp) ! upward longwave flux on interfaces
real(r8) :: flux_lw_clr_up(pcols,pverp) ! upward longwave clearsky flux
real(r8) :: flux_lw_dn(pcols,pverp) ! downward flux
real(r8) :: flux_lw_clr_dn(pcols,pverp) ! downward clearsky flux
real(r8) :: qrlc(pcols,pver)
real(r8) :: flntc(pcols) ! Clear sky lw flux at model top
real(r8) :: flut(pcols) ! Upward flux at top of model
real(r8) :: flutc(pcols) ! Upward Clear Sky flux at top of model
real(r8) :: lwcf(pcols) ! longwave cloud forcing
real(r8) :: fln200(pcols) ! net longwave flux interpolated to 200 mb
real(r8) :: fln200c(pcols) ! net clearsky longwave flux interpolated to 200 mb
real(r8) :: flnr(pcols) ! net longwave flux interpolated to tropopause
real(r8) :: flnsc(pcols) ! Clear sky lw flux at srf (up-down)
real(r8) :: fldsc(pcols) ! Clear sky lw flux at srf (down)
real(r8) :: tot_cld_vistau(pcols,pver) ! gbx water+ice cloud optical depth (only during day, night = fillvalue)
real(r8) :: tot_icld_vistau(pcols,pver) ! in-cld water+ice cloud optical depth (only during day, night = fillvalue)
real(r8) :: liq_icld_vistau(pcols,pver) ! in-cld liq cloud optical depth (only during day, night = fillvalue)
real(r8) :: ice_icld_vistau(pcols,pver) ! in-cld ice cloud optical depth (only during day, night = fillvalue)
real(r8) :: snow_icld_vistau(pcols,pver) ! snow in-cloud visible sw optical depth for output on history files
real(r8) :: grau_icld_vistau(pcols,pver) ! Graupel in-cloud visible sw optical depth for output on history files
end type rad_out_t
! Control variables set via namelist
character(len=cl) :: coefs_lw_file ! filepath for lw coefficients
character(len=cl) :: coefs_sw_file ! filepath for sw coefficients
integer :: iradsw = -1 ! freq. of shortwave radiation calc in time steps (positive)
! or hours (negative).
integer :: iradlw = -1 ! frequency of longwave rad. calc. in time steps (positive)
! or hours (negative).
integer :: irad_always = 0 ! Specifies length of time in timesteps (positive)
! or hours (negative) SW/LW radiation will be
! run continuously from the start of an
! initial or restart run
logical :: use_rad_dt_cosz = .false. ! if true, use radiation dt for all cosz calculations
logical :: spectralflux = .false. ! calculate fluxes (up and down) per band.
logical :: graupel_in_rad = .false. ! graupel in radiation code
logical :: use_rad_uniform_angle = .false. ! if true, use the namelist rad_uniform_angle for the coszrs calculation
! Gathered indices of day and night columns
integer :: nday ! Number of daylight columns
integer :: nnite ! Number of night columns
integer :: idxday(pcols) ! chunk indices of daylight columns
integer :: idxnite(pcols) ! chunk indices of night columns
real(r8) :: coszrs(pcols) ! Cosine solar zenith angle
real(r8) :: eccf ! Earth orbit eccentricity factor
integer :: band2gpt_sw(2,nswbands)
! Physics buffer indices
integer :: qrs_idx = 0
integer :: qrl_idx = 0
integer :: su_idx = 0
integer :: sd_idx = 0
integer :: lu_idx = 0
integer :: ld_idx = 0
integer :: fsds_idx = 0
integer :: fsns_idx = 0
integer :: fsnt_idx = 0
integer :: flns_idx = 0
integer :: flnt_idx = 0
integer :: cld_idx = 0
integer :: cldfsnow_idx = 0
integer :: cldfgrau_idx = 0
integer :: dei_idx
integer :: mu_idx
integer :: lambda_idx
integer :: iciwp_idx
integer :: iclwp_idx
integer :: des_idx
integer :: icswp_idx
integer :: icgrauwp_idx
integer :: degrau_idx
character(len=4) :: diag(0:N_DIAG) =(/' ','_d1 ','_d2 ','_d3 ','_d4 ','_d5 ',&
'_d6 ','_d7 ','_d8 ','_d9 ','_d10'/)
! averaging time interval for zenith angle
real(r8) :: dt_avg = 0._r8
real(r8) :: rad_uniform_angle = -99._r8
! Number of layers in radiation calculations.
integer :: nlay
! Number of interfaces in radiation calculations.
integer :: nlayp
! Number of CAM layers in radiation calculations. Is either equal to nlay, or is
! 1 less than nlay if "extra layer" is used in the radiation calculations.
integer :: nlaycam
! Indices for copying data between CAM/WACCM and RRTMGP arrays. Since RRTMGP is
! vertical order agnostic we can send data using the top to bottom order used
! in CAM/WACCM. But the number of layers that RRTMGP does computations for
! may not match the number of layers in CAM/WACCM for two reasons:
! 1. If the CAM model top is below 1 Pa, then RRTMGP does calculations for an
! extra layer that is added between 1 Pa and the model top.
! 2. If the WACCM model top is above 1 Pa, then RRMTGP only does calculations
! for those model layers that are below 1 Pa.
integer :: ktopcam ! Index in CAM arrays of top level (layer or interface) at which
! RRTMGP is active.
integer :: ktoprad ! Index in RRTMGP arrays of the layer or interface corresponding
! to CAM's top layer or interface.
! Note: for CAM's top to bottom indexing, the index of a given layer
! (midpoint) and the upper interface of that layer, are the same.
integer :: nlwgpts
integer :: nswgpts
integer :: changeseed
integer :: irad_always_modified
real(kind=r8) :: tiny
! Band indices for bands containing specific wavelengths
integer :: idx_sw_diag
integer :: idx_nir_diag
integer :: idx_uv_diag
integer :: idx_sw_cloudsim
integer :: idx_lw_diag
integer :: idx_lw_cloudsim
real(r8) :: sw_low_bounds(nswbands)
real(r8) :: sw_high_bounds(nswbands)
! Flag to perform shortwave or longwave on current timestep
logical :: dosw
logical :: dolw
! Gas optics objects contain the data read from the coefficients files.
type(ty_gas_optics_rrtmgp_ccpp) :: kdist_sw
type(ty_gas_optics_rrtmgp_ccpp) :: kdist_lw
! lower case version of gaslist for RRTMGP
character(len=gasnamelength) :: gaslist_lc(nradgas)
type(var_desc_t) :: cospcnt_desc ! cosp
type(var_desc_t) :: nextsw_cday_desc
! Cloud optical properties TUV-x
integer :: swcldtau_idx = -1 ! shortwave cloud extinction optical depth. tau
integer :: swcldtauw_idx = -1 ! shortwave cloud extinction optical depth * single scattering albedo. tau*w
integer :: swcldtauwg_idx = -1 ! shortwave cloud extinction optical depth * single scattering albedo * asymmetry parameter. tau*w*g
!=========================================================================================
contains
!=========================================================================================
subroutine radiation_readnl(nlfile)
! Read radiation_nl namelist group.
use namelist_utils, only: find_group_name
use spmd_utils, only: mpicom, mstrid=>masterprocid, mpi_integer, mpi_logical, &
mpi_character, mpi_real8
character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input
! Local variables
integer :: unitn, ierr
integer :: dtime ! timestep size
character(len=32) :: errmsg
character(len=*), parameter :: sub = 'radiation_readnl'
character(len=cl) :: rrtmgp_coefs_lw_file, rrtmgp_coefs_sw_file
namelist /radiation_nl/ &
rrtmgp_coefs_lw_file, rrtmgp_coefs_sw_file, iradsw, iradlw, &
irad_always, use_rad_dt_cosz, spectralflux, use_rad_uniform_angle, &
rad_uniform_angle, graupel_in_rad
!-----------------------------------------------------------------------------
if (masterproc) then
open( newunit=unitn, file=trim(nlfile), status='old' )
call find_group_name(unitn, 'radiation_nl', status=ierr)
if (ierr == 0) then
read(unitn, radiation_nl, iostat=ierr, iomsg=errmsg)
if (ierr /= 0) then
call endrun(sub//': ERROR reading namelist: '//trim(errmsg))
end if
end if
close(unitn)
end if
! Broadcast namelist variables
call mpi_bcast(rrtmgp_coefs_lw_file, cl, mpi_character, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: rrtmgp_coefs_lw_file")
call mpi_bcast(rrtmgp_coefs_sw_file, cl, mpi_character, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: rrtmgp_coefs_sw_file")
call mpi_bcast(iradsw, 1, mpi_integer, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: iradsw")
call mpi_bcast(iradlw, 1, mpi_integer, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: iradlw")
call mpi_bcast(irad_always, 1, mpi_integer, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: irad_always")
call mpi_bcast(use_rad_dt_cosz, 1, mpi_logical, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: use_rad_dt_cosz")
call mpi_bcast(spectralflux, 1, mpi_logical, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: spectralflux")
call mpi_bcast(use_rad_uniform_angle, 1, mpi_logical, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: use_rad_uniform_angle")
call mpi_bcast(rad_uniform_angle, 1, mpi_real8, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: rad_uniform_angle")
call mpi_bcast(graupel_in_rad, 1, mpi_logical, mstrid, mpicom, ierr)
if (ierr /= 0) call endrun(sub//": FATAL: mpi_bcast: graupel_in_rad")
if (use_rad_uniform_angle .and. rad_uniform_angle == -99._r8) then
call endrun(sub//': ERROR - use_rad_uniform_angle is set to .true,' &
//' but rad_uniform_angle is not set ')
end if
! Set module data
coefs_lw_file = rrtmgp_coefs_lw_file
coefs_sw_file = rrtmgp_coefs_sw_file
! Convert iradsw, iradlw and irad_always from hours to timesteps if necessary
dtime = get_step_size()
if (iradsw < 0) iradsw = nint((-iradsw *3600._r8)/dtime)
if (iradlw < 0) iradlw = nint((-iradlw *3600._r8)/dtime)
if (irad_always < 0) irad_always = nint((-irad_always*3600._r8)/dtime)
!-----------------------------------------------------------------------
! Print runtime options to log.
!-----------------------------------------------------------------------
if (masterproc) then
write(iulog,*) 'RRTMGP radiation scheme parameters:'
write(iulog,10) trim(coefs_lw_file), trim(coefs_sw_file), nlwbands, nswbands, &
iradsw, iradlw, irad_always, use_rad_dt_cosz, spectralflux, graupel_in_rad
end if
10 format(' LW coefficents file: ', a/, &
' SW coefficents file: ', a/, &
' Number of LW bands: ',i5/, &
' Number of SW bands: ',i5/, &
' Frequency (timesteps) of Shortwave Radiation calc: ',i5/, &
' Frequency (timesteps) of Longwave Radiation calc: ',i5/, &
' SW/LW calc done every timestep for first N steps. N=',i5/, &
' Use average zenith angle: ',l5/, &
' Output spectrally resolved fluxes: ',l5/, &
' Graupel in Radiation Code: ',l5/)
end subroutine radiation_readnl
!================================================================================================
subroutine radiation_register
use rrtmgp_pre, only: rrtmgp_pre_init
use rrtmgp_inputs_setup, only: rrtmgp_inputs_setup_init
use rrtmgp_lw_gas_optics, only: rrtmgp_lw_gas_optics_init
use rrtmgp_sw_gas_optics, only: rrtmgp_sw_gas_optics_init
use radheat, only: p_top_for_equil_rad
! local variables
character(len=512) :: errmsg
! names of gases that are available in the model
! -- needed for the kdist initialization routines
type(ty_gas_concs_ccpp) :: available_gases
integer :: errflg
integer :: dtime
real(r8) :: dtime_r8
character(len=*), parameter :: sub = 'radiation_register'
real(r8) :: qrl_unused(1,1)
! Register radiation fields in the physics buffer
call pbuf_add_field('QRS' , 'global',dtype_r8,(/pcols,pver/), qrs_idx) ! shortwave radiative heating rate
call pbuf_add_field('QRL' , 'global',dtype_r8,(/pcols,pver/), qrl_idx) ! longwave radiative heating rate
call pbuf_add_field('FSDS' , 'global',dtype_r8,(/pcols/), fsds_idx) ! Surface solar downward flux
call pbuf_add_field('FSNS' , 'global',dtype_r8,(/pcols/), fsns_idx) ! Surface net shortwave flux
call pbuf_add_field('FSNT' , 'global',dtype_r8,(/pcols/), fsnt_idx) ! Top-of-model net shortwave flux
call pbuf_add_field('FLNS' , 'global',dtype_r8,(/pcols/), flns_idx) ! Surface net longwave flux
call pbuf_add_field('FLNT' , 'global',dtype_r8,(/pcols/), flnt_idx) ! Top-of-model net longwave flux
! If the namelist has been configured for preserving the spectral fluxes, then create
! physics buffer variables to store the results. This data is accessed by CARMA.
if (spectralflux) then
call pbuf_add_field('SU' , 'global',dtype_r8,(/pcols,pverp,nswbands/), su_idx) ! shortwave upward flux (per band)
call pbuf_add_field('SD' , 'global',dtype_r8,(/pcols,pverp,nswbands/), sd_idx) ! shortwave downward flux (per band)
call pbuf_add_field('LU' , 'global',dtype_r8,(/pcols,pverp,nlwbands/), lu_idx) ! longwave upward flux (per band)
call pbuf_add_field('LD' , 'global',dtype_r8,(/pcols,pverp,nlwbands/), ld_idx) ! longwave downward flux (per band)
end if
! Register fields for offline radiation driver.
call rad_data_register()
! Initialize available_gases object
call rrtmgp_pre_init(nradgas, available_gases, gaslist, gaslist_lc, errmsg, errflg)
if (errflg /= 0) then
call endrun(sub//': '//errmsg)
end if
! Read RRTMGP coefficients files and initialize kdist objects.
call rrtmgp_lw_gas_optics_init(coefs_lw_file, available_gases, kdist_lw, errmsg, errflg)
if (errflg /= 0) then
call endrun(sub//': lw '//errmsg)
end if
call rrtmgp_sw_gas_optics_init(coefs_sw_file, available_gases, kdist_sw, errmsg, errflg)
if (errflg /= 0) then
call endrun(sub//': sw '//errmsg)
end if
dtime = get_step_size()
dtime_r8 = real(dtime, r8)
! Set up inputs to RRTMGP
call rrtmgp_inputs_setup_init(nswbands, nlwbands, pref_edge, pver, pverp, kdist_sw, kdist_lw, qrl_unused, &
is_first_step(), use_rad_dt_cosz, dtime_r8, get_nstep(), iradsw, dt_avg, irad_always, &
is_first_restart_step(), p_top_for_equil_rad, nradgas, gasnamelength, get_curr_calday(), &
ktopcam, ktoprad, nlaycam, sw_low_bounds, sw_high_bounds, idx_sw_diag, idx_nir_diag, &
idx_uv_diag, idx_sw_cloudsim, idx_lw_diag, idx_lw_cloudsim, nswgpts, nlwgpts, changeseed, &
nlay, nlayp, nextsw_cday, band2gpt_sw, irad_always_modified, errmsg, errflg)
if (errflg /= 0) then
call endrun(sub//': '//errmsg)
end if
end subroutine radiation_register
!================================================================================================
function radiation_do(op)
! Return true if the specified operation is done this timestep.
character(len=*), intent(in) :: op ! name of operation
logical :: radiation_do ! return value
! Local variables
integer :: nstep ! current timestep number
integer :: errcode
character(len=512) :: errmsg
!-----------------------------------------------------------------------
nstep = get_nstep()
select case (op)
case ('sw') ! Set radiation_do to true if doing a shortwave heating calc this timestep
call radiation_do_ccpp(op, nstep, iradsw, irad_always, radiation_do, errmsg, errcode)
case ('lw') ! Set radiation_do to true if doing a longwave heating calc this timestep
call radiation_do_ccpp(op, nstep, iradlw, irad_always, radiation_do, errmsg, errcode)
case default
call endrun('radiation_do: unknown operation:'//op)
end select
end function radiation_do
!================================================================================================
subroutine radiation_init(pbuf2d)
use rrtmgp_inputs_cam, only: rrtmgp_inputs_cam_init
use rrtmgp_cloud_optics_setup, only: rrtmgp_cloud_optics_setup_init
use rrtmgp_sw_solar_var_setup, only: rrtmgp_sw_solar_var_setup_init
use solar_irrad_data, only: do_spctrl_scaling, has_spectrum
use cloud_rad_props, only: cloud_rad_props_init
! Initialize the radiation and cloud optics.
! Add fields to the history buffer.
! arguments
type(physics_buffer_desc), pointer :: pbuf2d(:,:)
! local variables
character(len=512) :: errmsg
integer :: i, icall
logical :: history_amwg ! output the variables used by the AMWG diag package
logical :: history_vdiag ! output the variables used by the AMWG variability diag package
logical :: history_budget ! output tendencies and state variables for CAM4
! temperature, water vapor, cloud ice and cloud
! liquid budgets.
integer :: history_budget_histfile_num ! history file number for budget fields
integer :: ierr, istat, errflg
character(len=*), parameter :: sub = 'radiation_init'
!-----------------------------------------------------------------------
! Lookup pbuf flds for TUV-x aerosol optics
call rrtmgp_inputs_cam_init()
! Set radconstants module-level index variables that we're setting in CCPP-ized scheme now
call radconstants_init(idx_sw_diag, idx_nir_diag, idx_uv_diag, idx_lw_diag)
call rrtmgp_sw_solar_var_setup_init(nswbands, do_spctrl_scaling, has_spectrum, errmsg, errflg)
if (errflg /= 0) then
call endrun(sub//': '//errmsg)
end if
! initialize output fields for offline driver
call rad_data_init(pbuf2d)
! Read ice and liquid optics files
call cloud_rad_props_init(tiny)
if (errflg /= 0) then
call endrun(sub//': '//errmsg)
end if
cld_idx = pbuf_get_index('CLD')
cldfsnow_idx = pbuf_get_index('CLDFSNOW', errcode=ierr)
cldfgrau_idx = pbuf_get_index('CLDFGRAU', errcode=ierr)
if (is_first_step()) then
call pbuf_set_field(pbuf2d, qrl_idx, 0._r8)
end if
call phys_getopts(history_amwg_out = history_amwg, &
history_vdiag_out = history_vdiag, &
history_budget_out = history_budget, &
history_budget_histfile_num_out = history_budget_histfile_num)
if (docosp) call cospsimulator_intr_init()
allocate(cosp_cnt(begchunk:endchunk), stat=istat)
call handle_allocate_error(istat, sub, 'cosp_cnt')
if (is_first_restart_step()) then
cosp_cnt(begchunk:endchunk) = cosp_cnt_init
else
cosp_cnt(begchunk:endchunk) = 0
end if
! Add fields to history buffer
call addfld('TOT_CLD_VISTAU', (/ 'lev' /), 'A', '1', &
'Total gbx cloud extinction visible sw optical depth', &
sampling_seq='rad_lwsw', flag_xyfill=.true.)
call addfld('TOT_ICLD_VISTAU', (/ 'lev' /), 'A', '1', &
'Total in-cloud extinction visible sw optical depth', &
sampling_seq='rad_lwsw', flag_xyfill=.true.)
call addfld('LIQ_ICLD_VISTAU', (/ 'lev' /), 'A', '1', &
'Liquid in-cloud extinction visible sw optical depth', &
sampling_seq='rad_lwsw', flag_xyfill=.true.)
call addfld('ICE_ICLD_VISTAU', (/ 'lev' /), 'A', '1', &
'Ice in-cloud extinction visible sw optical depth', &
sampling_seq='rad_lwsw', flag_xyfill=.true.)
if (cldfsnow_idx > 0) then
call addfld('SNOW_ICLD_VISTAU', (/ 'lev' /), 'A', '1', &
'Snow in-cloud extinction visible sw optical depth', &
sampling_seq='rad_lwsw', flag_xyfill=.true.)
end if
if (cldfgrau_idx > 0 .and. graupel_in_rad) then
call addfld('GRAU_ICLD_VISTAU', (/ 'lev' /), 'A', '1', &
'Graupel in-cloud extinction visible sw optical depth', &
sampling_seq='rad_lwsw', flag_xyfill=.true.)
endif
! Add shortwave radiation fields to history master field list.
do icall = 0, N_DIAG
if (active_calls(icall)) then
call addfld('SOLIN'//diag(icall), horiz_only, 'A', 'W/m2', &
'Solar insolation', sampling_seq='rad_lwsw')
call addfld('QRS'//diag(icall), (/ 'lev' /), 'A', 'K/s', &
'Solar heating rate', sampling_seq='rad_lwsw')
call addfld('QRSC'//diag(icall), (/ 'lev' /), 'A', 'K/s', &
'Clearsky solar heating rate', sampling_seq='rad_lwsw')
call addfld('FSNT'//diag(icall), horiz_only, 'A', 'W/m2', &
'Net solar flux at top of model', sampling_seq='rad_lwsw')
call addfld('FSNTC'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky net solar flux at top of model', sampling_seq='rad_lwsw')
call addfld('FSNTOA'//diag(icall), horiz_only, 'A', 'W/m2', &
'Net solar flux at top of atmosphere', sampling_seq='rad_lwsw')
call addfld('FSNTOAC'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky net solar flux at top of atmosphere', sampling_seq='rad_lwsw')
call addfld('SWCF'//diag(icall), horiz_only, 'A', 'W/m2', &
'Shortwave cloud forcing', sampling_seq='rad_lwsw')
call addfld('FSUTOA'//diag(icall), horiz_only, 'A', 'W/m2', &
'Upwelling solar flux at top of atmosphere', sampling_seq='rad_lwsw')
call addfld('FSN200'//diag(icall), horiz_only, 'A', 'W/m2', &
'Net shortwave flux at 200 mb', sampling_seq='rad_lwsw')
call addfld('FSN200C'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky net shortwave flux at 200 mb', sampling_seq='rad_lwsw')
call addfld('FSNR'//diag(icall), horiz_only, 'A', 'W/m2', &
'Net solar flux at tropopause', sampling_seq='rad_lwsw')
call addfld('SOLL'//diag(icall), horiz_only, 'A', 'W/m2', &
'Solar downward near infrared direct to surface', sampling_seq='rad_lwsw')
call addfld('SOLS'//diag(icall), horiz_only, 'A', 'W/m2', &
'Solar downward visible direct to surface', sampling_seq='rad_lwsw')
call addfld('SOLLD'//diag(icall), horiz_only, 'A', 'W/m2', &
'Solar downward near infrared diffuse to surface', sampling_seq='rad_lwsw')
call addfld('SOLSD'//diag(icall), horiz_only, 'A', 'W/m2', &
'Solar downward visible diffuse to surface', sampling_seq='rad_lwsw')
call addfld('FSNS'//diag(icall), horiz_only, 'A', 'W/m2', &
'Net solar flux at surface', sampling_seq='rad_lwsw')
call addfld('FSNSC'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky net solar flux at surface', sampling_seq='rad_lwsw')
call addfld('FSDS'//diag(icall), horiz_only, 'A', 'W/m2', &
'Downwelling solar flux at surface', sampling_seq='rad_lwsw')
call addfld('FSDSC'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky downwelling solar flux at surface', sampling_seq='rad_lwsw')
! Fluxes on CAM grid
call addfld('FUS'//diag(icall), (/ 'ilev' /), 'I', 'W/m2', &
'Shortwave upward flux', sampling_seq='rad_lwsw')
call addfld('FDS'//diag(icall), (/ 'ilev' /), 'I', 'W/m2', &
'Shortwave downward flux', sampling_seq='rad_lwsw')
call addfld('FUSC'//diag(icall), (/ 'ilev' /), 'I', 'W/m2', &
'Shortwave clear-sky upward flux', sampling_seq='rad_lwsw')
call addfld('FDSC'//diag(icall), (/ 'ilev' /), 'I', 'W/m2', &
'Shortwave clear-sky downward flux', sampling_seq='rad_lwsw')
if (history_amwg) then
call add_default('SOLIN'//diag(icall), 1, ' ')
call add_default('QRS'//diag(icall), 1, ' ')
call add_default('FSNT'//diag(icall), 1, ' ')
call add_default('FSNTC'//diag(icall), 1, ' ')
call add_default('FSNTOA'//diag(icall), 1, ' ')
call add_default('FSNTOAC'//diag(icall), 1, ' ')
call add_default('SWCF'//diag(icall), 1, ' ')
call add_default('FSNS'//diag(icall), 1, ' ')
call add_default('FSNSC'//diag(icall), 1, ' ')
call add_default('FSUTOA'//diag(icall), 1, ' ')
call add_default('FSDSC'//diag(icall), 1, ' ')
call add_default('FSDS'//diag(icall), 1, ' ')
endif
end if
end do
if (scm_crm_mode) then
call add_default('FUS ', 1, ' ')
call add_default('FUSC ', 1, ' ')
call add_default('FDS ', 1, ' ')
call add_default('FDSC ', 1, ' ')
endif
! Add longwave radiation fields to history master field list.
do icall = 0, N_DIAG
if (active_calls(icall)) then
call addfld('QRL'//diag(icall), (/ 'lev' /), 'A', 'K/s', &
'Longwave heating rate', sampling_seq='rad_lwsw')
call addfld('QRLC'//diag(icall), (/ 'lev' /), 'A', 'K/s', &
'Clearsky longwave heating rate', sampling_seq='rad_lwsw')
call addfld('FLNT'//diag(icall), horiz_only, 'A', 'W/m2', &
'Net longwave flux at top of model', sampling_seq='rad_lwsw')
call addfld('FLNTC'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky net longwave flux at top of model', sampling_seq='rad_lwsw')
call addfld('FLUT'//diag(icall), horiz_only, 'A', 'W/m2', &
'Upwelling longwave flux at top of model', sampling_seq='rad_lwsw')
call addfld('FLUTC'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky upwelling longwave flux at top of model', sampling_seq='rad_lwsw')
call addfld('LWCF'//diag(icall), horiz_only, 'A', 'W/m2', &
'Longwave cloud forcing', sampling_seq='rad_lwsw')
call addfld('FLN200'//diag(icall), horiz_only, 'A', 'W/m2', &
'Net longwave flux at 200 mb', sampling_seq='rad_lwsw')
call addfld('FLN200C'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky net longwave flux at 200 mb', sampling_seq='rad_lwsw')
call addfld('FLNR'//diag(icall), horiz_only, 'A', 'W/m2', &
'Net longwave flux at tropopause', sampling_seq='rad_lwsw')
call addfld('FLNS'//diag(icall), horiz_only, 'A', 'W/m2', &
'Net longwave flux at surface', sampling_seq='rad_lwsw')
call addfld('FLNSC'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky net longwave flux at surface', sampling_seq='rad_lwsw')
call addfld('FLDS'//diag(icall), horiz_only, 'A', 'W/m2', &
'Downwelling longwave flux at surface', sampling_seq='rad_lwsw')
call addfld('FLDSC'//diag(icall), horiz_only, 'A', 'W/m2', &
'Clearsky Downwelling longwave flux at surface', sampling_seq='rad_lwsw')
! Fluxes on CAM grid
call addfld('FUL'//diag(icall), (/ 'ilev' /), 'I', 'W/m2', &
'Longwave upward flux', sampling_seq='rad_lwsw')
call addfld('FDL'//diag(icall), (/ 'ilev' /), 'I', 'W/m2', &
'Longwave downward flux', sampling_seq='rad_lwsw')
call addfld('FULC'//diag(icall), (/ 'ilev' /), 'I', 'W/m2', &
'Longwave clear-sky upward flux', sampling_seq='rad_lwsw')
call addfld('FDLC'//diag(icall), (/ 'ilev' /), 'I', 'W/m2', &
'Longwave clear-sky downward flux', sampling_seq='rad_lwsw')
if (history_amwg) then
call add_default('QRL'//diag(icall), 1, ' ')
call add_default('FLNT'//diag(icall), 1, ' ')
call add_default('FLNTC'//diag(icall), 1, ' ')
call add_default('FLUT'//diag(icall), 1, ' ')
call add_default('FLUTC'//diag(icall), 1, ' ')
call add_default('LWCF'//diag(icall), 1, ' ')
call add_default('FLNS'//diag(icall), 1, ' ')
call add_default('FLNSC'//diag(icall), 1, ' ')
call add_default('FLDS'//diag(icall), 1, ' ')
end if
end if
end do
call addfld('EMIS', (/ 'lev' /), 'A', '1', 'Cloud longwave emissivity')
if (scm_crm_mode) then
call add_default ('FUL ', 1, ' ')
call add_default ('FULC ', 1, ' ')
call add_default ('FDL ', 1, ' ')
call add_default ('FDLC ', 1, ' ')
endif
! Heating rate needed for d(theta)/dt computation
call addfld ('HR',(/ 'lev' /), 'A','K/s','Heating rate needed for d(theta)/dt computation')
if ( history_budget .and. history_budget_histfile_num > 1 ) then
call add_default ('QRL ', history_budget_histfile_num, ' ')
call add_default ('QRS ', history_budget_histfile_num, ' ')
end if
if (history_vdiag) then
call add_default('FLUT', 2, ' ')
call add_default('FLUT', 3, ' ')
end if
! get the clouds optical properties from radiation code
swcldtau_idx = pbuf_get_index('SWCLDTAU', errcode=ierr)
swcldtauw_idx = pbuf_get_index('SWCLDTAUW', errcode=ierr)
swcldtauwg_idx = pbuf_get_index('SWCLDTAUWG', errcode=ierr)
end subroutine radiation_init
!===============================================================================
subroutine radiation_define_restart(file)
! define variables to be written to restart file
! arguments
type(file_desc_t), intent(inout) :: file
! local variables
integer :: ierr
!----------------------------------------------------------------------------
call pio_seterrorhandling(file, PIO_BCAST_ERROR)
ierr = pio_def_var(file, 'nextsw_cday', pio_double, nextsw_cday_desc)
ierr = pio_put_att(file, nextsw_cday_desc, 'long_name', 'future radiation calday for surface models')
if (docosp) then
ierr = pio_def_var(File, 'cosp_cnt_init', pio_int, cospcnt_desc)
end if
end subroutine radiation_define_restart
!===============================================================================
subroutine radiation_write_restart(file)
! write variables to restart file
! arguments
type(file_desc_t), intent(inout) :: file
! local variables
integer :: ierr
!----------------------------------------------------------------------------
ierr = pio_put_var(File, nextsw_cday_desc, (/ nextsw_cday /))
if (docosp) then
ierr = pio_put_var(File, cospcnt_desc, (/cosp_cnt(begchunk)/))
end if
end subroutine radiation_write_restart
!===============================================================================
subroutine radiation_read_restart(file)
! read variables from restart file
! arguments
type(file_desc_t), intent(inout) :: file
! local variables
integer :: ierr
type(var_desc_t) :: vardesc
integer :: err_handling
!----------------------------------------------------------------------------
if (docosp) then
call pio_seterrorhandling(File, PIO_BCAST_ERROR, err_handling)
ierr = pio_inq_varid(File, 'cosp_cnt_init', vardesc)
call pio_seterrorhandling(File, err_handling)
if (ierr /= PIO_NOERR) then
cosp_cnt_init = 0
else
ierr = pio_get_var(File, vardesc, cosp_cnt_init)
end if
end if
ierr = pio_inq_varid(file, 'nextsw_cday', vardesc)
ierr = pio_get_var(file, vardesc, nextsw_cday)
end subroutine radiation_read_restart
!===============================================================================
subroutine radiation_tend( &
state, ptend, pbuf, cam_out, cam_in, net_flx, rd_out)
!-----------------------------------------------------------------------
!
! CAM driver for radiation computation.
!
!-----------------------------------------------------------------------
! Location/Orbital Parameters for cosine zenith angle
use phys_grid, only: get_rlat_all_p, get_rlon_all_p
use cam_control_mod, only: eccen, mvelpp, lambm0, obliqr
use shr_orb_mod, only: shr_orb_decl, shr_orb_cosz
! CCPPized schemes
use rrtmgp_inputs, only: rrtmgp_inputs_run
use rrtmgp_pre, only: rrtmgp_pre_run, rrtmgp_pre_timestep_init
use rrtmgp_lw_cloud_optics, only: rrtmgp_lw_cloud_optics_run
use rrtmgp_lw_mcica_subcol_gen, only: rrtmgp_lw_mcica_subcol_gen_run
use rrtmgp_lw_gas_optics_pre, only: rrtmgp_lw_gas_optics_pre_run
use rrtmgp_lw_gas_optics, only: rrtmgp_lw_gas_optics_run
use rrtmgp_lw_rte, only: rrtmgp_lw_rte_run
use rrtmgp_dry_static_energy_tendency, only: rrtmgp_dry_static_energy_tendency_run
use rrtmgp_post, only: rrtmgp_post_run
use rrtmgp_sw_solar_var, only: rrtmgp_sw_solar_var_run
use rrtmgp_sw_mcica_subcol_gen, only: rrtmgp_sw_mcica_subcol_gen_run
use rrtmgp_sw_cloud_optics, only: rrtmgp_sw_cloud_optics_run
use rrtmgp_sw_gas_optics_pre, only: rrtmgp_sw_gas_optics_pre_run
use rrtmgp_sw_gas_optics, only: rrtmgp_sw_gas_optics_run
use rrtmgp_sw_rte, only: rrtmgp_sw_rte_run
use rrtmgp_inputs_cam, only: rrtmgp_get_gas_mmrs, rrtmgp_set_aer_lw, &
rrtmgp_set_aer_sw
! RRTMGP drivers for flux calculations.
use mo_rte_lw, only: rte_lw
use mo_rte_sw, only: rte_sw
use radheat, only: radheat_tend
use radiation_data, only: rad_data_write
use solar_irrad_data, only: sol_irrad, we, nbins, sol_tsi, do_spctrl_scaling
use interpolate_data, only: vertinterp
use tropopause, only: tropopause_find_cam, TROP_ALG_HYBSTOB, TROP_ALG_CLIMATE
use cospsimulator_intr, only: docosp, cospsimulator_intr_run, cosp_nradsteps
use cam_history_support, only: fillvalue
use dycore, only: dycore_is
! Arguments
type(physics_state), intent(in), target :: state
type(physics_ptend), intent(out) :: ptend
type(physics_buffer_desc), pointer :: pbuf(:)
type(cam_out_t), intent(inout) :: cam_out
type(cam_in_t), intent(in) :: cam_in
real(r8), intent(out) :: net_flx(pcols)
type(rad_out_t), target, optional, intent(out) :: rd_out
! Local variables
type(rad_out_t), pointer :: rd ! allow rd_out to be optional by allocating a local object
! if the argument is not present
logical :: write_output
integer :: i, k, gas_idx, istat
integer :: lchnk, ncol
logical :: dosw, dolw
integer :: icall ! loop index for climate/diagnostic radiation calls
real(r8) :: calday ! current calendar day
real(r8) :: delta ! Solar declination angle in radians
real(r8) :: eccf ! Earth orbit eccentricity factor
real(r8) :: clat(pcols) ! current latitudes(radians)
real(r8) :: clon(pcols) ! current longitudes(radians)
real(r8) :: coszrs(pcols) ! Cosine solar zenith angle
integer :: itim_old
integer :: nextsw_nstep
integer :: offset
real(r8) :: next_cday
real(r8), pointer :: cld(:,:) ! cloud fraction
real(r8), pointer :: cldfsnow(:,:) ! cloud fraction of just "snow clouds"
real(r8), pointer :: cldfgrau(:,:) ! cloud fraction of just "graupel clouds"
real(r8), pointer :: cldfsnow_in(:,:) ! Cloud fraction of just "snow clouds", subset
real(r8), pointer :: cldfgrau_in(:,:) ! Cloud fraction of just "graupel clouds", subset
real(r8) :: cldfprime(pcols,pver) ! combined cloud fraction
real(r8) :: cld_lw_abs(nlwbands,state%ncol,pver) ! Cloud absorption optics depth
real(r8) :: snow_lw_abs(nlwbands,state%ncol,pver) ! Snow absorption optics depth
real(r8) :: grau_lw_abs(nlwbands,state%ncol,pver) ! Graupel absorption optics depth
real(r8) :: c_cld_lw_abs(nlwbands,state%ncol,pver)
real(r8) :: cld_tau(nswbands,state%ncol,pver) ! Cloud absorption optical depth (sw)
real(r8) :: snow_tau(nswbands,state%ncol,pver) ! Snow absorption optical depth (sw)
real(r8) :: grau_tau(nswbands,state%ncol,pver) ! Graupel absorption optical depth (sw)
real(r8) :: c_cld_tau(nswbands,state%ncol,pver)
real(r8) :: c_cld_tau_w(nswbands,state%ncol,pver)
real(r8) :: c_cld_tau_w_g(nswbands,state%ncol,pver)
real(r8), pointer :: qrs(:,:) ! shortwave radiative heating rate adjusted by air pressure thickness
real(r8), pointer :: qrl(:,:) ! longwave radiative heating rate adjusted by air pressure thickness
real(r8) :: qrs_prime(pcols, pver) ! shortwave heating rate
real(r8) :: qrl_prime(pcols, pver) ! longwave heating rate
real(r8), pointer :: fsds(:) ! Surface solar down flux
real(r8), pointer :: fsns(:) ! Surface solar absorbed flux
real(r8), pointer :: fsnt(:) ! Net column abs solar flux at model top
real(r8), pointer :: flns(:) ! Srf longwave cooling (up-down) flux
real(r8), pointer :: flnt(:) ! Net outgoing lw flux at model top
real(r8), pointer :: dei(:,:)
real(r8), pointer :: mu(:,:)
real(r8), pointer :: lambda(:,:)
real(r8), pointer :: iciwp(:,:)
real(r8), pointer :: iclwp(:,:)
real(r8), pointer :: des(:,:)
real(r8), pointer :: icswp(:,:)
real(r8), pointer :: icgrauwp(:,:)
real(r8), pointer :: degrau(:,:)
real(r8), pointer :: icgrauwp_in(:,:)
real(r8), pointer :: degrau_in(:,:)
real(r8), pointer, dimension(:,:,:) :: su => NULL() ! shortwave spectral flux up
real(r8), pointer, dimension(:,:,:) :: sd => NULL() ! shortwave spectral flux down
real(r8), pointer, dimension(:,:,:) :: lu => NULL() ! longwave spectral flux up
real(r8), pointer, dimension(:,:,:) :: ld => NULL() ! longwave spectral flux down
! tropopause diagnostic
integer :: troplev(pcols)
real(r8) :: p_trop(pcols)
! state data passed to radiation calc
real(r8), allocatable :: t_sfc(:)
real(r8), allocatable :: emis_sfc(:,:)
real(r8), allocatable :: t_rad(:,:)
real(r8), allocatable :: pmid_rad(:,:)
real(r8), allocatable :: pint_rad(:,:)
real(r8), allocatable :: t_day(:,:)
real(r8), allocatable :: pmid_day(:,:)
real(r8), allocatable :: pint_day(:,:)
real(r8), allocatable :: coszrs_day(:)
real(r8), allocatable :: alb_dir(:,:)
real(r8), allocatable :: alb_dif(:,:)
real(r8), allocatable :: tauc(:,:,:)
real(r8), allocatable :: cldf(:,:)
real(r8), allocatable :: gas_mmrs(:,:,:)
! in-cloud optical depths for COSP
real(r8) :: cld_tau_cloudsim(pcols,pver) ! liq + ice
real(r8) :: snow_tau_cloudsim(pcols,pver) ! snow
real(r8) :: grau_tau_cloudsim(pcols,pver) ! graupel
real(r8) :: cld_lw_abs_cloudsim(pcols,pver) ! liq + ice
real(r8) :: snow_lw_abs_cloudsim(pcols,pver)! snow
real(r8) :: grau_lw_abs_cloudsim(pcols,pver)! graupel
logical :: do_graupel, do_snow
! TOA solar flux on RRTMGP g-points
real(r8), allocatable :: toa_flux(:,:)
! Scale factors based on spectral distribution from input irradiance dataset
real(r8), allocatable :: sfac(:,:)
! Planck sources for LW.
type(ty_source_func_lw_ccpp) :: sources_lw
! Gas volume mixing ratios. Use separate objects for LW and SW because SW only does
! calculations for daylight columns.
! These objects have a final method which deallocates the internal memory when they
! go out of scope (i.e., when radiation_tend returns), so no need for explicit deallocation.
type(ty_gas_concs_ccpp) :: gas_concs_lw
type(ty_gas_concs_ccpp) :: gas_concs_sw
! Atmosphere optics. This object is initialized with gas optics, then is incremented
! by the aerosol optics for the clear-sky radiative flux calculations, and then
! incremented again by the cloud optics for the all-sky radiative flux calculations.
type(ty_optical_props_1scl_ccpp) :: atm_optics_lw
type(ty_optical_props_2str_ccpp) :: atm_optics_sw
! Cloud optical properties objects (McICA sampling of cloud optical properties).
type(ty_optical_props_1scl_ccpp) :: cloud_lw
type(ty_optical_props_2str_ccpp) :: cloud_sw
! Aerosol optical properties objects.
type(ty_optical_props_1scl_ccpp) :: aer_lw
type(ty_optical_props_2str_ccpp) :: aer_sw
! Flux objects contain all fluxes computed by RRTMGP.
! SW allsky fluxes always include spectrally resolved fluxes needed for surface models.
type(ty_fluxes_byband_ccpp) :: fsw
! LW allsky fluxes only need spectrally resolved fluxes when spectralflux=.true.
type(ty_fluxes_byband_ccpp) :: flw
! Only broadband fluxes needed for clear sky (diagnostics).
type(ty_fluxes_broadband_ccpp) :: fswc, flwc