-
Notifications
You must be signed in to change notification settings - Fork 181
Expand file tree
/
Copy pathmacrop_driver.F90
More file actions
1191 lines (973 loc) · 54.4 KB
/
Copy pathmacrop_driver.F90
File metadata and controls
1191 lines (973 loc) · 54.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 macrop_driver
!-------------------------------------------------------------------------------------------------------
! Purpose:
!
! Provides the CAM interface to the prognostic cloud macrophysics
!
! Author: Andrew Gettelman, Cheryl Craig October 2010
! Origin: modified from stratiform.F90 elements
! (Boville 2002, Coleman 2004, Park 2009, Kay 2010)
!-------------------------------------------------------------------------------------------------------
use shr_kind_mod, only: r8=>shr_kind_r8
use spmd_utils, only: masterproc
use ppgrid, only: pcols, pver, pverp
use physconst, only: latice, latvap
use phys_control, only: phys_getopts
use constituents, only: cnst_get_ind, pcnst
use physics_buffer, only: physics_buffer_desc, pbuf_set_field, pbuf_get_field, pbuf_old_tim_idx
use time_manager, only: is_first_step
use cldwat2m_macro, only: ini_macro
use perf_mod, only: t_startf, t_stopf
use cam_logfile, only: iulog
use cam_abortutils, only: endrun
implicit none
private
save
public :: macrop_driver_readnl
public :: macrop_driver_register
public :: macrop_driver_init
public :: macrop_driver_tend
public :: liquid_macro_tend
logical, public :: do_cldice ! .true., park macrophysics is prognosing cldice
logical, public :: do_cldliq ! .true., park macrophysics is prognosing cldliq
logical, public :: do_detrain ! .true., park macrophysics is detraining ice into stratiform
! ------------------------- !
! Private Module Parameters !
! ------------------------- !
! 'cu_det_st' : If .true. (.false.), detrain cumulus liquid condensate into the pre-existing liquid stratus
! (environment) without (with) macrophysical evaporation. If there is no pre-esisting stratus,
! evaporate cumulus liquid condensate. This option only influences the treatment of cumulus
! liquid condensate, not cumulus ice condensate.
logical, parameter :: cu_det_st = .false.
! Parameters used for selecting generalized critical RH for liquid and ice stratus
integer :: rhminl_opt = 0
integer :: rhmini_opt = 0
character(len=16) :: shallow_scheme
logical :: use_shfrc ! Local copy of flag from convect_shallow_use_shfrc
integer :: &
ixcldliq, &! cloud liquid amount index
ixcldice, &! cloud ice amount index
ixnumliq, &! cloud liquid number index
ixnumice, &! cloud ice water index
qcwat_idx, &! qcwat index in physics buffer
lcwat_idx, &! lcwat index in physics buffer
iccwat_idx, &! iccwat index in physics buffer
nlwat_idx, &! nlwat index in physics buffer
niwat_idx, &! niwat index in physics buffer
tcwat_idx, &! tcwat index in physics buffer
CC_T_idx, &!
CC_qv_idx, &!
CC_ql_idx, &!
CC_qi_idx, &!
CC_nl_idx, &!
CC_ni_idx, &!
CC_qlst_idx, &!
cld_idx, &! cld index in physics buffer
ast_idx, &! stratiform cloud fraction index in physics buffer
aist_idx, &! ice stratiform cloud fraction index in physics buffer
alst_idx, &! liquid stratiform cloud fraction index in physics buffer
qist_idx, &! ice stratiform in-cloud IWC
qlst_idx, &! liquid stratiform in-cloud LWC
concld_idx, &! concld index in physics buffer
fice_idx, &
cmeliq_idx, &
shfrc_idx
! Physics buffer indices for convective_cloud_cover
integer :: sh_frac_idx = 0
integer :: dp_frac_idx = 0
integer :: &
dlfzm_idx = -1, & ! ZM detrained convective cloud water mixing ratio.
dnlfzm_idx = -1, & ! ZM detrained convective cloud water num concen.
dnifzm_idx = -1 ! ZM detrained convective cloud ice num concen.
integer :: &
cmfmc_sh_idx = -1
contains
! ===============================================================================
subroutine macrop_driver_readnl(nlfile)
use namelist_utils, only: find_group_name
use units, only: getunit, freeunit
use mpishorthand
character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input
! Namelist variables
logical :: macro_park_do_cldice = .true. ! do_cldice = .true., park macrophysics is prognosing cldice
logical :: macro_park_do_cldliq = .true. ! do_cldliq = .true., park macrophysics is prognosing cldliq
logical :: macro_park_do_detrain = .true. ! do_detrain = .true., park macrophysics is detraining ice into stratiform
! Local variables
integer :: unitn, ierr
character(len=*), parameter :: subname = 'macrop_driver_readnl'
namelist /macro_park_nl/ macro_park_do_cldice, macro_park_do_cldliq, macro_park_do_detrain
!-----------------------------------------------------------------------------
if (masterproc) then
unitn = getunit()
open( unitn, file=trim(nlfile), status='old' )
call find_group_name(unitn, 'macro_park_nl', status=ierr)
if (ierr == 0) then
read(unitn, macro_park_nl, iostat=ierr)
if (ierr /= 0) then
call endrun(subname // ':: ERROR reading namelist')
end if
end if
close(unitn)
call freeunit(unitn)
! set local variables
do_cldice = macro_park_do_cldice
do_cldliq = macro_park_do_cldliq
do_detrain = macro_park_do_detrain
end if
#ifdef SPMD
! Broadcast namelist variables
call mpibcast(do_cldice, 1, mpilog, 0, mpicom)
call mpibcast(do_cldliq, 1, mpilog, 0, mpicom)
call mpibcast(do_detrain, 1, mpilog, 0, mpicom)
#endif
end subroutine macrop_driver_readnl
!================================================================================================
subroutine macrop_driver_register
!---------------------------------------------------------------------- !
! !
! Register the constituents (cloud liquid and cloud ice) and the fields !
! in the physics buffer. !
! !
!---------------------------------------------------------------------- !
use physics_buffer, only : pbuf_add_field, dtype_r8, dyn_time_lvls
!-----------------------------------------------------------------------
call phys_getopts(shallow_scheme_out=shallow_scheme)
call pbuf_add_field('AST', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), ast_idx)
call pbuf_add_field('AIST', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), aist_idx)
call pbuf_add_field('ALST', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), alst_idx)
call pbuf_add_field('QIST', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), qist_idx)
call pbuf_add_field('QLST', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), qlst_idx)
call pbuf_add_field('CLD', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), cld_idx)
call pbuf_add_field('CONCLD', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), concld_idx)
call pbuf_add_field('QCWAT', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), qcwat_idx)
call pbuf_add_field('LCWAT', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), lcwat_idx)
call pbuf_add_field('ICCWAT', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), iccwat_idx)
call pbuf_add_field('NLWAT', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), nlwat_idx)
call pbuf_add_field('NIWAT', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), niwat_idx)
call pbuf_add_field('TCWAT', 'global', dtype_r8, (/pcols,pver,dyn_time_lvls/), tcwat_idx)
call pbuf_add_field('FICE', 'physpkg', dtype_r8, (/pcols,pver/), fice_idx)
call pbuf_add_field('CMELIQ', 'physpkg', dtype_r8, (/pcols,pver/), cmeliq_idx)
end subroutine macrop_driver_register
!============================================================================ !
! !
!============================================================================ !
subroutine macrop_driver_init(pbuf2d)
!-------------------------------------------- !
! !
! Initialize the cloud water parameterization !
! !
!-------------------------------------------- !
use physics_buffer, only : pbuf_get_index
use cam_history, only: addfld, add_default
use convect_shallow, only: convect_shallow_use_shfrc
type(physics_buffer_desc), pointer :: pbuf2d(:,:)
logical :: history_aerosol ! Output the MAM aerosol tendencies
logical :: history_budget ! Output tendencies and state variables for CAM4
! temperature, water vapor, cloud ice and cloud
! liquid budgets.
integer :: history_budget_histfile_num ! output history file number for budget fields
integer :: istat
character(len=*), parameter :: subname = 'macrop_driver_init'
!-----------------------------------------------------------------------
! Initialization routine for cloud macrophysics
call ini_macro(rhminl_opt, rhmini_opt)
call phys_getopts(history_aerosol_out = history_aerosol , &
history_budget_out = history_budget , &
history_budget_histfile_num_out = history_budget_histfile_num )
! Find out whether shfrc from convect_shallow will be used in cldfrc
if( convect_shallow_use_shfrc() ) then
use_shfrc = .true.
shfrc_idx = pbuf_get_index('shfrc')
else
use_shfrc = .false.
endif
call addfld ('DPDLFLIQ', (/ 'lev' /), 'A', 'kg/kg/s', 'Detrained liquid water from deep convection', sampled_on_subcycle=.true.)
call addfld ('DPDLFICE', (/ 'lev' /), 'A', 'kg/kg/s', 'Detrained ice from deep convection', sampled_on_subcycle=.true.)
call addfld ('SHDLFLIQ', (/ 'lev' /), 'A', 'kg/kg/s', 'Detrained liquid water from shallow convection', sampled_on_subcycle=.true.)
call addfld ('SHDLFICE', (/ 'lev' /), 'A', 'kg/kg/s', 'Detrained ice from shallow convection', sampled_on_subcycle=.true.)
call addfld ('DPDLFT', (/ 'lev' /), 'A', 'K/s', 'T-tendency due to deep convective detrainment', sampled_on_subcycle=.true.)
call addfld ('SHDLFT', (/ 'lev' /), 'A', 'K/s', 'T-tendency due to shallow convective detrainment', sampled_on_subcycle=.true.)
call addfld ('ZMDLF', (/ 'lev' /), 'A', 'kg/kg/s', 'Detrained liquid water from ZM convection', sampled_on_subcycle=.true.)
call addfld ('MACPDT', (/ 'lev' /), 'A', 'W/kg', 'Heating tendency - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('MACPDQ', (/ 'lev' /), 'A', 'kg/kg/s', 'Q tendency - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('MACPDLIQ', (/ 'lev' /), 'A', 'kg/kg/s', 'CLDLIQ tendency - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('MACPDICE', (/ 'lev' /), 'A', 'kg/kg/s', 'CLDICE tendency - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('CLDVAPADJ', (/ 'lev' /), 'A', 'kg/kg/s', &
'Q tendency associated with liq/ice adjustment - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('CLDLIQADJ', (/ 'lev' /), 'A', 'kg/kg/s', 'CLDLIQ adjustment tendency - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('CLDICEADJ', (/ 'lev' /), 'A', 'kg/kg/s', 'CLDICE adjustment tendency - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('CLDLIQDET', (/ 'lev' /), 'A', 'kg/kg/s', &
'Detrainment of conv cld liq into envrionment - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('CLDICEDET', (/ 'lev' /), 'A', 'kg/kg/s', &
'Detrainment of conv cld ice into envrionment - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('CLDLIQLIM', (/ 'lev' /), 'A', 'kg/kg/s', 'CLDLIQ limiting tendency - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('CLDICELIM', (/ 'lev' /), 'A', 'kg/kg/s', 'CLDICE limiting tendency - Revised macrophysics', sampled_on_subcycle=.true.)
call addfld ('AST', (/ 'lev' /), 'A', '1', 'Stratus cloud fraction', sampled_on_subcycle=.true.)
call addfld ('LIQCLDF', (/ 'lev' /), 'A', '1', 'Stratus Liquid cloud fraction', sampled_on_subcycle=.true.)
call addfld ('ICECLDF', (/ 'lev' /), 'A', '1', 'Stratus ICE cloud fraction', sampled_on_subcycle=.true.)
call addfld ('CLDST', (/ 'lev' /), 'A', 'fraction', 'Stratus cloud fraction', sampled_on_subcycle=.true.)
call addfld ('CONCLD', (/ 'lev' /), 'A', 'fraction', 'Convective cloud cover', sampled_on_subcycle=.true.)
call addfld ('CLR_LIQ', (/ 'lev' /), 'A', 'fraction', 'Clear sky fraction for liquid stratus', sampled_on_subcycle=.true.)
call addfld ('CLR_ICE', (/ 'lev' /), 'A', 'fraction', 'Clear sky fraction for ice stratus', sampled_on_subcycle=.true.)
call addfld ('CLDLIQSTR', (/ 'lev' /), 'A', 'kg/kg', 'Stratiform CLDLIQ', sampled_on_subcycle=.true.)
call addfld ('CLDICESTR', (/ 'lev' /), 'A', 'kg/kg', 'Stratiform CLDICE', sampled_on_subcycle=.true.)
call addfld ('CLDLIQCON', (/ 'lev' /), 'A', 'kg/kg', 'Convective CLDLIQ', sampled_on_subcycle=.true.)
call addfld ('CLDICECON', (/ 'lev' /), 'A', 'kg/kg', 'Convective CLDICE', sampled_on_subcycle=.true.)
call addfld ('CLDSICE', (/ 'lev' /), 'A', 'kg/kg', 'CloudSat equivalent ice mass mixing ratio', sampled_on_subcycle=.true.)
call addfld ('CMELIQ', (/ 'lev' /), 'A', 'kg/kg/s', 'Rate of cond-evap of liq within the cloud', sampled_on_subcycle=.true.)
call addfld ('TTENDICE', (/ 'lev' /), 'A', 'K/s', 'T tendency from Ice Saturation Adjustment', sampled_on_subcycle=.true.)
call addfld ('QVTENDICE', (/ 'lev' /), 'A', 'kg/kg/s', 'Q tendency from Ice Saturation Adjustment', sampled_on_subcycle=.true.)
call addfld ('QITENDICE', (/ 'lev' /), 'A', 'kg/kg/s', 'CLDICE tendency from Ice Saturation Adjustment', sampled_on_subcycle=.true.)
call addfld ('NITENDICE', (/ 'lev' /), 'A', 'kg/kg/s', 'NUMICE tendency from Ice Saturation Adjustment', sampled_on_subcycle=.true.)
if ( history_budget ) then
call add_default ('DPDLFLIQ ', history_budget_histfile_num, ' ')
call add_default ('DPDLFICE ', history_budget_histfile_num, ' ')
call add_default ('SHDLFLIQ ', history_budget_histfile_num, ' ')
call add_default ('SHDLFICE ', history_budget_histfile_num, ' ')
call add_default ('DPDLFT ', history_budget_histfile_num, ' ')
call add_default ('SHDLFT ', history_budget_histfile_num, ' ')
call add_default ('ZMDLF ', history_budget_histfile_num, ' ')
call add_default ('MACPDT ', history_budget_histfile_num, ' ')
call add_default ('MACPDQ ', history_budget_histfile_num, ' ')
call add_default ('MACPDLIQ ', history_budget_histfile_num, ' ')
call add_default ('MACPDICE ', history_budget_histfile_num, ' ')
call add_default ('CLDVAPADJ', history_budget_histfile_num, ' ')
call add_default ('CLDLIQLIM', history_budget_histfile_num, ' ')
call add_default ('CLDLIQDET', history_budget_histfile_num, ' ')
call add_default ('CLDLIQADJ', history_budget_histfile_num, ' ')
call add_default ('CLDICELIM', history_budget_histfile_num, ' ')
call add_default ('CLDICEDET', history_budget_histfile_num, ' ')
call add_default ('CLDICEADJ', history_budget_histfile_num, ' ')
call add_default ('CMELIQ ', history_budget_histfile_num, ' ')
end if
! Get constituent indices
call cnst_get_ind('CLDLIQ', ixcldliq)
call cnst_get_ind('CLDICE', ixcldice)
call cnst_get_ind('NUMLIQ', ixnumliq)
call cnst_get_ind('NUMICE', ixnumice)
! Get physics buffer indices
CC_T_idx = pbuf_get_index('CC_T')
CC_qv_idx = pbuf_get_index('CC_qv')
CC_ql_idx = pbuf_get_index('CC_ql')
CC_qi_idx = pbuf_get_index('CC_qi')
CC_nl_idx = pbuf_get_index('CC_nl')
CC_ni_idx = pbuf_get_index('CC_ni')
CC_qlst_idx = pbuf_get_index('CC_qlst')
cmfmc_sh_idx = pbuf_get_index('CMFMC_SH')
sh_frac_idx = pbuf_get_index('SH_FRAC')
dp_frac_idx = pbuf_get_index('DP_FRAC')
! Init pbuf fields. Note that the fields CLD, CONCLD, QCWAT, LCWAT,
! ICCWAT, and TCWAT are initialized in phys_inidat.
if (is_first_step()) then
call pbuf_set_field(pbuf2d, ast_idx, 0._r8)
call pbuf_set_field(pbuf2d, aist_idx, 0._r8)
call pbuf_set_field(pbuf2d, alst_idx, 0._r8)
call pbuf_set_field(pbuf2d, qist_idx, 0._r8)
call pbuf_set_field(pbuf2d, qlst_idx, 0._r8)
call pbuf_set_field(pbuf2d, nlwat_idx, 0._r8)
call pbuf_set_field(pbuf2d, niwat_idx, 0._r8)
end if
! the following are physpkg, so they need to be init every time
call pbuf_set_field(pbuf2d, fice_idx, 0._r8)
call pbuf_set_field(pbuf2d, cmeliq_idx, 0._r8)
end subroutine macrop_driver_init
!============================================================================ !
! !
!============================================================================ !
subroutine macrop_driver_tend( &
state, ptend, dtime, landfrac, &
ocnfrac, snowh, &
dlf, dlf2, cmfmc, ts, &
sst, zdu, &
pbuf, &
det_s, det_ice)
!-------------------------------------------------------- !
! !
! Purpose: !
! !
! Interface to detrain, cloud fraction and !
! cloud macrophysics subroutines !
! !
! Author: A. Gettelman, C. Craig, Oct 2010 !
! based on stratiform_tend by D.B. Coleman 4/2010 !
! !
!-------------------------------------------------------- !
use cloud_fraction_fice, only: cloud_fraction_fice_run
use physics_types, only: physics_state, physics_ptend
use physics_types, only: physics_ptend_init, physics_update
use physics_types, only: physics_ptend_sum, physics_state_copy
use physics_types, only: physics_state_dealloc
use cam_history, only: outfld
use constituents, only: cnst_get_ind, pcnst
use cldwat2m_macro, only: mmacro_pcond
use physconst, only: cpair, tmelt, gravit, cappa, rair, pref, lapse_rate
use time_manager, only: get_nstep
use ref_pres, only: top_lev => trop_cloud_top_lev
! CCPPized schemes
use convective_cloud_cover, only: convective_cloud_cover_run
use compute_cloud_fraction, only: compute_cloud_fraction_run
use ref_pres, only: trop_cloud_top_lev ! bring in explicitly for CCPPized scheme
!
! Input arguments
!
type(physics_state), intent(in) :: state ! State variables
type(physics_ptend), intent(out) :: ptend ! macrophysics parameterization tendencies
type(physics_buffer_desc), pointer :: pbuf(:) ! Physics buffer
real(r8), intent(in) :: dtime ! Timestep
real(r8), intent(in) :: landfrac(pcols) ! Land fraction (fraction)
real(r8), intent(in) :: ocnfrac (pcols) ! Ocean fraction (fraction)
real(r8), intent(in) :: snowh(pcols) ! Snow depth over land, water equivalent (m)
real(r8), intent(in) :: dlf(pcols,pver) ! Detrained water from convection schemes
real(r8), intent(in) :: dlf2(pcols,pver) ! Detrained water from shallow convection scheme
real(r8), intent(in) :: cmfmc(pcols,pverp) ! Deep + Shallow Convective mass flux [ kg /s/m^2 ]
real(r8), intent(in) :: ts(pcols) ! Surface temperature
real(r8), intent(in) :: sst(pcols) ! Sea surface temperature
real(r8), intent(in) :: zdu(pcols,pver) ! Detrainment rate from deep convection
! These two variables are needed for energy check
real(r8), intent(out) :: det_s(pcols) ! Integral of detrained static energy from ice
real(r8), intent(out) :: det_ice(pcols) ! Integral of detrained ice for energy check
!
! Local variables
!
type(physics_state) :: state_loc ! Local copy of the state variable
type(physics_ptend) :: ptend_loc ! Local parameterization tendencies
integer i,k
integer :: lchnk ! Chunk identifier
integer :: ncol ! Number of atmospheric columns
! Physics buffer fields
integer itim_old
real(r8), pointer, dimension(:,:) :: qcwat ! Cloud water old q
real(r8), pointer, dimension(:,:) :: tcwat ! Cloud water old temperature
real(r8), pointer, dimension(:,:) :: lcwat ! Cloud liquid water old q
real(r8), pointer, dimension(:,:) :: iccwat ! Cloud ice water old q
real(r8), pointer, dimension(:,:) :: nlwat ! Cloud liquid droplet number condentration. old.
real(r8), pointer, dimension(:,:) :: niwat ! Cloud ice droplet number condentration. old.
real(r8), pointer, dimension(:,:) :: CC_T ! Grid-mean microphysical tendency
real(r8), pointer, dimension(:,:) :: CC_qv ! Grid-mean microphysical tendency
real(r8), pointer, dimension(:,:) :: CC_ql ! Grid-mean microphysical tendency
real(r8), pointer, dimension(:,:) :: CC_qi ! Grid-mean microphysical tendency
real(r8), pointer, dimension(:,:) :: CC_nl ! Grid-mean microphysical tendency
real(r8), pointer, dimension(:,:) :: CC_ni ! Grid-mean microphysical tendency
real(r8), pointer, dimension(:,:) :: CC_qlst ! In-liquid stratus microphysical tendency
real(r8), pointer, dimension(:,:) :: cld ! Total cloud fraction
real(r8), pointer, dimension(:,:) :: ast ! Relative humidity cloud fraction
real(r8), pointer, dimension(:,:) :: aist ! Physical ice stratus fraction
real(r8), pointer, dimension(:,:) :: alst ! Physical liquid stratus fraction
real(r8), pointer, dimension(:,:) :: qist ! Physical in-cloud IWC
real(r8), pointer, dimension(:,:) :: qlst ! Physical in-cloud LWC
real(r8), pointer, dimension(:,:) :: concld ! Convective cloud fraction
real(r8), pointer, dimension(:,:) :: shfrc ! Cloud fraction from shallow convection scheme
real(r8), pointer, dimension(:,:) :: cmfmc_sh ! Shallow convective mass flux (pcols,pverp) [ kg/s/m^2 ]
real(r8), pointer, dimension(:,:) :: cmeliq
! Convective cloud to the physics buffer for purposes of ql contrib. to radn.
real(r8), pointer, dimension(:,:) :: fice_ql ! Cloud ice/water partitioning ratio.
! ZM microphysics
real(r8), pointer :: dlfzm(:,:) ! ZM detrained convective cloud water mixing ratio.
real(r8), pointer :: dnlfzm(:,:) ! ZM detrained convective cloud water num concen.
real(r8), pointer :: dnifzm(:,:) ! ZM detrained convective cloud ice num concen.
real(r8) :: latsub
! tendencies for ice saturation adjustment
real(r8) :: stend(pcols,pver)
real(r8) :: qvtend(pcols,pver)
real(r8) :: qitend(pcols,pver)
real(r8) :: initend(pcols,pver)
! Local variables for cldfrc
real(r8) cldst(pcols,pver) ! Stratus cloud fraction
real(r8) rhcloud(pcols,pver) ! Relative humidity cloud (last timestep)
real(r8) rhu00(pcols,pver) ! RH threshold for cloud
real(r8) icecldf(pcols,pver) ! Ice cloud fraction
real(r8) liqcldf(pcols,pver) ! Liquid cloud fraction (combined into cloud)
real(r8) relhum(pcols,pver) ! RH, output to determine drh/da
! Local variables for macrophysics
real(r8) rdtime ! 1./dtime
real(r8) qtend(pcols,pver) ! Moisture tendencies
real(r8) ttend(pcols,pver) ! Temperature tendencies
real(r8) ltend(pcols,pver) ! Cloud liquid water tendencies
real(r8) fice(pcols,pver) ! Fractional ice content within cloud
real(r8) fsnow(pcols,pver) ! Fractional snow production
real(r8) homoo(pcols,pver)
real(r8) qcreso(pcols,pver)
real(r8) prcio(pcols,pver)
real(r8) praio(pcols,pver)
real(r8) qireso(pcols,pver)
real(r8) ftem(pcols,pver)
real(r8) pracso (pcols,pver)
real(r8) dpdlfliq(pcols,pver)
real(r8) dpdlfice(pcols,pver)
real(r8) shdlfliq(pcols,pver)
real(r8) shdlfice(pcols,pver)
real(r8) dpdlft (pcols,pver)
real(r8) shdlft (pcols,pver)
real(r8) dum1
real(r8) qc(pcols,pver)
real(r8) qi(pcols,pver)
real(r8) nc(pcols,pver)
real(r8) ni(pcols,pver)
logical lq(pcnst)
! Output from mmacro_pcond
real(r8) tlat(pcols,pver)
real(r8) qvlat(pcols,pver)
real(r8) qcten(pcols,pver)
real(r8) qiten(pcols,pver)
real(r8) ncten(pcols,pver)
real(r8) niten(pcols,pver)
! Output from mmacro_pcond
real(r8) qvadj(pcols,pver) ! Macro-physics adjustment tendency from "positive_moisture" call (vapor)
real(r8) qladj(pcols,pver) ! Macro-physics adjustment tendency from "positive_moisture" call (liquid)
real(r8) qiadj(pcols,pver) ! Macro-physics adjustment tendency from "positive_moisture" call (ice)
real(r8) qllim(pcols,pver) ! Macro-physics tendency from "instratus_condensate" call (liquid)
real(r8) qilim(pcols,pver) ! Macro-physics tendency from "instratus_condensate" call (ice)
! For revised macophysics, mmacro_pcond
real(r8) itend(pcols,pver)
real(r8) lmitend(pcols,pver)
real(r8) zeros(pcols,pver)
real(r8) t_inout(pcols,pver)
real(r8) qv_inout(pcols,pver)
real(r8) ql_inout(pcols,pver)
real(r8) qi_inout(pcols,pver)
real(r8) concld_old(pcols,pver)
! Note that below 'clr_old' is defined using 'alst_old' not 'ast_old' for full consistency with the
! liquid condensation process which is using 'alst' not 'ast'.
! For microconsistency use 'concld_old', since 'alst_old' was computed using 'concld_old'.
! Since convective updraft fractional area is small, it does not matter whether 'concld' or 'concld_old' is used.
! Note also that 'clri_old' is defined using 'ast_old' since current microphysics is operating on 'ast_old'
real(r8) clrw_old(pcols,pver) ! (1 - concld_old - alst_old)
real(r8) clri_old(pcols,pver) ! (1 - concld_old - ast_old)
real(r8) nl_inout(pcols,pver)
real(r8) ni_inout(pcols,pver)
real(r8) nltend(pcols,pver)
real(r8) nitend(pcols,pver)
! For detraining cumulus condensate into the 'stratus' without evaporation
! This is for use in mmacro_pcond
real(r8) dlf_T(pcols,pver)
real(r8) dlf_qv(pcols,pver)
real(r8) dlf_ql(pcols,pver)
real(r8) dlf_qi(pcols,pver)
real(r8) dlf_nl(pcols,pver)
real(r8) dlf_ni(pcols,pver)
! Local variables for CFMIP calculations
real(r8) :: mr_lsliq(pcols,pver) ! mixing_ratio_large_scale_cloud_liquid (kg/kg)
real(r8) :: mr_lsice(pcols,pver) ! mixing_ratio_large_scale_cloud_ice (kg/kg)
real(r8) :: mr_ccliq(pcols,pver) ! mixing_ratio_convective_cloud_liquid (kg/kg)
real(r8) :: mr_ccice(pcols,pver) ! mixing_ratio_convective_cloud_ice (kg/kg)
! CloudSat equivalent ice mass mixing ratio (kg/kg)
real(r8) :: cldsice(pcols,pver)
! shallowcu, deepcu pbuf fields
real(r8), pointer, dimension(:,:) :: deepcu ! deep convection cloud fraction
real(r8), pointer, dimension(:,:) :: shallowcu ! shallow convection cloud fraction
! For CCPPized schemes
character(len=512) :: errmsg
integer :: errflg
! ======================================================================
lchnk = state%lchnk
ncol = state%ncol
call physics_state_copy(state, state_loc) ! Copy state to local state_loc.
! Associate pointers with physics buffer fields
itim_old = pbuf_old_tim_idx()
call pbuf_get_field(pbuf, qcwat_idx, qcwat, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, tcwat_idx, tcwat, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, lcwat_idx, lcwat, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, iccwat_idx, iccwat, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, nlwat_idx, nlwat, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, niwat_idx, niwat, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, cc_t_idx, cc_t, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, cc_qv_idx, cc_qv, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, cc_ql_idx, cc_ql, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, cc_qi_idx, cc_qi, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, cc_nl_idx, cc_nl, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, cc_ni_idx, cc_ni, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, cc_qlst_idx, cc_qlst, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, cld_idx, cld, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, concld_idx, concld, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, ast_idx, ast, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, aist_idx, aist, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, alst_idx, alst, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, qist_idx, qist, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, qlst_idx, qlst, start=(/1,1,itim_old/), kount=(/pcols,pver,1/) )
call pbuf_get_field(pbuf, cmeliq_idx, cmeliq)
! For purposes of convective ql.
call pbuf_get_field(pbuf, fice_idx, fice_ql )
call pbuf_get_field(pbuf, cmfmc_sh_idx, cmfmc_sh)
! check that qcwat and tcwat were initialized; if not then do it now.
if (qcwat(1,1) == huge(1._r8)) then
qcwat(:ncol,:) = state%q(:ncol,:,1)
end if
if (tcwat(1,1) == huge(1._r8)) then
tcwat(:ncol,:) = state%t(:ncol,:)
end if
! Initialize convective detrainment tendency
dlf_T(:,:) = 0._r8
dlf_qv(:,:) = 0._r8
dlf_ql(:,:) = 0._r8
dlf_qi(:,:) = 0._r8
dlf_nl(:,:) = 0._r8
dlf_ni(:,:) = 0._r8
! ------------------------------------- !
! From here, process computation begins !
! ------------------------------------- !
! ----------------------------------------------------------------------------- !
! Detrainment of convective condensate into the environment or stratiform cloud !
! ----------------------------------------------------------------------------- !
lq(:) = .FALSE.
lq(ixcldliq) = .TRUE.
lq(ixcldice) = .TRUE.
lq(ixnumliq) = .TRUE.
lq(ixnumice) = .TRUE.
call physics_ptend_init(ptend_loc, state%psetcols, 'pcwdetrain', ls=.true., lq=lq) ! Initialize local physics_ptend object
! Procedures :
! (1) Partition detrained convective cloud water into liquid and ice based on T.
! This also involves heating.
! If convection scheme can handle this internally, this step is not necssary.
! (2) Assuming a certain effective droplet radius, computes number concentration
! of detrained convective cloud liquid and ice.
! (3) If 'cu_det_st = .true' ('false'), detrain convective cloud 'liquid' into
! the pre-existing 'liquid' stratus ( mean environment ). The former does
! not involve any macrophysical evaporation while the latter does. This is
! a kind of 'targetted' deposition. Then, force in-stratus LWC to be bounded
! by qcst_min and qcst_max in mmacro_pcond.
! (4) In contrast to liquid, convective ice is detrained into the environment
! and involved in the sublimation. Similar bounds as liquid stratus are imposed.
! This is the key procesure generating upper-level cirrus clouds.
! The unit of dlf : [ kg/kg/s ]
det_s(:) = 0._r8
det_ice(:) = 0._r8
dpdlfliq = 0._r8
dpdlfice = 0._r8
shdlfliq = 0._r8
shdlfice = 0._r8
dpdlft = 0._r8
shdlft = 0._r8
do k = top_lev, pver
do i = 1, state_loc%ncol
if( state_loc%t(i,k) > 268.15_r8 ) then
dum1 = 0.0_r8
elseif( state_loc%t(i,k) < 238.15_r8 ) then
dum1 = 1.0_r8
else
dum1 = ( 268.15_r8 - state_loc%t(i,k) ) / 30._r8
endif
! If detrainment was done elsewhere, still update the variables used for output
! assuming that the temperature split between liquid and ice is the same as assumed
! here.
if (do_detrain) then
ptend_loc%q(i,k,ixcldliq) = dlf(i,k) * ( 1._r8 - dum1 )
ptend_loc%q(i,k,ixcldice) = dlf(i,k) * dum1
! dum2 = dlf(i,k) * ( 1._r8 - dum1 )
ptend_loc%q(i,k,ixnumliq) = 3._r8 * ( max(0._r8, ( dlf(i,k) - dlf2(i,k) )) * ( 1._r8 - dum1 ) ) / &
(4._r8*3.14_r8* 8.e-6_r8**3*997._r8) + & ! Deep Convection
3._r8 * ( dlf2(i,k) * ( 1._r8 - dum1 ) ) / &
(4._r8*3.14_r8*10.e-6_r8**3*997._r8) ! Shallow Convection
! dum2 = dlf(i,k) * dum1
ptend_loc%q(i,k,ixnumice) = 3._r8 * ( max(0._r8, ( dlf(i,k) - dlf2(i,k) )) * dum1 ) / &
(4._r8*3.14_r8*25.e-6_r8**3*500._r8) + & ! Deep Convection
3._r8 * ( dlf2(i,k) * dum1 ) / &
(4._r8*3.14_r8*50.e-6_r8**3*500._r8) ! Shallow Convection
ptend_loc%s(i,k) = dlf(i,k) * dum1 * latice
else
ptend_loc%q(i,k,ixcldliq) = 0._r8
ptend_loc%q(i,k,ixcldice) = 0._r8
ptend_loc%q(i,k,ixnumliq) = 0._r8
ptend_loc%q(i,k,ixnumice) = 0._r8
ptend_loc%s(i,k) = 0._r8
end if
! Only rliq is saved from deep convection, which is the reserved liquid. We need to keep
! track of the integrals of ice and static energy that is effected from conversion to ice
! so that the energy checker doesn't complain.
det_s(i) = det_s(i) + ptend_loc%s(i,k)*state_loc%pdel(i,k)/gravit
det_ice(i) = det_ice(i) - ptend_loc%q(i,k,ixcldice)*state_loc%pdel(i,k)/gravit
! Targetted detrainment of convective liquid water either directly into the
! existing liquid stratus or into the environment.
if( cu_det_st ) then
dlf_T(i,k) = ptend_loc%s(i,k)/cpair
dlf_qv(i,k) = 0._r8
dlf_ql(i,k) = ptend_loc%q(i,k,ixcldliq)
dlf_qi(i,k) = ptend_loc%q(i,k,ixcldice)
dlf_nl(i,k) = ptend_loc%q(i,k,ixnumliq)
dlf_ni(i,k) = ptend_loc%q(i,k,ixnumice)
ptend_loc%q(i,k,ixcldliq) = 0._r8
ptend_loc%q(i,k,ixcldice) = 0._r8
ptend_loc%q(i,k,ixnumliq) = 0._r8
ptend_loc%q(i,k,ixnumice) = 0._r8
ptend_loc%s(i,k) = 0._r8
dpdlfliq(i,k) = 0._r8
dpdlfice(i,k) = 0._r8
shdlfliq(i,k) = 0._r8
shdlfice(i,k) = 0._r8
dpdlft (i,k) = 0._r8
shdlft (i,k) = 0._r8
else
dpdlfliq(i,k) = ( dlf(i,k) - dlf2(i,k) ) * ( 1._r8 - dum1 )
dpdlfice(i,k) = ( dlf(i,k) - dlf2(i,k) ) * ( dum1 )
dpdlft (i,k) = ( dlf(i,k) - dlf2(i,k) ) * dum1 * latice/cpair
shdlfliq(i,k) = dlf2(i,k) * ( 1._r8 - dum1 )
shdlfice(i,k) = dlf2(i,k) * ( dum1 )
shdlft (i,k) = dlf2(i,k) * dum1 * latice/cpair
endif
end do
end do
call outfld( 'DPDLFLIQ ', dpdlfliq, pcols, lchnk )
call outfld( 'DPDLFICE ', dpdlfice, pcols, lchnk )
call outfld( 'SHDLFLIQ ', shdlfliq, pcols, lchnk )
call outfld( 'SHDLFICE ', shdlfice, pcols, lchnk )
call outfld( 'DPDLFT ', dpdlft , pcols, lchnk )
call outfld( 'SHDLFT ', shdlft , pcols, lchnk )
call outfld( 'ZMDLF', dlf , pcols, state_loc%lchnk )
det_ice(:ncol) = det_ice(:ncol)/1000._r8 ! divide by density of water
! Add the detrainment tendency to the output tendency
call physics_ptend_init(ptend, state%psetcols, 'macrop')
call physics_ptend_sum(ptend_loc, ptend, ncol)
! update local copy of state with the detrainment tendency
! ptend_loc is reset to zero by this call
call physics_update(state_loc, ptend_loc, dtime)
! -------------------------------------- !
! Computation of Various Cloud Fractions !
! -------------------------------------- !
! ----------------------------------------------------------------------------- !
! Treatment of cloud fraction in CAM4 and CAM5 differs !
! (1) CAM4 !
! . Cumulus AMT = Deep Cumulus AMT ( empirical fcn of mass flux ) + !
! Shallow Cumulus AMT ( empirical fcn of mass flux ) !
! . Stratus AMT = max( RH stratus AMT, Stability Stratus AMT ) !
! . Cumulus and Stratus are 'minimally' overlapped without hierarchy. !
! . Cumulus LWC,IWC is assumed to be the same as Stratus LWC,IWC !
! (2) CAM5 !
! . Cumulus AMT = Deep Cumulus AMT ( empirical fcn of mass flux ) + !
! Shallow Cumulus AMT ( internally fcn of mass flux and w ) !
! . Stratus AMT = fcn of environmental-mean RH ( no Stability Stratus ) !
! . Cumulus and Stratus are non-overlapped with higher priority on Cumulus !
! . Cumulus ( both Deep and Shallow ) has its own LWC and IWC. !
! ----------------------------------------------------------------------------- !
concld_old(:ncol,top_lev:pver) = concld(:ncol,top_lev:pver)
clrw_old(:ncol,:top_lev-1) = 0._r8
clri_old(:ncol,:top_lev-1) = 0._r8
do k = top_lev, pver
do i = 1, ncol
clrw_old(i,k) = max( 0._r8, min( 1._r8, 1._r8 - concld(i,k) - alst(i,k) ) )
clri_old(i,k) = max( 0._r8, min( 1._r8, 1._r8 - concld(i,k) - ast(i,k) ) )
end do
end do
if( use_shfrc ) then
call pbuf_get_field(pbuf, shfrc_idx, shfrc )
else
allocate(shfrc(pcols,pver))
shfrc(:,:) = 0._r8
endif
! CAM5 only uses 'concld' output from the below subroutine.
! Stratus ('ast' = max(alst,aist)) and total cloud fraction ('cld = ast + concld')
! will be computed using this updated 'concld' in the stratiform macrophysics
! scheme (mmacro_pcond) later below.
call t_startf("cldfrc")
call pbuf_get_field(pbuf, sh_frac_idx, shallowcu )
call pbuf_get_field(pbuf, dp_frac_idx, deepcu )
!REMOVECAM - no longer need this when CAM is retired and pcols no longer exists
shallowcu(:,:) = 0._r8
deepcu(:,:) = 0._r8
concld(:,:) = 0._r8
!REMOVECAM_END
! compute convective cloud fraction using CCPP-ized subroutine
call convective_cloud_cover_run( &
ncol = ncol, &
pver = pver, &
top_lev_cloudphys = trop_cloud_top_lev, & ! CAM5 macrophysics.
use_shfrc = use_shfrc, &
shfrc = shfrc(:ncol,:), &
cmfmc_total = cmfmc(:ncol,:), &
cmfmc_sh = cmfmc_sh(:ncol,:), &
shallowcu = shallowcu(:ncol,:), &
deepcu = deepcu(:ncol,:), &
concld = concld(:ncol,:), &
errmsg = errmsg, &
errflg = errflg)
! write out convective cloud fraction diagnostic.
call outfld( 'SH_CLD ', shallowcu , pcols, lchnk )
call outfld( 'DP_CLD ', deepcu , pcols, lchnk )
!REMOVECAM - no longer need this when CAM is retired and pcols no longer exists
cld(:,:) = 0._r8
rhcloud(:,:) = 0._r8
cldst(:,:) = 0._r8
rhu00(:,:) = 0._r8
icecldf(:,:) = 0._r8
liqcldf(:,:) = 0._r8
relhum(:,:) = 0._r8
!REMOVECAM_END
! call CCPPized cloud fraction scheme
call compute_cloud_fraction_run( &
ncol = ncol, &
pver = pver, &
cappa = cappa, &
gravit = gravit, &
rair = rair, &
pref = pref, &
lapse_rate = lapse_rate, &
top_lev_cloudphys = trop_cloud_top_lev, & ! CAM5 macrophysics.
pmid = state_loc%pmid(:ncol,:), &
ps = state_loc%pint(:ncol,pverp), &
temp = state_loc%t(:ncol,:), &
sst = sst(:ncol), &
q = state_loc%q(:ncol,:,1), & ! note: assumes wv is at index 1.
cldice = state_loc%q(:ncol,:,ixcldice), &
phis = state_loc%phis(:ncol), &
concld = concld(:ncol,:), &
landfrac = landfrac(:ncol), &
ocnfrac = ocnfrac(:ncol), &
snowh = snowh(:ncol), &
rhpert_flag = .false., & ! below output:
cloud = cld(:ncol, :), &
rhcloud = rhcloud(:ncol, :), &
cldst = cldst(:ncol,:), &
rhu00 = rhu00(:ncol,:), &
icecldf = icecldf(:ncol,:), &
liqcldf = liqcldf(:ncol,:), &
relhum = relhum(:ncol,:), &
errmsg = errmsg, &
errflg = errflg)
call t_stopf("cldfrc")
! ---------------------------------------------- !
! Stratiform Cloud Macrophysics and Microphysics !
! ---------------------------------------------- !
lchnk = state_loc%lchnk
ncol = state_loc%ncol
rdtime = 1._r8/dtime
! Define fractional amount of stratus condensate and precipitation in ice phase.
! This uses a ramp ( -30 ~ -10 for fice, -5 ~ 0 for fsnow ).
! The ramp within convective cloud may be different
!REMOVECAM - no longer need these when CAM is retired and pcols no longer exists
fice(:,:) = 0._r8
fsnow(:,:) = 0._r8
!REMOVECAM_END
call cloud_fraction_fice_run(ncol, state_loc%t(:ncol,:), tmelt, top_lev, pver, fice(:ncol,:), fsnow(:ncol,:), errmsg, errflg)
lq(:) = .FALSE.
lq(1) = .true.
lq(ixcldice) = .true.
lq(ixcldliq) = .true.
lq(ixnumliq) = .true.
lq(ixnumice) = .true.
! Initialize local physics_ptend object again
call physics_ptend_init(ptend_loc, state%psetcols, 'macro_park', &
ls=.true., lq=lq )
! --------------------------------- !
! Liquid Macrop_Driver Macrophysics !
! --------------------------------- !
call t_startf('mmacro_pcond')
zeros(:ncol,top_lev:pver) = 0._r8
qc(:ncol,top_lev:pver) = state_loc%q(:ncol,top_lev:pver,ixcldliq)
qi(:ncol,top_lev:pver) = state_loc%q(:ncol,top_lev:pver,ixcldice)
nc(:ncol,top_lev:pver) = state_loc%q(:ncol,top_lev:pver,ixnumliq)
ni(:ncol,top_lev:pver) = state_loc%q(:ncol,top_lev:pver,ixnumice)
! In CAM5, 'microphysical forcing' ( CC_... ) and 'the other advective forcings' ( ttend, ... )
! are separately provided into the prognostic microp_driver macrophysics scheme. This is an
! attempt to resolve in-cloud and out-cloud forcings.
if( get_nstep() .le. 1 ) then
tcwat(:ncol,top_lev:pver) = state_loc%t(:ncol,top_lev:pver)
qcwat(:ncol,top_lev:pver) = state_loc%q(:ncol,top_lev:pver,1)
lcwat(:ncol,top_lev:pver) = qc(:ncol,top_lev:pver) + qi(:ncol,top_lev:pver)
iccwat(:ncol,top_lev:pver) = qi(:ncol,top_lev:pver)
nlwat(:ncol,top_lev:pver) = nc(:ncol,top_lev:pver)
niwat(:ncol,top_lev:pver) = ni(:ncol,top_lev:pver)
ttend(:ncol,:) = 0._r8
qtend(:ncol,:) = 0._r8
ltend(:ncol,:) = 0._r8
itend(:ncol,:) = 0._r8
nltend(:ncol,:) = 0._r8
nitend(:ncol,:) = 0._r8
CC_T(:ncol,:) = 0._r8
CC_qv(:ncol,:) = 0._r8
CC_ql(:ncol,:) = 0._r8
CC_qi(:ncol,:) = 0._r8
CC_nl(:ncol,:) = 0._r8
CC_ni(:ncol,:) = 0._r8
CC_qlst(:ncol,:) = 0._r8
else
ttend(:ncol,top_lev:pver) = ( state_loc%t(:ncol,top_lev:pver) - tcwat(:ncol,top_lev:pver)) * rdtime &
- CC_T(:ncol,top_lev:pver)
qtend(:ncol,top_lev:pver) = ( state_loc%q(:ncol,top_lev:pver,1) - qcwat(:ncol,top_lev:pver)) * rdtime &
- CC_qv(:ncol,top_lev:pver)
ltend(:ncol,top_lev:pver) = ( qc(:ncol,top_lev:pver) + qi(:ncol,top_lev:pver) - lcwat(:ncol,top_lev:pver) ) * rdtime &
- (CC_ql(:ncol,top_lev:pver) + CC_qi(:ncol,top_lev:pver))
itend(:ncol,top_lev:pver) = ( qi(:ncol,top_lev:pver) - iccwat(:ncol,top_lev:pver)) * rdtime &
- CC_qi(:ncol,top_lev:pver)
nltend(:ncol,top_lev:pver) = ( nc(:ncol,top_lev:pver) - nlwat(:ncol,top_lev:pver)) * rdtime &
- CC_nl(:ncol,top_lev:pver)
nitend(:ncol,top_lev:pver) = ( ni(:ncol,top_lev:pver) - niwat(:ncol,top_lev:pver)) * rdtime &
- CC_ni(:ncol,top_lev:pver)
endif
lmitend(:ncol,top_lev:pver) = ltend(:ncol,top_lev:pver) - itend(:ncol,top_lev:pver)
t_inout(:ncol,top_lev:pver) = tcwat(:ncol,top_lev:pver)
qv_inout(:ncol,top_lev:pver) = qcwat(:ncol,top_lev:pver)
ql_inout(:ncol,top_lev:pver) = lcwat(:ncol,top_lev:pver) - iccwat(:ncol,top_lev:pver)
qi_inout(:ncol,top_lev:pver) = iccwat(:ncol,top_lev:pver)
nl_inout(:ncol,top_lev:pver) = nlwat(:ncol,top_lev:pver)
ni_inout(:ncol,top_lev:pver) = niwat(:ncol,top_lev:pver)
! Liquid Microp_Driver Macrophysics.
! The main roles of this subroutines are
! (1) compute net condensation rate of stratiform liquid ( cmeliq )
! (2) compute liquid stratus and ice stratus fractions.
! Note 'ttend...' are advective tendencies except microphysical process while
! 'CC...' are microphysical tendencies.
call mmacro_pcond( lchnk, ncol, dtime, state_loc%pmid, state_loc%pdel, &
t_inout, qv_inout, ql_inout, qi_inout, nl_inout, ni_inout, &
ttend, qtend, lmitend, itend, nltend, nitend, &
CC_T, CC_qv, CC_ql, CC_qi, CC_nl, CC_ni, CC_qlst, &
dlf_T, dlf_qv, dlf_ql, dlf_qi, dlf_nl, dlf_ni, &
concld_old, concld, clrw_old, clri_old, landfrac, snowh, &
tlat, qvlat, qcten, qiten, ncten, niten, &
cmeliq, qvadj, qladj, qiadj, qllim, qilim, &
cld, alst, aist, qlst, qist, do_cldice )
! Copy of concld/fice to put in physics buffer
! Below are used only for convective cloud.