22 subroutine progomega_calc(first_time_step,flag_restart,im,km,kbcon1,ktcon,omegain,delt,del, &
23 zi,cnvflg,omegaout,grav,buo,drag,wush,lbb1,lbb2,lbb3,dt_decay)
25 use machine,
only : kind_phys
29 integer,
intent(in) :: im,km
30 integer,
intent(in) :: kbcon1(im),ktcon(im)
32 real(kind=kind_phys),
intent(in) :: delt,grav
33 real(kind=kind_phys),
intent(in) :: lbb1,lbb2,lbb3,dt_decay
34 real(kind=kind_phys),
intent(in) :: omegain(im,km)
35 real(kind=kind_phys),
intent(in) :: del(im,km),zi(im,km)
36 real(kind=kind_phys),
intent(in) :: drag(im,km)
37 real(kind=kind_phys),
intent(in) :: buo(im,km)
38 real(kind=kind_phys),
intent(in) :: wush(im,km)
40 real(kind=kind_phys),
intent(inout) :: omegaout(im,km)
42 logical,
intent(in) :: cnvflg(im)
43 logical,
intent(in) :: first_time_step
44 logical,
intent(in) :: flag_restart
53 real(kind=kind_phys) :: omega(im,km)
54 real(kind=kind_phys) :: omega_new(im,km)
55 real(kind=kind_phys) :: omega_start(im,km)
57 real(kind=kind_phys) :: terma(im,km)
58 real(kind=kind_phys) :: termb(im,km)
59 real(kind=kind_phys) :: termc(im,km)
60 real(kind=kind_phys) :: memory_term,buoy_term,adv_term
61 real(kind=kind_phys) :: decay_fac
66 real(kind=kind_phys) :: dp,dz,pi_conv,discr
67 real(kind=kind_phys) :: rhs_exp
69 real(kind=kind_phys) :: omega_eps
70 real(kind=kind_phys) :: a_eps,b_eps,disc_eps
72 real(kind=kind_phys) :: cfl_target
73 real(kind=kind_phys) :: dt_sub
74 real(kind=kind_phys) :: dt_remaining
75 real(kind=kind_phys) :: dt_cfl
76 real(kind=kind_phys) :: time_done
80 logical :: active_point_found
87 cfl_target = 0.8_kind_phys
89 omega_eps = 1.0e-5_kind_phys
90 a_eps = 1.0e-12_kind_phys
91 b_eps = 1.0e-12_kind_phys
92 disc_eps = 1.0e-12_kind_phys
95 decay_fac = exp(-delt/dt_decay)
104 terma(i,k) = 0.0_kind_phys
105 termb(i,k) = 0.0_kind_phys
106 termc(i,k) = 0.0_kind_phys
108 omega(i,k) = omegain(i,k)
109 omega_new(i,k) = omegain(i,k)
110 omegaout(i,k) = omegain(i,k)
122 if (.not. cnvflg(i))
then
124 omega(i,k) = omegain(i,k)
125 omega_new(i,k) = omega(i,k)
126 omegaout(i,k) = omega(i,k)
131 if (abs(omega(i,k)) < omega_eps)
then
133 omega(i,k) = 0.0_kind_phys
134 omega_new(i,k) = 0.0_kind_phys
135 omegaout(i,k) = 0.0_kind_phys
151 if (.not. cnvflg(i))
then
153 omega(i,k) = omegain(i,k) * decay_fac
154 omega_new(i,k) = omega(i,k)
155 omegaout(i,k) = omega(i,k)
160 if (abs(omega(i,k)) < omega_eps)
then
162 omega(i,k) = 0.0_kind_phys
163 omega_new(i,k) = 0.0_kind_phys
164 omegaout(i,k) = 0.0_kind_phys
175 if (first_time_step .and. .not. flag_restart)
then
182 if (k >= kbcon1(i) .and. k < ktcon(i))
then
184 omega(i,k) = -1.2_kind_phys
185 omega_new(i,k) = -1.2_kind_phys
186 omegaout(i,k) = -1.2_kind_phys
201 time_done = 0.0_kind_phys
205 omega_start(:,:) = omega(:,:)
207 do while (time_done < delt)
209 dt_remaining = delt - time_done
218 dt_cfl = dt_remaining
219 active_point_found = .false.
225 if (k > kbcon1(i) .and. k < ktcon(i))
then
226 dp = 1000.0_kind_phys * del(i,k)
227 if (dp > 0.0_kind_phys)
then
228 active_point_found = .true.
229 if (abs(omega(i,k)) > omega_eps)
then
230 dt_cfl = min(dt_cfl, &
231 cfl_target * dp / abs(omega(i,k)))
241 if (.not. active_point_found)
exit
243 dt_sub = min(dt_remaining,dt_cfl)
246 if (dt_sub <= 1.0e-8_kind_phys)
then
247 dt_sub = dt_remaining
257 omega_new(:,:) = omega(:,:)
268 if (k >= kbcon1(i) .and. k < ktcon(i))
then
270 omega_new(i,kbcon1(i)) = 0.0_kind_phys
272 dp = 1000.0_kind_phys * del(i,k)
273 dz = zi(i,k+1) - zi(i,k)
275 if (dp <= 0.0_kind_phys) cycle
276 if (abs(dz) <= 1.0e-12_kind_phys) cycle
284 memory_term = omega(i,k)
286 buoy_term = -0.5_kind_phys * dt_sub * lbb2 &
289 if (k == kbcon1(i))
then
290 adv_term = 0.0_kind_phys
292 adv_term = -dt_sub * omega(i,k) &
293 * (omega(i,k-1)-omega(i,k)) / dp
296 rhs_exp = memory_term + buoy_term + adv_term
304 terma(i,k) = -0.5_kind_phys * dt_sub * lbb1 &
305 * drag(i,k) / pi_conv
307 termb(i,k) = 1.0_kind_phys &
308 + 0.5_kind_phys * dt_sub * wush(i,k)
310 termc(i,k) = -rhs_exp
316 if (abs(terma(i,k)) < a_eps)
then
318 if (abs(termb(i,k)) > b_eps)
then
319 omega_new(i,k) = -termc(i,k) / termb(i,k)
322 omega_new(i,k) = omega(i,k)
327 discr = termb(i,k)**2 &
328 - 4.0_kind_phys * terma(i,k) * termc(i,k)
330 if (discr >= -disc_eps)
then
332 discr = max(discr,0.0_kind_phys)
335 (-termb(i,k) + sqrt(discr)) &
336 / (2.0_kind_phys * terma(i,k))
341 omega_new(i,k) = omega(i,k)
351 omega_new(i,k) = max( &
352 min(omega_new(i,k),-1.2_kind_phys), &
366 omega(:,:) = omega_new(:,:)
368 time_done = time_done + dt_sub
372 if (delt-time_done < 1.0e-8_kind_phys*delt)
then
382 omegaout(:,:) = omega(:,:)