1 ! Generated by TAPENADE (INRIA, Tropics team)
2 ! Tapenade 3.3 (r3163) - 09/25/2009 09:04
4 MODULE A_MODULE_MP_MKESSLER
8 ! Differentiation of kessler in reverse (adjoint) mode:
9 ! gradient, with respect to input variables: qc p t qr qv rainnc
11 ! of linear combination of output variables: qc p t qr qv rainnc
14 SUBROUTINE A_MKESSLER(t, tb, qv, qvb, qc, qcb, qr, qrb, rho, rhob, p, &
15 & pb, pii, piib, dt_in, z, xlv, cp, ep2, svp1, svp2, svp3, svpt0, &
16 & rhowater, dz8w, rainnc, rainncb, rainncv, rainncvb, ids, ide, jds, &
17 & jde, kds, kde, ims, ime, jms, jme, kms, kme, its, ite, jts, jte, kts&
20 USE module_mp_mkessler, ONLY : SMALLSTEP, RFALL, AUTOCA, SATADJ
23 !----------------------------------------------------------------
24 ! Restructered from WRF Kessler Warm rain process
25 ! H.L. Wang Aug. 1 2009
26 !----------------------------------------------------------------
27 REAL, PARAMETER :: c1=.001
28 REAL, PARAMETER :: c2=.001
29 REAL, PARAMETER :: c3=2.2
30 REAL, PARAMETER :: c4=.875
31 !----------------------------------------------------------------
32 INTEGER, INTENT(IN) :: ids, ide, jds, jde, kds, kde, ims, ime, jms, &
33 & jme, kms, kme, its, ite, jts, jte, kts, kte
34 REAL, INTENT(IN) :: xlv, cp
35 REAL, INTENT(IN) :: ep2, svp1, svp2, svp3, svpt0
36 REAL, INTENT(IN) :: rhowater
37 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(INOUT) :: t, qv, &
39 REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: tb, qvb, qcb, qrb
40 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN) :: rho, p, &
42 REAL, DIMENSION(ims:ime, kms:kme, jms:jme) :: rhob, pb, piib
43 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN) :: z
44 REAL, INTENT(IN) :: dt_in
45 REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: rainnc, rainncv
46 REAL, DIMENSION(ims:ime, jms:jme) :: rainncb, rainncvb
48 REAL :: qrprod, ern, gam, rcgs, rcgsi
49 REAL, DIMENSION(its:ite, kts:kte, jts:jte) :: prod
50 REAL, DIMENSION(kts:kte) :: vt, prodk, vtden, rdzk, rhok, piik, &
52 REAL, DIMENSION(kts:kte) :: rhokb, piikb
54 INTEGER :: nfall, n, nfall_new
55 REAL :: qrr, pressure, temp, es, qvs, dz, dt
56 REAL :: f5, dtfall, rdz, product
57 REAL :: vtmax, crmax, factorn
58 REAL :: qcr, factorr, ppt
59 REAL, PARAMETER :: max_cr_sedimentation=0.75
60 !----------------------------------------------------------------
63 REAL, DIMENSION(kts:kte) :: qv1d, qc1d, qr1d, t1d, p1d
64 REAL, DIMENSION(kts:kte) :: qv1db, qc1db, qr1db, t1db, p1db
65 REAL :: dtleft, rainncv0, max_cr
67 INTEGER :: kvts, kvte, kn
71 ! print*,its,ite,jts,jte
72 ! print*,ims,ime,jms,jme
73 ! print*,ids,ide,jds,jde
79 rdzk(k) = 1./(z(i, k+1, j)-z(i, k, j))
81 rdzk(kte) = 1./(z(i, kte, j)-z(i, kte-1, j))
91 CALL PUSHREAL8(p1d(k))
93 CALL PUSHREAL8(rhok(k))
94 rhok(k) = rho(i, k, j)
95 CALL PUSHREAL8(piik(k))
96 piik(k) = pii(i, k, j)
97 rdzw(k) = 1./dz8w(i, k, j)
99 CALL PUSHINTEGER4(kvts)
102 CALL PUSHINTEGER4(kvte)
104 CALL PUSHREAL8(dtleft)
106 CALL SMALLSTEP(qr1d, rdzk, rdzw, rhok, max_cr, dtleft, nfall, &
110 CALL PUSHREAL8ARRAY(qr1d, kte - kts + 1)
111 CALL RFALL(qr1d, rdzk, rdzw, rhok, rainncv0, rhowater, max_cr&
112 & , dtleft, kvts, kvte)
114 CALL PUSHINTEGER4(kn - 1)
115 CALL PUSHREAL8ARRAY(qr1d, kte - kts + 1)
116 CALL PUSHREAL8ARRAY(qc1d, kte - kts + 1)
118 !autoca(qc1d,qr1d, kvts,kvte,c1,c2,c3,c4,dt )
119 !autoca(qc1d,qr1d, kvts,kvte,c1,c2,c3,c4,dt )
120 CALL AUTOCA(qc1d, qr1d, kvts, kvte, c1, c2, c3, c4, dt)
121 CALL PUSHREAL8ARRAY(t1d, kte - kts + 1)
122 CALL PUSHREAL8ARRAY(qr1d, kte - kts + 1)
123 CALL PUSHREAL8ARRAY(qc1d, kte - kts + 1)
124 CALL PUSHREAL8ARRAY(qv1d, kte - kts + 1)
125 !satadj(qv,qc,qr, tmp, pii,rho, kvts,kvte,xlv, cp,EP2,SVP1,SVP2,SVP3,SVPT0)
126 CALL SATADJ(qv1d, qc1d, qr1d, t1d, p1d, piik, rhok, kvts, kvte, &
127 & xlv, dt, cp, ep2, svp1, svp2, svp3, svpt0)
140 t1db(k) = t1db(k) + tb(i, k, j)
142 qr1db(k) = qr1db(k) + qrb(i, k, j)
144 qc1db(k) = qc1db(k) + qcb(i, k, j)
146 qv1db(k) = qv1db(k) + qvb(i, k, j)
149 CALL POPREAL8ARRAY(qv1d, kte - kts + 1)
150 CALL POPREAL8ARRAY(qc1d, kte - kts + 1)
151 CALL POPREAL8ARRAY(qr1d, kte - kts + 1)
152 CALL POPREAL8ARRAY(t1d, kte - kts + 1)
153 CALL SATADJ_B(qv1d, qv1db, qc1d, qc1db, qr1d, qr1db, t1d, t1db, &
154 & p1d, p1db, piik, piikb, rhok, rhokb, kvts, kvte, xlv, dt&
155 & , cp, ep2, svp1, svp2, svp3, svpt0)
156 CALL POPREAL8ARRAY(qc1d, kte - kts + 1)
157 CALL POPREAL8ARRAY(qr1d, kte - kts + 1)
158 CALL AUTOCA_B(qc1d, qc1db, qr1d, qr1db, kvts, kvte, c1, c2, c3, &
160 rainncvb(i, j) = rainncvb(i, j) + rainncb(i, j)
161 CALL POPINTEGER4(ad_to)
163 rainncv0b = rainncvb(i, j)
164 CALL POPREAL8ARRAY(qr1d, kte - kts + 1)
165 CALL RFALL_B(qr1d, qr1db, rdzk, rdzw, rhok, rhokb, rainncv0, &
166 & rainncv0b, rhowater, max_cr, dtleft, kvts, kvte)
169 CALL POPREAL8(dtleft)
170 CALL POPINTEGER4(kvte)
171 CALL POPINTEGER4(kvts)
173 CALL POPREAL8(piik(k))
174 piib(i, k, j) = piib(i, k, j) + piikb(k)
176 CALL POPREAL8(rhok(k))
177 rhob(i, k, j) = rhob(i, k, j) + rhokb(k)
179 CALL POPREAL8(p1d(k))
180 pb(i, k, j) = pb(i, k, j) + p1db(k)
182 tb(i, k, j) = tb(i, k, j) + t1db(k)
184 qrb(i, k, j) = qrb(i, k, j) + qr1db(k)
186 qcb(i, k, j) = qcb(i, k, j) + qc1db(k)
188 qvb(i, k, j) = qvb(i, k, j) + qv1db(k)
193 END SUBROUTINE A_MKESSLER
195 ! Differentiation of rfall in reverse (adjoint) mode:
196 ! gradient, with respect to input variables: prodk rhok
197 ! of linear combination of output variables: prodk rainncv0 rhok
198 SUBROUTINE RFALL_B(prodk, prodkb, rdzk, rdzw, rhok, rhokb, rainncv0, &
199 & rainncv0b, rhowat, max_cr, dtfall, kvts, kvte)
201 INTEGER :: k, kvts, kvte
202 REAL, DIMENSION(kvts:kvte) :: vtden, vt, prodk, factor, rdzk, rdzw, &
204 REAL, DIMENSION(kvts:kvte) :: vtdenb, vtb, prodkb, factorb, rhokb
205 REAL :: rainncv0, rhowat, max_cr, ppt, dtleft
206 REAL :: rainncv0b, pptb
220 IF (prodk(k) .LT. 0) THEN
229 qrr = prodk(k)*0.001*rhok(k)
231 arg1 = rhok(1)/rhok(k)
232 vtden(k) = SQRT(arg1)
233 IF (qrr/(0.001*rhok(k)) .GE. 1d-5) THEN
234 vt(k) = 36.34*qrr**0.1364*vtden(k)
243 factor(k) = dtfall*rdzk(k)/rhok(k)
245 factor(kvte) = dtfall*rdzk(kvte)
250 !------------------------------------------------------------------------------
251 ! Time split loop, Fallout done with flux upstream
252 !------------------------------------------------------------------------------
254 CALL PUSHREAL8(prodk(k))
255 prodk(k) = prodk(k) - factor(k)*(rhok(k)*prodk(k)*vt(k)-rhok(k+1)*&
256 & prodk(k+1)*vt(k+1))
259 CALL PUSHREAL8(prodk(k))
260 prodk(k) = prodk(k) - factor(k)*prodk(k)*vt(k)
263 IF (prodk(k) .LT. 0) THEN
270 CALL POPINTEGER4(branch)
271 IF (.NOT.branch .LT. 2) prodkb(k) = 0.0
276 CALL POPREAL8(prodk(k))
277 factorb(k) = -(vt(k)*prodk(k)*prodkb(k))
278 vtb(k) = -(factor(k)*prodk(k)*prodkb(k))
279 prodkb(k) = (1.0-vt(k)*factor(k))*prodkb(k)
281 CALL POPREAL8(prodk(k))
282 temp = rhok(k+1)*prodk(k+1)
283 temp0 = rhok(k)*prodk(k)
284 temp0b = -(factor(k)*prodkb(k))
285 tempb1 = -(vt(k+1)*temp0b)
286 factorb(k) = factorb(k) - (temp0*vt(k)-temp*vt(k+1))*prodkb(k)
287 rhokb(k) = rhokb(k) + vt(k)*prodk(k)*temp0b
288 vtb(k) = vtb(k) + temp0*temp0b
289 rhokb(k+1) = rhokb(k+1) + prodk(k+1)*tempb1
290 prodkb(k+1) = prodkb(k+1) + rhok(k+1)*tempb1
291 vtb(k+1) = vtb(k+1) - temp*temp0b
292 prodkb(k) = vt(k)*rhok(k)*temp0b + prodkb(k)
295 pptb = 1000.*rainncv0b
296 tempb0 = dtfall*rhok(k)*pptb/rhowat
297 rhokb(k) = rhokb(k) + dtfall*prodk(k)*vt(k)*pptb/rhowat
298 prodkb(k) = prodkb(k) + vt(k)*tempb0
299 vtb(k) = vtb(k) + prodk(k)*tempb0
302 rhokb(k) = rhokb(k) - dtfall*rdzk(k)*factorb(k)/rhok(k)**2
307 CALL POPINTEGER4(branch)
308 IF (branch .LT. 2) THEN
309 qrrb = 36.34*vtden(k)*0.1364*qrr**(-0.8636)*vtb(k)
310 vtdenb(k) = vtdenb(k) + 36.34*qrr**0.1364*vtb(k)
316 IF (arg1 .EQ. 0.0) THEN
319 arg1b = vtdenb(k)/(2.0*SQRT(arg1))
323 tempb = arg1b/rhok(k)
324 rhokb(1) = rhokb(1) + tempb
325 rhokb(k) = rhokb(k) + 0.001*prodk(k)*qrrb - rhok(1)*tempb/rhok(k)
327 prodkb(k) = prodkb(k) + 0.001*rhok(k)*qrrb
330 CALL POPINTEGER4(branch)
331 IF (.NOT.branch .LT. 2) prodkb(k) = 0.0
333 END SUBROUTINE RFALL_B
335 ! Differentiation of autoca in reverse (adjoint) mode:
336 ! gradient, with respect to input variables: qc1d qr1d
337 ! of linear combination of output variables: qc1d qr1d
338 SUBROUTINE AUTOCA_B(qc1d, qc1db, qr1d, qr1db, kvts, kvte, c1, c2, c3, &
342 INTEGER :: kvts, kvte, k
343 REAL, DIMENSION(kvts:kvte) :: qc1d, qr1d
344 REAL, DIMENSION(kvts:kvte) :: qc1db, qr1db
345 REAL :: c1, c2, c3, c4
346 REAL :: qrrc, dt, factorn, qrprod, qrprod2
347 REAL :: factornb, qrprodb, qrprod2b
355 IF (qr1d(k) .LT. 0.0) THEN
361 IF (qc1d(k) .LT. 0.0) THEN
367 IF (qr1d(k) .GE. qrrc) THEN
370 CALL PUSHREAL8(factorn)
371 factorn = 1.0/(1.+c3*dt*pwr1)
374 CALL PUSHREAL8(factorn)
378 qrprod = qc1d(k)*(1.0-factorn)
380 IF (qc1d(k) - c2 .GT. 0) THEN
381 qrprod2 = factorn*c1*dt*(qc1d(k)-c2)
382 IF (qrprod2 .GT. qc1d(k) - c2) THEN
383 qrprod2 = qc1d(k) - c2
392 qrprod = qrprod + qrprod2
393 IF (qc1d(k) - qrprod .GT. 0) THEN
400 CALL POPINTEGER4(branch)
401 IF (branch .LT. 2) THEN
402 qrprodb = qr1db(k) - qc1db(k)
409 CALL POPINTEGER4(branch)
410 IF (branch .LT. 2) THEN
411 IF (branch .LT. 1) THEN
416 qc1db(k) = qc1db(k) + qrprod2b
419 temp0b = c1*dt*qrprod2b
420 factornb = (qc1d(k)-c2)*temp0b
421 qc1db(k) = qc1db(k) + factorn*temp0b
422 100 qc1db(k) = qc1db(k) + (1.0-factorn)*qrprodb
423 factornb = factornb - qc1d(k)*qrprodb
424 CALL POPINTEGER4(branch)
425 IF (branch .LT. 1) THEN
426 CALL POPREAL8(factorn)
427 temp = c3*dt*pwr1 + 1.
428 pwr1b = -(c3*dt*factornb/temp**2)
430 IF (.NOT.(qr1d(k) .LE. 0.0 .AND. (c4 .EQ. 0.0 .OR. c4 .NE. INT(&
431 & c4)))) qr1db(k) = qr1db(k) + c4*qr1d(k)**(c4-1)*pwr1b
433 CALL POPREAL8(factorn)
435 CALL POPINTEGER4(branch)
436 IF (.NOT.branch .LT. 1) qc1db(k) = 0.0
437 CALL POPINTEGER4(branch)
438 IF (.NOT.branch .LT. 1) qr1db(k) = 0.0
440 END SUBROUTINE AUTOCA_B
442 ! Differentiation of satadj in reverse (adjoint) mode:
443 ! gradient, with respect to input variables: qc qr qv p1d rhok
445 ! of linear combination of output variables: qc qr qv p1d rhok
447 SUBROUTINE SATADJ_B(qv, qvb, qc, qcb, qr, qrb, tmp, tmpb, p1d, p1db, &
448 & pii, piib, rhok, rhokb, kvts, kvte, xlv, dt, cp, ep2, svp1, svp2, &
451 INTEGER :: kvts, kvte, k
452 REAL, DIMENSION(kvts:kvte) :: qv, qc, qr, tmp, p1d, pii, rhok
453 REAL, DIMENSION(kvts:kvte) :: qvb, qcb, qrb, tmpb, p1db, piib, rhokb
454 REAL, DIMENSION(kvts:kvte) :: rcgs, pressure, temp, es, qvs
455 REAL, DIMENSION(kvts:kvte) :: rcgsb, pressureb, tempb, esb, qvsb
456 REAL, DIMENSION(kvts:kvte) :: ern, qv2cl, rn2qv
457 REAL, DIMENSION(kvts:kvte) :: ernb, qv2clb, rn2qvb
459 REAL :: svp1, svp2, svp3, svpt0, ep2, xlv, cp, dt, f5
460 REAL :: ernmax, product
461 REAL :: ernmaxb, productb
494 f5 = svp2*(svpt0-svp3)*xlv/cp
497 rcgs(k) = 0.001*rhok(k)
499 temp(k) = pii(k)*tmp(k)
501 arg1 = svp2*(temp(k)-svpt0)/(temp(k)-svp3)
502 es(k) = 1000.*svp1*EXP(arg1)
503 qvs(k) = ep2*es(k)/(pressure(k)-es(k))
504 IF (qr(k) .LT. 0) THEN
510 IF (qv(k) .LT. 0) THEN
516 IF (qc(k) .LT. 0) THEN
524 !not related to time; maximum transform qv to cl (sat) or cl to qv (sub sat)
525 qv2cl(k) = (qv(k)-qvs(k))/(1.+pressure(k)/(pressure(k)-es(k))*qvs(&
526 & k)*f5/(temp(k)-svp3)**2)
527 ! sub sat rain evaperate
529 IF (qvs(k) .GT. qv(k)) THEN
530 IF (qr(k) .GE. 1d-5) THEN
531 rn2qv(k) = dt*((1.6+124.9*(rcgs(k)*qr(k))**.2046)*(rcgs(k)*qr(&
532 & k))**.525/(2.55e8/(pressure(k)*qvs(k))+5.4e5))*((qvs(k)-qv(k&
533 & ))/(rcgs(k)*qvs(k)))
539 IF (rn2qv(k) .GT. qr(k)) THEN
546 IF (-qv2cl(k) - qc(k) .GT. 0.0) THEN
547 ernmax = -qv2cl(k) - qc(k)
552 ! ern(k) = amin1(rn2qv(k), ernmax)
554 IF (rn2qv(k) .GT. ernmax) THEN
563 ! Update all variables
564 ! product = amax1(qv2cl(k),-qc(k))
566 IF (qv2cl(k) .LT. -qc(k)) THEN
572 CALL PUSHREAL8(qv(k))
573 ! qv(k) = amax1(qv(k) - product + ern(k),0.)
574 qv(k) = qv(k) - product + ern(k)
575 IF (qv(k) .LT. 0) THEN
580 CALL PUSHREAL8(temp(k))
581 temp(k) = temp(k) + xlv/cp*(product-ern(k))
592 temp13b = tmpb(k)/pii(k)
593 tempb(k) = tempb(k) + temp13b
594 piib(k) = piib(k) - temp(k)*temp13b/pii(k)
596 CALL POPREAL8(temp(k))
597 temp13b0 = xlv*tempb(k)/cp
598 productb = qcb(k) + temp13b0
599 ernb(k) = ernb(k) - qrb(k) - temp13b0
600 CALL POPINTEGER4(branch)
601 IF (.NOT.branch .LT. 1) qvb(k) = 0.0
603 productb = productb - qvb(k)
604 ernb(k) = ernb(k) + qvb(k)
605 CALL POPINTEGER4(branch)
606 IF (.NOT.branch .LT. 1) THEN
607 qcb(k) = qcb(k) - productb
610 qv2clb(k) = qv2clb(k) + productb
611 CALL POPINTEGER4(branch)
612 IF (branch .LT. 2) THEN
613 IF (branch .LT. 1) THEN
622 rn2qvb(k) = rn2qvb(k) + ernb(k)
624 CALL POPINTEGER4(branch)
625 IF (.NOT.branch .LT. 1) THEN
626 qv2clb(k) = qv2clb(k) - ernmaxb
627 qcb(k) = qcb(k) - ernmaxb
629 CALL POPINTEGER4(branch)
630 IF (.NOT.branch .LT. 1) THEN
631 qrb(k) = qrb(k) + rn2qvb(k)
634 CALL POPINTEGER4(branch)
635 IF (branch .LT. 1) THEN
636 temp12 = rcgs(k)*qvs(k)
637 temp4 = pressure(k)*qvs(k)
638 temp11 = 2.55e8/temp4
639 temp5 = (temp11+5.4e5)*temp12
640 temp6 = rcgs(k)*qr(k)
641 temp10 = 124.9*temp6**.2046 + 1.6
643 temp8 = rcgs(k)*qr(k)
645 temp9b = dt*temp7*rn2qvb(k)
646 temp8b = (qvs(k)-qv(k))*.525*temp8**(-0.475)*temp9b
647 temp7b = dt*temp9*(qvs(k)-qv(k))*rn2qvb(k)/temp5
648 temp6b = 124.9*.2046*temp6**(-0.7954)*temp7b
649 temp5b = -(temp7*temp7b)
650 temp4b = -(temp12*temp11*temp5b/temp4)
651 rcgsb(k) = rcgsb(k) + (temp11+5.4e5)*qvs(k)*temp5b + qr(k)*&
652 & temp6b + qr(k)*temp8b
653 qrb(k) = qrb(k) + rcgs(k)*temp6b + rcgs(k)*temp8b
654 qvsb(k) = qvsb(k) + (temp11+5.4e5)*rcgs(k)*temp5b + pressure(k)*&
655 & temp4b + temp9*temp9b
656 qvb(k) = qvb(k) - temp9*temp9b
657 pressureb(k) = pressureb(k) + qvs(k)*temp4b
664 temp3 = (temp(k)-svp3)**2
665 temp0 = (pressure(k)-es(k))*temp3
666 temp2 = pressure(k)*qvs(k)
668 temp2b = qv2clb(k)/(f5*temp1+1.)
669 temp1b = -((qv(k)-qvs(k))*f5*temp2b/((f5*temp1+1.)*temp0))
670 temp0b2 = -(temp1*temp1b)
671 temp0b3 = temp3*temp0b2
672 qvb(k) = qvb(k) + temp2b
673 qvsb(k) = qvsb(k) + pressure(k)*temp1b - temp2b
674 pressureb(k) = pressureb(k) + temp0b3 + qvs(k)*temp1b
675 esb(k) = esb(k) - temp0b3
676 tempb(k) = tempb(k) + (pressure(k)-es(k))*2*(temp(k)-svp3)*temp0b2
680 CALL POPINTEGER4(branch)
681 IF (.NOT.branch .LT. 2) qcb(k) = 0.0
682 CALL POPINTEGER4(branch)
683 IF (.NOT.branch .LT. 1) qvb(k) = 0.0
684 CALL POPINTEGER4(branch)
685 IF (.NOT.branch .LT. 1) qrb(k) = 0.0
686 temp0b = ep2*qvsb(k)/(pressure(k)-es(k))
687 temp0b0 = -(es(k)*temp0b/(pressure(k)-es(k)))
688 esb(k) = esb(k) + temp0b - temp0b0
689 pressureb(k) = pressureb(k) + temp0b0
691 arg1b = svp1*1000.*EXP(arg1)*esb(k)
694 temp0b1 = svp2*arg1b/(temp(k)-svp3)
695 tempb(k) = tempb(k) + (1.0-(temp(k)-svpt0)/(temp(k)-svp3))*temp0b1
696 piib(k) = piib(k) + tmp(k)*tempb(k)
697 tmpb(k) = tmpb(k) + pii(k)*tempb(k)
699 p1db(k) = p1db(k) + pressureb(k)
701 rhokb(k) = rhokb(k) + 0.001*rcgsb(k)
704 END SUBROUTINE SATADJ_B
706 END MODULE A_MODULE_MP_MKESSLER