SCALE-RM
scale_atmos_phy_mp_common.F90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
11 !-------------------------------------------------------------------------------
12 #include "scalelib.h"
14  !-----------------------------------------------------------------------------
15  !
16  !++ used modules
17  !
18  use scale_precision
19  use scale_io
20  use scale_prof
22  use scale_tracer
23  !-----------------------------------------------------------------------------
24  implicit none
25  private
26  !-----------------------------------------------------------------------------
27  !
28  !++ Public procedure
29  !
31  public :: atmos_phy_mp_saturation_adjustment
35 
36  interface atmos_phy_mp_saturation_adjustment
38  end interface atmos_phy_mp_saturation_adjustment
39 
40  !-----------------------------------------------------------------------------
41  !
42  !++ Public parameters & variables
43  !
44  !-----------------------------------------------------------------------------
45  !
46  !++ Private procedure
47  !
48  !-----------------------------------------------------------------------------
49  !
50  !++ Private parameters & variables
51  !
52  !-----------------------------------------------------------------------------
53 contains
54 
55  !-----------------------------------------------------------------------------
59  !-----------------------------------------------------------------------------
60  subroutine atmos_phy_mp_negative_fixer( &
61  KA, KS, KE, IA, IS, IE, JA, JS, JE, QLA, QIA, &
62  limit_negative, &
63  DENS, TEMP, &
64  CVtot, CPtot, &
65  QV, QTRC, &
66  RHOH, &
67  DENS_diff, &
68  ENGI_diff )
69  use scale_prc, only: &
70  prc_abort
71  use scale_const, only: &
72  cvdry => const_cvdry, &
73  cpdry => const_cpdry
74  use scale_atmos_hydrometeor, only: &
75  atmos_hydrometeor_lhv, &
76  atmos_hydrometeor_lhs, &
77  cv_vapor, &
78  cp_vapor, &
79  cv_water, &
80  cp_water, &
81  cv_ice, &
82  cp_ice
83  implicit none
84  integer, intent(in) :: KA, KS, KE
85  integer, intent(in) :: IA, IS, IE
86  integer, intent(in) :: JA, JS, JE
87  integer, intent(in) :: QLA, QIA
88 
89  real(RP), intent(in) :: limit_negative
90 
91  real(RP), intent(inout) :: DENS (ka,ia,ja)
92  real(RP), intent(inout) :: TEMP (ka,ia,ja)
93  real(RP), intent(inout) :: CVtot(ka,ia,ja)
94  real(RP), intent(inout) :: CPtot(ka,ia,ja)
95  real(RP), intent(inout) :: QV (ka,ia,ja)
96  real(RP), intent(inout) :: QTRC (ka,ia,ja,qla+qia)
97 
98  real(RP), intent(out), optional :: RHOH (ka,ia,ja)
99  real(RP), intent(out), optional :: DENS_diff(ka,ia,ja)
100  real(RP), intent(out), optional :: ENGI_diff(ka,ia,ja)
101 
102  real(RP) :: LHV(ka)
103  real(RP) :: LHS(ka)
104  real(RP) :: eng (ka)
105  real(RP) :: eng0 (ka)
106  real(RP) :: dens0(ka)
107  real(RP) :: diffq(ka)
108  real(RP) :: diffq_min
109  real(RP) :: work
110 
111  logical :: rhoh_out
112  logical :: dens_out
113  logical :: engi_out
114 
115  integer :: k, i, j, iq
116  !---------------------------------------------------------------------------
117 
118  call prof_rapstart('MP_filter', 3)
119 
120  rhoh_out = present( rhoh )
121  dens_out = present( dens_diff )
122  engi_out = present( engi_diff )
123 
124  diffq_min = 0.0_rp
125 
126  !$omp parallel do default(none) OMP_SCHEDULE_ collapse(2) &
127  !$omp reduction(min:diffq_min) &
128  !$omp private(i,j,k,iq, &
129  !$omp LHV,LHS,eng,eng0,dens0,diffq,work) &
130  !$omp shared(KA,KS,KE,IS,IE,JS,JE,QLA,QIA, &
131  !$omp CVdry,CPdry,CV_VAPOR,CP_VAPOR,CV_WATER,CP_WATER,CV_ICE,CP_ICE, &
132  !$omp DENS,TEMP,CVtot,CPtot,QV,QTRC, &
133  !$omp RHOH,DENS_diff,ENGI_diff,rhoh_out,dens_out,engi_out,limit_negative)
134  do j = js, je
135  do i = is, ie
136 
137  diffq(:) = 0.0_rp
138 
139  do k = ks, ke
140  eng(k) = cvtot(k,i,j) * temp(k,i,j)
141  end do
142 
143  if ( rhoh_out ) then
144  do k = ks, ke
145  eng0(k) = eng(k)
146  end do
147  end if
148 
149  if ( qla > 0 ) then
150  call atmos_hydrometeor_lhv( ka, ks, ke, temp(:,i,j), lhv(:) )
151 
152  do iq = 1, qla
153  do k = ks, ke
154  work = - min( qtrc(k,i,j,iq), 0.0_rp ) ! work is positive (vapor to liq)
155  if ( work > 0.0_rp ) then
156  eng(k) = eng(k) + work * lhv(k)
157  diffq(k) = diffq(k) - work
158  cvtot(k,i,j) = cvtot(k,i,j) + work * ( cv_water - cv_vapor )
159  cptot(k,i,j) = cptot(k,i,j) + work * ( cp_water - cp_vapor )
160  ! remove negative value of hydrometeors (mass)
161  qtrc(k,i,j,iq) = 0.0_rp
162  end if
163  enddo
164  enddo
165  end if
166 
167  if ( qia > 0 ) then
168  call atmos_hydrometeor_lhs( ka, ks, ke, temp(:,i,j), lhs(:) )
169 
170  do iq = qla+1, qla+qia
171  do k = ks, ke
172  work = - min( qtrc(k,i,j,iq), 0.0_rp ) ! work is positive (vapor to ice)
173  if ( work > 0.0_rp ) then
174  eng(k) = eng(k) + work * lhs(k)
175  diffq(k) = diffq(k) - work
176  cvtot(k,i,j) = cvtot(k,i,j) + work * ( cv_ice - cv_vapor )
177  cptot(k,i,j) = cptot(k,i,j) + work * ( cp_ice - cp_vapor )
178  ! remove negative value of hydrometeors (mass)
179  qtrc(k,i,j,iq) = 0.0_rp
180  end if
181  enddo
182  enddo
183  end if
184 
185 
186  if ( abs(limit_negative) > 0.0_rp ) then
187  do k = ks, ke
188  if ( diffq(k) < - abs(limit_negative) ) then
189  diffq_min = min( diffq_min, diffq(k) )
190  log_error("ATMOS_PHY_MP_negative_fixer",*) 'large negative is found'
191  log_error_cont(*) 'value = ', diffq(k), ' at (', k, ',', i, ',', j, ')'
192  end if
193  end do
194  end if
195 
196  do k = ks, ke
197  if ( diffq(k) < 0.0_rp ) then
198  ! Compensate for the lack of hydrometeors by the water vapor
199  qv(k,i,j) = qv(k,i,j) + diffq(k)
200  end if
201  end do
202 
203  if ( rhoh_out ) then
204  do k = ks, ke
205  rhoh(k,i,j) = ( eng(k) - eng0(k) ) * dens(k,i,j)
206  end do
207  end if
208 
209 
210  if ( dens_out ) then
211  do k = ks, ke
212  dens0(k) = dens(k,i,j)
213  end do
214  end if
215  if ( engi_out ) then
216  do k = ks, ke
217  eng0(k) = eng(k) * dens(k,i,j)
218  end do
219  end if
220 
221  ! fix negative QV
222  do k = ks, ke
223  work = - min( qv(k,i,j), 0.0_rp )
224  if ( work > 0.0_rp ) then
225  qv(k,i,j) = 0.0_rp
226  dens(k,i,j) = dens(k,i,j) * ( 1.0_rp + work ) ! not to change mass of dry air
227  cvtot(k,i,j) = ( cvtot(k,i,j) + work * cv_vapor ) / ( 1.0_rp + work )
228  cptot(k,i,j) = ( cptot(k,i,j) + work * cp_vapor ) / ( 1.0_rp + work )
229  eng(k) = ( eng(k) + work * cv_vapor * temp(k,i,j) ) / ( 1.0_rp + work )
230  end if
231  enddo
232 
233  do k = ks, ke
234  ! update
235  temp(k,i,j) = eng(k) / cvtot(k,i,j)
236  end do
237 
238  if ( dens_out ) then
239  do k = ks, ke
240  dens_diff(k,i,j) = dens(k,i,j) - dens0(k)
241  end do
242  end if
243  if ( engi_out ) then
244  do k = ks, ke
245  engi_diff(k,i,j) = eng(k) * dens(k,i,j) - eng0(k)
246  end do
247  end if
248 
249  enddo
250  enddo
251 
252 
253  if ( abs(limit_negative) > 0.0_rp &
254  .AND. abs(limit_negative) < abs(diffq_min) ) then
255  log_error_cont(*) 'maximum negative hydrometeor ', diffq_min, ' < ', - abs(limit_negative)
256  call prc_abort
257  endif
258 
259  call prof_rapend('MP_filter', 3)
260 
261  return
262  end subroutine atmos_phy_mp_negative_fixer
263 
264  !-----------------------------------------------------------------------------
266  !-----------------------------------------------------------------------------
268  KA, KS, KE, IA, IS, IE, JA, JS, JE, &
269  DENS, &
270  flag_liquid, &
271  TEMP, &
272  QV, QC, QI, &
273  CPtot, CVtot, &
274  RHOE_d )
275  use scale_prc, only: &
276  prc_abort
277  use scale_atmos_hydrometeor, only: &
278  cp_vapor, &
279  cp_water, &
280  cp_ice, &
281  cv_vapor, &
282  cv_water, &
283  cv_ice, &
284  lhv, &
285  lhf
286  use scale_atmos_saturation, only: &
287  atmos_saturation_moist_conversion_dens_all, &
288  atmos_saturation_moist_conversion_dens_liq
289  implicit none
290 
291  integer, intent(in) :: KA, KS, KE
292  integer, intent(in) :: IA, IS, IE
293  integer, intent(in) :: JA, JS, JE
294 
295  real(RP), intent(in) :: DENS(ka,ia,ja)
296  logical , intent(in) :: flag_liquid
297 
298  real(RP), intent(inout) :: TEMP (ka,ia,ja)
299  real(RP), intent(inout) :: QV (ka,ia,ja)
300  real(RP), intent(inout) :: QC (ka,ia,ja)
301  real(RP), intent(inout) :: QI (ka,ia,ja)
302  real(RP), intent(inout) :: CPtot(ka,ia,ja)
303  real(RP), intent(inout) :: CVtot(ka,ia,ja)
304 
305  real(RP), intent(out) :: RHOE_d(ka,ia,ja)
306 
307  ! working
308  real(RP) :: QV1
309  real(RP) :: QC1
310  real(RP) :: QI1
311 
312  real(RP) :: Emoist ! moist internal energy
313 
314  logical :: converged, error
315 
316  integer :: k, i, j
317  !---------------------------------------------------------------------------
318 
319  call prof_rapstart('MP_Saturation_adjustment', 2)
320 
321  error = .false.
322 
323  if ( flag_liquid ) then ! warm rain
324 
325  !$omp parallel do default(none) OMP_SCHEDULE_ collapse(2) &
326  !$omp shared(KS,KE,IS,IE,JS,JE, &
327  !$omp CP_VAPOR,CP_WATER,CV_VAPOR,CV_WATER,LHV,LHF, &
328  !$omp DENS,QV,QC,TEMP,CPtot,CVtot,RHOE_d,error) &
329  !$omp private(i,j,k, &
330  !$omp QV1,QC1,Emoist,converged)
331  do j = js, je
332  do i = is, ie
333  do k = ks, ke
334 
335  qv1 = qv(k,i,j)
336  qc1 = qc(k,i,j)
337 
338  emoist = temp(k,i,j) * cvtot(k,i,j) &
339  + qv1 * lhv
340 
341  call atmos_saturation_moist_conversion_dens_liq( dens(k,i,j), emoist, & ! [IN]
342  temp(k,i,j), qv1, qc1, & ! [INOUT]
343  cptot(k,i,j), cvtot(k,i,j), & ! [INOUT]
344  converged ) ! [OUT]
345 
346  if ( .NOT. converged ) then
347  log_error("ATMOS_PHY_MP_saturation_adjustment_3D",*) 'moist_conversion not converged! ', k,i,j
348  error = .true.
349  exit
350  endif
351 
352  rhoe_d(k,i,j) = - lhv * ( qv1 - qv(k,i,j) ) * dens(k,i,j)
353 
354  qv(k,i,j) = qv1
355  qc(k,i,j) = qc1
356 
357  end do
358  end do
359  end do
360 
361  if ( error ) call prc_abort
362 
363  else ! cold rain
364 
365  !$omp parallel do default(none) OMP_SCHEDULE_ collapse(2) &
366  !$omp shared (KS,KE,IS,IE,JS,JE, &
367  !$omp CP_VAPOR,CP_WATER,CP_ICE,CV_VAPOR,CV_WATER,CV_ICE,LHV,LHF, &
368  !$omp DENS,QV,QC,QI,TEMP,CPtot,CVtot,RHOE_d,error) &
369  !$omp private(i,j,k, &
370  !$omp QV1,QC1,QI1,Emoist,converged)
371  do j = js, je
372  do i = is, ie
373  do k = ks, ke
374  qv1 = qv(k,i,j)
375  qc1 = qc(k,i,j)
376  qi1 = qi(k,i,j)
377 
378  emoist = temp(k,i,j) * cvtot(k,i,j) &
379  + qv1 * lhv &
380  - qi1 * lhf
381 
382  call atmos_saturation_moist_conversion_dens_all( dens(k,i,j), emoist, & ! [IN]
383  temp(k,i,j), qv1, qc1, qi1, & ! [INOUT]
384  cptot(k,i,j), cvtot(k,i,j), & ! [INOUT]
385  converged ) ! [OUT]
386 
387  if ( .NOT. converged ) then
388  log_error("ATMOS_PHY_MP_saturation_adjustment_3D",*) 'moist_conversion not converged! ', k,i,j
389  error = .true.
390  exit
391  endif
392 
393  rhoe_d(k,i,j) = ( - lhv * ( qv1 - qv(k,i,j) ) &
394  + lhf * ( qi1 - qi(k,i,j) ) ) * dens(k,i,j)
395 
396  qv(k,i,j) = qv1
397  qc(k,i,j) = qc1
398  qi(k,i,j) = qi1
399 
400  end do
401  end do
402  end do
403 
404  if ( error ) call prc_abort
405  endif
406 
407  call prof_rapend ('MP_Saturation_adjustment', 2)
408 
409  return
411 
412  !-----------------------------------------------------------------------------
413 !OCL SERIAL
415  KA, KS, KE, QHA, QLA, QIA, &
416  TEMP, vterm, FDZ, RCDZ, dt, &
417  i, j, &
418  DENS, RHOQ, CPtot, CVtot, RHOE, &
419  mflx, sflx )
420  use scale_const, only: &
421  grav => const_grav
422  use scale_atmos_hydrometeor, only: &
423  cp_water, &
424  cp_ice, &
425  cv_water, &
426  cv_ice
427  implicit none
428  integer, intent(in) :: KA, KS, KE
429  integer, intent(in) :: QHA, QLA, QIA
430 
431  real(RP), intent(in) :: TEMP (ka)
432  real(RP), intent(in) :: vterm(ka,qha) ! terminal velocity of cloud mass
433  real(RP), intent(in) :: FDZ (ka)
434  real(RP), intent(in) :: RCDZ (ka)
435  real(DP), intent(in) :: dt
436  integer, intent(in) :: i, j ! for debug
437 
438  real(RP), intent(inout) :: DENS (ka)
439  real(RP), intent(inout) :: RHOQ (ka,qha)
440  real(RP), intent(inout) :: CPtot(ka)
441  real(RP), intent(inout) :: CVtot(ka)
442  real(RP), intent(inout) :: RHOE (ka)
443 
444  real(RP), intent(out) :: mflx (ka)
445  real(RP), intent(out) :: sflx (2)
446 
447  real(RP) :: vtermh(ka)
448  real(RP) :: qflx (ka)
449  real(RP) :: eflx (ka)
450  real(RP) :: RHOCP (ka)
451  real(RP) :: RHOCV (ka)
452  real(RP) :: dDENS
453  real(RP) :: CP, CV
454 
455  integer :: k, iq
456  !---------------------------------------------------------------------------
457 
458  ! tracer/energy transport by falldown
459  ! 1st order upwind, forward euler, velocity is always negative
460 
461  mflx(:) = 0.0_rp
462  sflx(:) = 0.0_rp
463  qflx(ke) = 0.0_rp
464  eflx(ke) = 0.0_rp
465 
466  do k = ks, ke
467  rhocp(k) = cptot(k) * dens(k)
468  rhocv(k) = cvtot(k) * dens(k)
469  end do
470 
471  do iq = 1, qha
472  do k = ks, ke-1
473  vtermh(k) = 0.5_rp * ( vterm(k+1,iq) + vterm(k,iq) )
474  enddo
475  vtermh(ks-1) = vterm(ks,iq)
476 
477  !--- mass flux for each tracer, upwind with vel < 0
478  do k = ks-1, ke-1
479  qflx(k) = vtermh(k) * rhoq(k+1,iq)
480  enddo
481 
482  !--- update falling tracer
483  do k = ks, ke
484  rhoq(k,iq) = rhoq(k,iq) - dt * ( qflx(k) - qflx(k-1) ) * rcdz(k)
485  enddo ! falling (water mass & number) tracer
486 
487  ! QTRC(iq; iq>QLA+QLI) is not mass tracer, such as number density
488  if ( iq > qla + qia ) cycle
489 
490  do k = ks-1, ke-1
491  mflx(k) = mflx(k) + qflx(k)
492  end do
493 
494  if ( iq > qla ) then ! ice water
495  cp = cp_ice
496  cv = cv_ice
497  sflx(2) = sflx(2) + qflx(ks-1)
498  else ! liquid water
499  cp = cp_water
500  cv = cv_water
501  sflx(1) = sflx(1) + qflx(ks-1)
502  end if
503 
504  !--- update density
505  do k = ks, ke
506  ddens = - ( qflx(k) - qflx(k-1) ) * rcdz(k) * dt
507  rhocp(k) = rhocp(k) + cp * ddens
508  rhocv(k) = rhocv(k) + cv * ddens
509  dens(k) = dens(k) + ddens
510  end do
511 
512  ! internal energy flux
513  do k = ks-1, ke-1
514  eflx(k) = qflx(k) * temp(k+1) * cv &
515  + qflx(k) * fdz(k) * grav ! potential energy
516  end do
517  !--- update internal energy
518  do k = ks, ke
519  rhoe(k) = rhoe(k) - ( eflx(k) - eflx(k-1) ) * rcdz(k) * dt
520  end do
521 
522  end do
523 
524  do k = ks, ke
525  cptot(k) = rhocp(k) / dens(k)
526  cvtot(k) = rhocv(k) / dens(k)
527  end do
528 
529  return
530  end subroutine atmos_phy_mp_precipitation_upwind
531 
532  !-----------------------------------------------------------------------------
533 !OCL SERIAL
535  KA, KS, KE, QHA, QLA, QIA, &
536  TEMP, vterm, FZ, FDZ, RCDZ, dt, &
537  i, j, &
538  DENS, RHOQ, CPtot, CVtot, RHOE, &
539  mflx, sflx )
540  use scale_const, only: &
541  grav => const_grav
542  use scale_atmos_hydrometeor, only: &
543  cp_water, &
544  cp_ice, &
545  cv_water, &
546  cv_ice
547  implicit none
548  integer, intent(in) :: KA, KS, KE
549  integer, intent(in) :: QHA, QLA, QIA
550 
551  real(RP), intent(in) :: TEMP (ka)
552  real(RP), intent(in) :: vterm(ka,qha) ! terminal velocity of cloud mass
553  real(RP), intent(in) :: FZ (ka)
554  real(RP), intent(in) :: FDZ (ka)
555  real(RP), intent(in) :: RCDZ (ka)
556  real(DP), intent(in) :: dt
557  integer, intent(in) :: i, j ! for debug
558 
559  real(RP), intent(inout) :: DENS (ka)
560  real(RP), intent(inout) :: RHOQ (ka,qha)
561  real(RP), intent(inout) :: CPtot(ka)
562  real(RP), intent(inout) :: CVtot(ka)
563  real(RP), intent(inout) :: RHOE (ka)
564 
565  real(RP), intent(out) :: mflx (ka)
566  real(RP), intent(out) :: sflx (2)
567 
568  real(RP) :: qflx(ka)
569  real(RP) :: eflx(ka)
570  real(RP) :: RHOCP(ka)
571  real(RP) :: RHOCV(ka)
572  real(RP) :: dDENS
573  real(RP) :: CP, CV
574 
575  real(RP) :: vtermh(ka)
576  real(RP) :: dvterm(ka)
577  real(RP) :: cdz (ka)
578  real(RP) :: rfdz2 (ka)
579  real(RP) :: dist (ka)
580  real(RP) :: Z_src
581  real(RP) :: flx
582  integer :: k_src (ka)
583  integer :: k_dst
584 
585  integer :: k, iq
586  !---------------------------------------------------------------------------
587 
588  ! tracer/energy transport by falldown
589  ! velocity is always negative
590 
591  mflx(:) = 0.0_rp
592  sflx(:) = 0.0_rp
593  qflx(:) = 0.0_rp
594  eflx(:) = 0.0_rp
595 
596  do k = ks, ke
597  rhocp(k) = cptot(k) * dens(k)
598  rhocv(k) = cvtot(k) * dens(k)
599  end do
600 
601  do k = ks, ke
602  cdz(k) = 1.0_rp / rcdz(k)
603  end do
604  do k = ks, ke-1
605  rfdz2(k) = 1.0_rp / ( cdz(k) + cdz(k+1) )
606  end do
607 
608  do iq = 1, qha
609  do k = ks, ke-1
610  vtermh(k) = ( cdz(k) * vterm(k+1,iq) + cdz(k+1) * vterm(k,iq) ) * rfdz2(k)
611  enddo
612  vtermh(ks-1) = vterm(ks,iq)
613 
614  do k = ks, ke
615  dvterm(k) = vtermh(k) - vtermh(k-1)
616  enddo
617 
618  ! Movement distance of the cell wall by the fall
619  ! the midpoint method (second-order Runge-Kutta)
620  ! dz/dt = v(z + v dt/2) ~ v(z) + v dt/2 dv/dz + 1/2 (v dt/2)^2 d^2v/dz^2
621  do k = ks, ke-1
622  dist(k) = - vtermh(k) * dt &
623  + vtermh(k) * dt**2 / 2.0_rp * ( dvterm(k+1)+dvterm(k) ) * rfdz2(k) &
624  - vtermh(k)**2 * dt**3 / 4.0_rp * ( dvterm(k+1)*rcdz(k+1) - dvterm(k)*rcdz(k) ) * rfdz2(k)
625  dist(k) = max( dist(k), 0.0_rp )
626  enddo
627  dist(ks-1) = - vtermh(ks-1) * dt &
628  + vtermh(ks-1) * dt**2 / 2.0_rp * dvterm(ks)*rcdz(ks)
629  dist(ks-1) = max( dist(ks-1), 0.0_rp )
630 
631  ! wall cannot overtake
632  do k = ke-2, ks-1, -1
633  dist(k) = min( dist(k), dist(k+1) + cdz(k+1) )
634  end do
635 
636 ! LOG_INFO_CONT(*) "distance", iq
637 ! do k = KA, 1, -1
638 ! LOG_INFO_CONT('(1x,I5,3F9.3,ES15.5)') k, dist(k), vtermh(k), vterm(k,iq), RHOQ(k,iq)
639 ! enddo
640 
641  ! search number of source cell
642  do k_dst = ks-1, ke-1
643  z_src = fz(k_dst) + dist(k_dst)
644 
645  k_src(k_dst) = k_dst
646  do k = k_dst, ke-1
647  if ( z_src > fz(k ) &
648  .AND. z_src <= fz(k+1) ) then
649  k_src(k_dst) = k
650  endif
651  enddo
652  if ( z_src > fz(ke) ) k_src(k_dst) = ke
653  enddo
654 
655 ! LOG_INFO_CONT(*) "seek", iq
656 ! do k = KA, 1, -1
657 ! LOG_INFO_CONT('(1x,2I5,2F9.3)') k, k_src(k), FZ(k), FZ(k)+dist(k)
658 ! enddo
659 
660  if ( iq > qla ) then ! ice water
661  cp = cp_ice
662  cv = cv_ice
663  else ! liquid water
664  cp = cp_water
665  cv = cv_water
666  end if
667 
668  do k_dst = ks-1, ke-1
669  do k = k_dst, k_src(k_dst)-1
670  flx = rhoq(k+1,iq) * cdz(k+1) / dt ! sum column mass rhoq*dz
671  qflx(k_dst) = qflx(k_dst) - flx
672  eflx(k_dst) = eflx(k_dst) - flx * temp(k+1) * cv ! internal energy flux
673  dist(k_dst) = dist(k_dst) - cdz(k+1) ! residual
674  enddo
675  if ( k_src(k_dst) < ke ) then
676  ! residual (simple upwind)
677  flx = rhoq(k_src(k_dst)+1,iq) * dist(k_dst) / dt
678  qflx(k_dst) = qflx(k_dst) - flx ! sum column mass rhoq*dz
679  eflx(k_dst) = eflx(k_dst) -flx * temp(k_src(k_dst)+1) * cv ! internal energy flux
680  end if
681 
682  eflx(k_dst) = eflx(k_dst) + qflx(k) * fdz(k_dst) * grav ! potential energy
683  enddo
684 
685 ! LOG_INFO_CONT(*) "flux", iq
686 ! do k = KA, 1, -1
687 ! LOG_INFO_CONT('(1x,2I5,F9.3,2ES15.5)') k, k_src(k), dist(k), qflx(k), vtermh(k)*RHOQ(k+1,iq)
688 ! enddo
689 
690  !--- update falling tracer
691  do k = ks, ke
692  rhoq(k,iq) = rhoq(k,iq) - dt * ( qflx(k) - qflx(k-1) ) * rcdz(k)
693  enddo ! falling (water mass & number) tracer
694 
695 ! LOG_INFO_CONT(*) "tendency", iq
696 ! do k = KA, 1, -1
697 ! LOG_INFO_CONT('(1x,I5,ES15.5)') k, - dt * ( qflx(k) - qflx(k-1) ) * RCDZ(k)
698 ! enddo
699 
700  ! QTRC(iq; iq>QLA+QLI) is not mass tracer, such as number density
701  if ( iq > qla + qia ) cycle
702 
703  do k = ks-1, ke-1
704  mflx(k) = mflx(k) + qflx(k)
705  end do
706 
707  if ( iq > qla ) then ! ice water
708  sflx(2) = sflx(2) + qflx(ks-1)
709  else ! liquid water
710  sflx(1) = sflx(1) + qflx(ks-1)
711  end if
712 
713  !--- update density
714  do k = ks, ke
715  ddens = - ( qflx(k) - qflx(k-1) ) * rcdz(k) * dt
716  rhocp(k) = rhocp(k) + cp * ddens
717  rhocv(k) = rhocv(k) + cv * ddens
718  dens(k) = dens(k) + ddens
719  end do
720 
721  !--- update internal energy
722  do k = ks, ke
723  rhoe(k) = rhoe(k) - ( eflx(k) - eflx(k-1) ) * rcdz(k) * dt
724  end do
725 
726  end do
727 
728  do k = ks, ke
729  cptot(k) = rhocp(k) / dens(k)
730  cvtot(k) = rhocv(k) / dens(k)
731  end do
732 
733  return
735 
736  !-----------------------------------------------------------------------------
737 !OCL SERIAL
739  KA, KS, KE, &
740  DENS, MOMZ, U, V, mflx, &
741  RCDZ, RFDZ, &
742  MOMZ_t, RHOU_t, RHOV_t )
743  implicit none
744 
745  integer, intent(in) :: KA, KS, KE
746  real(RP), intent(in) :: DENS (ka)
747  real(RP), intent(in) :: MOMZ (ka)
748  real(RP), intent(in) :: U (ka)
749  real(RP), intent(in) :: V (ka)
750  real(RP), intent(in) :: mflx (ka)
751  real(RP), intent(in) :: RCDZ (ka)
752  real(RP), intent(in) :: RFDZ (ka)
753  real(RP), intent(out) :: MOMZ_t(ka)
754  real(RP), intent(out) :: RHOU_t(ka)
755  real(RP), intent(out) :: RHOV_t(ka)
756 
757  real(RP) :: flx(ka)
758 
759  integer :: k
760  !---------------------------------------------------------------------------
761 
762  flx(ke) = 0.0_rp
763 
764  !--- momentum z (half level)
765  do k = ks, ke-1
766  flx(k) = ( mflx(k) + mflx(k-1) ) * momz(k) / ( dens(k+1) + dens(k) )
767  enddo
768  do k = ks, ke-1
769  momz_t(k) = - ( flx(k+1) - flx(k) ) * rfdz(k)
770  enddo
771  momz_t(ke) = 0.0_rp
772 
773  !--- momentum x
774  do k = ks-1, ke-1
775  flx(k) = mflx(k) * u(k+1)
776  enddo
777  do k = ks, ke
778  rhou_t(k) = - ( flx(k) - flx(k-1) ) * rcdz(k)
779  enddo
780 
781  !--- momentum y
782  do k = ks-1, ke-1
783  flx(k) = mflx(k) * v(k+1)
784  enddo
785  do k = ks, ke
786  rhov_t(k) = - ( flx(k) - flx(k-1) ) * rcdz(k)
787  enddo
788 
789  return
791 
792 end module scale_atmos_phy_mp_common
real(rp), public const_cvdry
specific heat (dry air,constant volume) [J/kg/K]
Definition: scale_const.F90:57
real(rp), public const_cpdry
specific heat (dry air,constant pressure) [J/kg/K]
Definition: scale_const.F90:56
module atmosphere / saturation
real(rp), public cv_ice
CV for ice [J/kg/K].
real(rp), public cp_ice
CP for ice [J/kg/K].
module ATMOSPHERE / Physics Cloud Microphysics - Common
module TRACER
real(rp), public cv_vapor
CV for vapor [J/kg/K].
module atmosphere / hydrometeor
module atmosphere / grid / cartesC index
module PROCESS
Definition: scale_prc.F90:11
real(rp), public const_grav
standard acceleration of gravity [m/s2]
Definition: scale_const.F90:46
subroutine, public atmos_phy_mp_precipitation_semilag(KA, KS, KE, QHA, QLA, QIA, TEMP, vterm, FZ, FDZ, RCDZ, dt, i, j, DENS, RHOQ, CPtot, CVtot, RHOE, mflx, sflx)
subroutine, public atmos_phy_mp_precipitation_momentum(KA, KS, KE, DENS, MOMZ, U, V, mflx, RCDZ, RFDZ, MOMZ_t, RHOU_t, RHOV_t)
subroutine atmos_phy_mp_saturation_adjustment_3d(KA, KS, KE, IA, IS, IE, JA, JS, JE, DENS, flag_liquid, TEMP, QV, QC, QI, CPtot, CVtot, RHOE_d)
Saturation adjustment.
real(rp), public lhf
latent heat of fusion for use [J/kg]
subroutine, public prc_abort
Abort Process.
Definition: scale_prc.F90:338
real(rp), public lhv
latent heat of vaporization for use [J/kg]
module CONSTANT
Definition: scale_const.F90:11
subroutine, public prof_rapstart(rapname_base, level)
Start raptime.
Definition: scale_prof.F90:157
module profiler
Definition: scale_prof.F90:11
subroutine, public atmos_phy_mp_precipitation_upwind(KA, KS, KE, QHA, QLA, QIA, TEMP, vterm, FDZ, RCDZ, dt, i, j, DENS, RHOQ, CPtot, CVtot, RHOE, mflx, sflx)
module PRECISION
module STDIO
Definition: scale_io.F90:10
subroutine, public prof_rapend(rapname_base, level)
Save raptime.
Definition: scale_prof.F90:210
real(rp), public cp_vapor
CP for vapor [J/kg/K].
real(rp), public cp_water
CP for water [J/kg/K].
real(rp), public cv_water
CV for water [J/kg/K].
subroutine, public atmos_phy_mp_negative_fixer(KA, KS, KE, IA, IS, IE, JA, JS, JE, QLA, QIA, limit_negative, DENS, TEMP, CVtot, CPtot, QV, QTRC, RHOH, DENS_diff, ENGI_diff)
ATMOS_PHY_MP_negative_fixer negative fixer.