module_small_step_em.F
References to this file elsewhere.
1 !WRF:MODEL_LAYER:DYNAMICS
2 !
3
4 ! SMALL_STEP code for the geometric height coordinate model
5 !
6 !---------------------------------------------------------------------------
7
8 MODULE module_small_step_em
9
10 USE module_configure
11 USE module_model_constants
12
13 CONTAINS
14
15 !----------------------------------------------------------------------
16
17 SUBROUTINE small_step_prep( u_1, u_2, v_1, v_2, w_1, w_2, &
18 t_1, t_2, ph_1, ph_2, &
19 mub, mu_1, mu_2, &
20 muu, muus, muv, muvs, &
21 mut, muts, mudf, &
22 u_save, v_save, w_save, &
23 t_save, ph_save, mu_save, &
24 ww, ww_save, &
25 dnw, c2a, pb, p, alt, &
26 msfu, msfv, msft, &
27 rk_step, &
28 ids,ide, jds,jde, kds,kde, &
29 ims,ime, jms,jme, kms,kme, &
30 its,ite, jts,jte, kts,kte )
31
32 IMPLICIT NONE ! religion first
33
34 ! declarations for the stuff coming in
35
36 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
37 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
38 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
39
40 INTEGER, INTENT(IN ) :: rk_step
41
42 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: u_1, &
43 v_1, &
44 w_1, &
45 t_1, &
46 ph_1
47
48 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT( OUT) :: u_save, &
49 v_save, &
50 w_save, &
51 t_save, &
52 ph_save
53
54 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: u_2, &
55 v_2, &
56 w_2, &
57 t_2, &
58 ph_2
59
60 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT( OUT) :: c2a, &
61 ww_save
62
63 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: pb, &
64 p, &
65 alt, &
66 ww
67
68 ! pjj/cray
69 ! REAL, DIMENSION(ims:ime, jms:jme) , INTENT(INOUT) :: mu_1
70 REAL, DIMENSION(ims:ime, jms:jme) , INTENT(INOUT) :: mu_1,mu_2
71
72 REAL, DIMENSION(ims:ime, jms:jme) , INTENT(INout) :: mub, &
73 muu, &
74 muv, &
75 mut, &
76 msfu, &
77 msfv, &
78 msft
79
80 REAL, DIMENSION(ims:ime, jms:jme) , INTENT( OUT) :: muus, &
81 muvs, &
82 muts, &
83 !pjj/cray
84 ! mu_2, &
85 mudf
86
87 REAL, DIMENSION(ims:ime, jms:jme) , INTENT( OUT) :: mu_save
88
89 REAL, DIMENSION(kms:kme, jms:jme) , INTENT(IN ) :: dnw
90
91 ! local variables
92
93 INTEGER :: i, j, k
94 INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end
95 INTEGER :: i_endu, j_endv
96
97
98 !<DESCRIPTION>
99 !
100 ! small_step_prep prepares the prognostic variables for the small timestep.
101 ! This includes switching time-levels in the arrays and computing coupled
102 ! perturbation variables for the small timestep
103 ! (i.e. mu*u" = mu(t)*u(t)-mu(*)*u(*); mu*u" is advanced during the small
104 ! timesteps
105 !
106 !</DESCRIPTION>
107
108 i_start = its
109 i_end = ite
110 j_start = jts
111 j_end = jte
112 k_start = kts
113 k_end = min(kte,kde-1)
114
115 i_endu = i_end
116 j_endv = j_end
117
118 IF(i_end == ide) i_end = i_end - 1
119 IF(j_end == jde) j_end = j_end - 1
120
121 ! if this is the first RK step, reset *_1 to *_2
122 ! (we are replacing the t-dt fields with the time t fields)
123
124 IF ((rk_step == 1) ) THEN
125
126 ! 1 jun 2001 -> added boundary copy to 2D boundary condition routines,
127 ! should be OK now without the following data copy
128 !#if 0
129 ! DO j=j_start, j_end
130 ! mu_2(0,j)=mu_2(1,j)
131 ! mu_2(i_endu,j)=mu_2(i_end,j)
132 ! mu_1(0,j)=mu_2(1,j)
133 ! mu_1(i_endu,j)=mu_2(i_end,j)
134 ! mub(0,j)=mub(1,j)
135 ! mub(i_endu,j)=mub(i_end,j)
136 ! ENDDO
137 ! DO i=i_start, i_end
138 ! mu_2(i,0)=mu_2(i,1)
139 ! mu_2(i,j_endv)=mu_2(i,j_end)
140 ! mu_1(i,0)=mu_2(i,1)
141 ! mu_1(i,j_endv)=mu_2(i,j_end)
142 ! mub(i,0)=mub(i,1)
143 ! mub(i,j_endv)=mub(i,j_end)
144 ! ENDDO
145 !#endif
146
147 DO j=j_start, j_end
148 DO i=i_start, i_end
149 mu_1(i,j)=mu_2(i,j)
150 ww_save(i,kde,j) = 0.
151 ww_save(i,1,j) = 0.
152 mudf(i,j) = 0. ! initialize external mode div damp to zero
153 ENDDO
154 ENDDO
155
156 DO j=j_start, j_end
157 DO k=k_start, k_end
158 DO i=i_start, i_endu
159 u_1(i,k,j) = u_2(i,k,j)
160 ENDDO
161 ENDDO
162 ENDDO
163
164 DO j=j_start, j_endv
165 DO k=k_start, k_end
166 DO i=i_start, i_end
167 v_1(i,k,j) = v_2(i,k,j)
168 ENDDO
169 ENDDO
170 ENDDO
171
172 DO j=j_start, j_end
173 DO k=k_start, k_end
174 DO i=i_start, i_end
175 t_1(i,k,j) = t_2(i,k,j)
176 ENDDO
177 ENDDO
178 ENDDO
179
180 DO j=j_start, j_end
181 DO k=k_start, min(kde,kte)
182 DO i=i_start, i_end
183 w_1(i,k,j) = w_2(i,k,j)
184 ph_1(i,k,j) = ph_2(i,k,j)
185 ENDDO
186 ENDDO
187 ENDDO
188
189 DO j=j_start, j_end
190 DO i=i_start, i_end
191 muts(i,j)=mub(i,j)+mu_2(i,j)
192 ENDDO
193 DO i=i_start, i_endu
194 ! rk_step==1, WCS fix for tiling
195 ! muus(i,j)=0.5*(mub(i,j)+mu_2(i,j)+mub(i-1,j)+mu_2(i-1,j))
196 muus(i,j) = muu(i,j)
197 ENDDO
198 ENDDO
199
200 DO j=j_start, j_endv
201 DO i=i_start, i_end
202 ! rk_step==1, WCS fix for tiling
203 ! muvs(i,j)=0.5*(mub(i,j)+mu_2(i,j)+mub(i,j-1)+mu_2(i,j-1))
204 muvs(i,j) = muv(i,j)
205 ENDDO
206 ENDDO
207
208 DO j=j_start, j_end
209 DO i=i_start, i_end
210 mu_save(i,j)=mu_2(i,j)
211 mu_2(i,j)=mu_2(i,j)-mu_2(i,j)
212 ENDDO
213 ENDDO
214
215 ELSE
216
217 DO j=j_start, j_end
218 DO i=i_start, i_end
219 muts(i,j)=mub(i,j)+mu_1(i,j)
220 ENDDO
221 DO i=i_start, i_endu
222 muus(i,j)=0.5*(mub(i,j)+mu_1(i,j)+mub(i-1,j)+mu_1(i-1,j))
223 ENDDO
224 ENDDO
225
226 DO j=j_start, j_endv
227 DO i=i_start, i_end
228 muvs(i,j)=0.5*(mub(i,j)+mu_1(i,j)+mub(i,j-1)+mu_1(i,j-1))
229 ENDDO
230 ENDDO
231
232 DO j=j_start, j_end
233 DO i=i_start, i_end
234 mu_save(i,j)=mu_2(i,j)
235 mu_2(i,j)=mu_1(i,j)-mu_2(i,j)
236 ENDDO
237 ENDDO
238
239
240 END IF
241
242 ! set up the small timestep variables
243
244 DO j=j_start, j_end
245 DO i=i_start, i_end
246 ww_save(i,kde,j) = 0.
247 ww_save(i,1,j) = 0.
248 ENDDO
249 ENDDO
250
251 DO j=j_start, j_end
252 DO k=k_start, k_end
253 DO i=i_start, i_end
254 c2a(i,k,j) = cpovcv*(pb(i,k,j)+p(i,k,j))/alt(i,k,j)
255 ENDDO
256 ENDDO
257 ENDDO
258
259 DO j=j_start, j_end
260 DO k=k_start, k_end
261 DO i=i_start, i_endu
262 u_save(i,k,j) = u_2(i,k,j)
263 u_2(i,k,j) = (muus(i,j)*u_1(i,k,j)-muu(i,j)*u_2(i,k,j))/msfu(i,j)
264 ENDDO
265 ENDDO
266 ENDDO
267
268 DO j=j_start, j_endv
269 DO k=k_start, k_end
270 DO i=i_start, i_end
271 v_save(i,k,j) = v_2(i,k,j)
272 v_2(i,k,j) = (muvs(i,j)*v_1(i,k,j)-muv(i,j)*v_2(i,k,j))/msfv(i,j)
273 ENDDO
274 ENDDO
275 ENDDO
276
277 DO j=j_start, j_end
278 DO k=k_start, k_end
279 DO i=i_start, i_end
280 t_save(i,k,j) = t_2(i,k,j)
281 t_2(i,k,j) = muts(i,j)*t_1(i,k,j)-mut(i,j)*t_2(i,k,j)
282 ENDDO
283 ENDDO
284 ENDDO
285
286 DO j=j_start, j_end
287 ! DO k=k_start, min(kde,kte)
288 DO k=k_start, kde
289 DO i=i_start, i_end
290 w_save(i,k,j) = w_2(i,k,j)
291 w_2(i,k,j) = (muts(i,j)* w_1(i,k,j)-mut(i,j)* w_2(i,k,j))/msft(i,j)
292 ph_save(i,k,j) = ph_2(i,k,j)
293 ph_2(i,k,j) = ph_1(i,k,j)-ph_2(i,k,j)
294 ENDDO
295 ENDDO
296 ENDDO
297
298 DO j=j_start, j_end
299 ! DO k=k_start, min(kde,kte)
300 DO k=k_start, kde
301 DO i=i_start, i_end
302 ww_save(i,k,j) = ww(i,k,j)
303 ENDDO
304 ENDDO
305 ENDDO
306
307 END SUBROUTINE small_step_prep
308
309 !-------------------------------------------------------------------------
310
311
312 SUBROUTINE small_step_finish( u_2, u_1, v_2, v_1, w_2, w_1, &
313 t_2, t_1, ph_2, ph_1, ww, ww1, &
314 mu_2, mu_1, &
315 mut, muts, muu, muus, muv, muvs, &
316 u_save, v_save, w_save, &
317 t_save, ph_save, mu_save, &
318 msfu, msfv, msft, &
319 h_diabatic, &
320 number_of_small_timesteps,dts, &
321 rk_step, rk_order, &
322 ids,ide, jds,jde, kds,kde, &
323 ims,ime, jms,jme, kms,kme, &
324 its,ite, jts,jte, kts,kte )
325
326
327 IMPLICIT NONE ! religion first
328
329 ! stuff passed in
330
331 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
332 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
333 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
334 INTEGER, INTENT(IN ) :: number_of_small_timesteps
335 INTEGER, INTENT(IN ) :: rk_step, rk_order
336 REAL, INTENT(IN ) :: dts
337
338 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: u_1, &
339 v_1, &
340 w_1, &
341 t_1, &
342 ww1, &
343 ph_1
344
345 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(INOUT) :: u_2, &
346 v_2, &
347 w_2, &
348 t_2, &
349 ww, &
350 ph_2
351
352 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(IN ) :: u_save, &
353 v_save, &
354 w_save, &
355 t_save, &
356 ph_save, &
357 h_diabatic
358
359 REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: muus, muvs
360 REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: mu_2, mu_1
361 REAL, DIMENSION(ims:ime, jms:jme), INTENT(INOUT) :: mut, muts, &
362 muu, muv, mu_save
363 REAL, DIMENSION(ims:ime, jms:jme), INTENT(IN ) :: msfu, msfv, msft
364
365
366 ! local stuff
367
368 INTEGER :: i,j,k
369 INTEGER :: i_start, i_end, j_start, j_end, i_endu, j_endv
370
371 !<DESCRIPTION>
372 !
373 ! small_step_finish reconstructs the full uncoupled prognostic variables
374 ! from the coupled perturbation variables used in the small timesteps.
375 !
376 !</DESCRIPTION>
377
378 i_start = its
379 i_end = ite
380 j_start = jts
381 j_end = jte
382
383 i_endu = i_end
384 j_endv = j_end
385
386 IF(i_end == ide) i_end = i_end - 1
387 IF(j_end == jde) j_end = j_end - 1
388
389
390 ! 1 jun 2001 -> added boundary copy to 2D boundary condition routines,
391 ! should be OK now without the following data copy
392
393 !#if 0
394 ! DO j=j_start, j_end
395 ! muts(0,j)=muts(1,j)
396 ! muts(i_endu,j)=muts(i_end,j)
397 ! ENDDO
398 ! DO i=i_start, i_end
399 ! muts(i,0)=muts(i,1)
400 ! muts(i,j_endv)=muts(i,j_end)
401 ! ENDDO
402
403 ! DO j = j_start, j_endv
404 ! DO i = i_start, i_end
405 ! muvs(i,j) = 0.5*(muts(i,j) + muts(i,j-1))
406 ! ENDDO
407 ! ENDDO
408
409 ! DO j = j_start, j_end
410 ! DO i = i_start, i_endu
411 ! muus(i,j) = 0.5*(muts(i,j) + muts(i-1,j))
412 ! ENDDO
413 ! ENDDO
414 !#endif
415
416 ! addition of time level t back into variables
417
418 DO j = j_start, j_endv
419 DO k = kds, kde-1
420 DO i = i_start, i_end
421 v_2(i,k,j) = (msfv(i,j)*v_2(i,k,j) + v_save(i,k,j)*muv(i,j))/muvs(i,j)
422 ENDDO
423 ENDDO
424 ENDDO
425
426 DO j = j_start, j_end
427 DO k = kds, kde-1
428 DO i = i_start, i_endu
429 u_2(i,k,j) = (msfu(i,j)*u_2(i,k,j) + u_save(i,k,j)*muu(i,j))/muus(i,j)
430 ENDDO
431 ENDDO
432 ENDDO
433
434 DO j = j_start, j_end
435 DO k = kds, kde
436 DO i = i_start, i_end
437 w_2(i,k,j) = (msft(i,j)*w_2(i,k,j) + w_save(i,k,j)*mut(i,j))/muts(i,j)
438 ph_2(i,k,j) = ph_2(i,k,j) + ph_save(i,k,j)
439 ww(i,k,j) = ww(i,k,j) + ww1(i,k,j)
440 ENDDO
441 ENDDO
442 ENDDO
443
444 #ifdef REVERT
445 DO j = j_start, j_end
446 DO k = kds, kde-1
447 DO i = i_start, i_end
448 t_2(i,k,j) = (t_2(i,k,j) + t_save(i,k,j)*mut(i,j))/muts(i,j)
449 ENDDO
450 ENDDO
451 ENDDO
452 #else
453 IF ( rk_step < rk_order ) THEN
454 DO j = j_start, j_end
455 DO k = kds, kde-1
456 DO i = i_start, i_end
457 t_2(i,k,j) = (t_2(i,k,j) + t_save(i,k,j)*mut(i,j))/muts(i,j)
458 ENDDO
459 ENDDO
460 ENDDO
461 ELSE
462
463 DO j = j_start, j_end
464 DO k = kds, kde-1
465 DO i = i_start, i_end
466 t_2(i,k,j) = (t_2(i,k,j) - dts*number_of_small_timesteps*mut(i,j)*h_diabatic(i,k,j) &
467 + t_save(i,k,j)*mut(i,j))/muts(i,j)
468 ENDDO
469 ENDDO
470 ENDDO
471 ENDIF
472 #endif
473
474 DO j = j_start, j_end
475 DO i = i_start, i_end
476 mu_2(i,j) = mu_2(i,j) + mu_save(i,j)
477 ENDDO
478 ENDDO
479
480 END SUBROUTINE small_step_finish
481
482 !-----------------------------------------------------------------------
483
484 SUBROUTINE calc_p_rho( al, p, ph, &
485 alt, t_2, t_1, c2a, pm1, &
486 mu, muts, znu, t0, &
487 rdnw, dnw, smdiv, &
488 non_hydrostatic, step, &
489 ids, ide, jds, jde, kds, kde, &
490 ims, ime, jms, jme, kms, kme, &
491 its,ite, jts,jte, kts,kte )
492
493 IMPLICIT NONE ! religion first
494
495 ! declarations for the stuff coming in
496
497 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
498 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
499 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
500
501 INTEGER, INTENT(IN ) :: step
502
503 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT( OUT) :: al, &
504 p
505 ! pjj/cray
506 ! p, &
507 ! pm1
508
509 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(IN ) :: alt, &
510 t_2, &
511 t_1, &
512 c2a
513
514 ! pjj/cray
515 ! REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: ph
516 REAL, DIMENSION(ims:ime, kms:kme, jms:jme),INTENT(INOUT) :: ph, pm1
517
518 REAL, DIMENSION(ims:ime, jms:jme) , INTENT(IN ) :: mu, &
519 muts
520
521 REAL, DIMENSION(kms:kme) , INTENT(IN ) :: dnw, &
522 rdnw, &
523 znu
524
525 REAL, INTENT(IN ) :: t0, smdiv
526
527 LOGICAL, INTENT(IN ) :: non_hydrostatic
528
529 ! local variables
530
531 INTEGER :: i, j, k
532 INTEGER :: i_start, i_end, j_start, j_end, k_start, k_end
533 REAL :: ptmp
534
535 !<DESCRIPTION>
536 !
537 ! For the nonhydrostatic option,
538 ! calc_p_rho computes the perturbation inverse density and
539 ! perturbation pressure from the hydrostatic relation and the
540 ! linearized equation of state, respectively.
541 !
542 ! For the hydrostatic option,
543 ! calc_p_rho computes the perturbation pressure, perturbation density,
544 ! and perturbation geopotential
545 ! from the vertical coordinate definition, linearized equation of state
546 ! and the hydrostatic relation, respectively.
547 !
548 ! forward weighting of the pressure (divergence damping) is also
549 ! computed here.
550 !
551 !</DESCRIPTION>
552
553 i_start = its
554 i_end = ite
555 j_start = jts
556 j_end = jte
557 k_start = kts
558 k_end = min(kte,kde-1)
559
560 IF(i_end == ide) i_end = i_end - 1
561 IF(j_end == jde) j_end = j_end - 1
562
563 IF (non_hydrostatic) THEN
564 DO j=j_start, j_end
565 DO k=k_start, k_end
566 DO i=i_start, i_end
567
568 ! al computation is all dry, so ok with moisture
569
570 al(i,k,j)=-1./muts(i,j)*(alt(i,k,j)*mu(i,j) &
571 +rdnw(k)*(ph(i,k+1,j)-ph(i,k,j)))
572
573 ! this is temporally linearized p, no moisture correction needed
574
575 p(i,k,j)=c2a(i,k,j)*(alt(i,k,j)*(t_2(i,k,j)-mu(i,j)*t_1(i,k,j)) &
576 /(muts(i,j)*(t0+t_1(i,k,j)))-al (i,k,j))
577
578 ENDDO
579 ENDDO
580 ENDDO
581
582 ELSE ! hydrostatic calculation
583
584 DO j=j_start, j_end
585 DO k=k_start, k_end
586 DO i=i_start, i_end
587 p(i,k,j)=mu(i,j)*znu(k)
588 al(i,k,j)=alt(i,k,j)*(t_2(i,k,j)-mu(i,j)*t_1(i,k,j)) &
589 /(muts(i,j)*(t0+t_1(i,k,j)))-p(i,k,j)/c2a(i,k,j)
590 ph(i,k+1,j)=ph(i,k,j)-dnw(k)*(muts(i,j)*al (i,k,j) &
591 +mu(i,j)*alt(i,k,j))
592 ENDDO
593 ENDDO
594 ENDDO
595
596 END IF
597
598 ! divergence damping setup
599
600 IF (step == 0) then ! we're initializing small timesteps
601 DO j=j_start, j_end
602 DO k=k_start, k_end
603 DO i=i_start, i_end
604 pm1(i,k,j)=p(i,k,j)
605 ENDDO
606 ENDDO
607 ENDDO
608 ELSE ! we're in the small timesteps
609 DO j=j_start, j_end ! and adding div damping component
610 DO k=k_start, k_end
611 DO i=i_start, i_end
612 ptmp = p(i,k,j)
613 p(i,k,j) = p(i,k,j) + smdiv*(p(i,k,j)-pm1(i,k,j))
614 pm1(i,k,j) = ptmp
615 ENDDO
616 ENDDO
617 ENDDO
618 END IF
619
620 END SUBROUTINE calc_p_rho
621
622 !----------------------------------------------------------------------
623
624 SUBROUTINE calc_coef_w( a,alpha,gamma, &
625 mut, cqw, &
626 rdn, rdnw, c2a, &
627 dts, g, epssm, &
628 ids,ide, jds,jde, kds,kde, & ! domain dims
629 ims,ime, jms,jme, kms,kme, & ! memory dims
630 its,ite, jts,jte, kts,kte ) ! tile dims
631
632 IMPLICIT NONE ! religion first
633
634 ! passed in through the call
635
636 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
637 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
638 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
639
640
641 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: c2a, &
642 cqw
643
644 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(INOUT) :: alpha, &
645 gamma, &
646 a
647
648 REAL, DIMENSION(ims:ime, jms:jme), INTENT(IN ) :: mut
649
650 REAL, DIMENSION(kms:kme), INTENT(IN ) :: rdn, &
651 rdnw
652
653 REAL, INTENT(IN ) :: epssm, &
654 dts, &
655 g
656
657 ! Local stack data.
658
659 REAL, DIMENSION(ims:ime) :: cof
660 REAL :: b, c
661
662 INTEGER :: i, j, k, i_start, i_end, j_start, j_end, k_start, k_end
663 INTEGER :: ij, ijp, ijm
664
665 !<DESCRIPTION>
666 !
667 ! calc_coef_w calculates the coefficients needed for the
668 ! implicit solution of the vertical momentum and geopotential equations.
669 ! This requires solution of a tri-diagonal equation.
670 !
671 !</DESCRIPTION>
672
673
674 i_start = its
675 i_end = ite
676 j_start = jts
677 j_end = jte
678 k_start = kts
679 k_end = kte-1
680
681 IF(j_end == jde) j_end = j_end - 1
682 IF(i_end == ide) i_end = i_end - 1
683
684 outer_j_loop: DO j = j_start, j_end
685
686 DO i = i_start, i_end
687 cof(i) = (.5*dts*g*(1.+epssm)/mut(i,j))**2
688 a(i, 2 ,j) = 0.
689 a(i,kde,j) =-2.*cof(i)*rdnw(kde-1)**2*c2a(i,kde-1,j)
690 gamma(i,1 ,j) = 0.
691 ENDDO
692
693 DO k=3,kde-1
694 DO i=i_start, i_end
695 a(i,k,j) = -cqw(i,k,j)*cof(i)*rdn(k)* rdnw(k-1)*c2a(i,k-1,j)
696 ENDDO
697 ENDDO
698
699
700 DO k=2,kde-1
701 DO i=i_start, i_end
702 b = 1.+cqw(i,k,j)*cof(i)*rdn(k)*(rdnw(k )*c2a(i,k,j ) &
703 +rdnw(k-1)*c2a(i,k-1,j))
704 c = -cqw(i,k,j)*cof(i)*rdn(k)*rdnw(k )*c2a(i,k,j )
705 alpha(i,k,j) = 1./(b-a(i,k,j)*gamma(i,k-1,j))
706 gamma(i,k,j) = c*alpha(i,k,j)
707 ENDDO
708 ENDDO
709
710 DO i=i_start, i_end
711 b = 1.+2.*cof(i)*rdnw(kde-1)**2*c2a(i,kde-1,j)
712 c = 0.
713 alpha(i,kde,j) = 1./(b-a(i,kde,j)*gamma(i,kde-1,j))
714 gamma(i,kde,j) = c*alpha(i,kde,j)
715 ENDDO
716
717 ENDDO outer_j_loop
718
719 END SUBROUTINE calc_coef_w
720
721 !----------------------------------------------------------------------
722
723 SUBROUTINE advance_uv ( u, ru_tend, v, rv_tend, &
724 p, pb, &
725 ph, php, alt, al, mu, &
726 muu, cqu, muv, cqv, mudf, &
727 rdx, rdy, dts, &
728 cf1, cf2, cf3, fnm, fnp, &
729 emdiv, &
730 rdnw, config_flags, spec_zone, &
731 non_hydrostatic, &
732 ids, ide, jds, jde, kds, kde, &
733 ims, ime, jms, jme, kms, kme, &
734 its, ite, jts, jte, kts, kte )
735
736
737
738 IMPLICIT NONE ! religion first
739
740 ! stuff coming in
741
742 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
743
744 LOGICAL, INTENT(IN ) :: non_hydrostatic
745
746 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
747 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
748 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
749 INTEGER, INTENT(IN ) :: spec_zone
750
751 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
752 INTENT(INOUT) :: &
753 u, &
754 v
755
756 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
757 INTENT(IN ) :: &
758 ru_tend, &
759 rv_tend, &
760 ph, &
761 php, &
762 p, &
763 pb, &
764 alt, &
765 al, &
766 cqu, &
767 cqv
768
769
770 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: muu, &
771 muv, &
772 mu, &
773 mudf
774
775
776 REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnm, &
777 fnp , &
778 rdnw
779
780 REAL, INTENT(IN ) :: rdx, &
781 rdy, &
782 dts, &
783 cf1, &
784 cf2, &
785 cf3, &
786 emdiv
787
788
789 ! Local 3d array from the stack (note tile size)
790
791 REAL, DIMENSION (its:ite, kts:kte) :: dpn, dpxy
792 REAL, DIMENSION (its:ite) :: mudf_xy
793 REAL :: dx, dy
794
795 INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end
796 INTEGER :: i_endu, j_endv, k_endw
797 INTEGER :: i_start_up, i_end_up, j_start_up, j_end_up
798 INTEGER :: i_start_vp, i_end_vp, j_start_vp, j_end_vp
799
800 INTEGER :: i_start_u_tend, i_end_u_tend, j_start_v_tend, j_end_v_tend
801
802 !<DESCRIPTION>
803 !
804 ! advance_uv advances the explicit perturbation horizontal momentum
805 ! equations (u,v) by adding in the large-timestep tendency along with
806 ! the small timestep pressure gradient tendency.
807 !
808 !</DESCRIPTION>
809
810 ! now, the real work.
811 ! set the loop bounds taking into account boundary conditions.
812
813 IF( config_flags%nested .or. config_flags%specified ) THEN
814 i_start = max( its,ids+spec_zone )
815 i_end = min( ite,ide-spec_zone-1 )
816 j_start = max( jts,jds+spec_zone )
817 j_end = min( jte,jde-spec_zone-1 )
818 k_start = kts
819 k_end = min( kte, kde-1 )
820
821 i_endu = min( ite,ide-spec_zone )
822 j_endv = min( jte,jde-spec_zone )
823 k_endw = k_end
824
825 IF( config_flags%periodic_x) THEN
826 i_start = its
827 i_end = ite
828 i_endu = i_end
829 IF(i_end == ide) i_end = i_end - 1
830 ENDIF
831 ELSE
832 i_start = its
833 i_end = ite
834 j_start = jts
835 j_end = jte
836 k_start = kts
837 k_end = kte-1
838
839 i_endu = i_end
840 j_endv = j_end
841 k_endw = k_end
842
843 IF(j_end == jde) j_end = j_end - 1
844 IF(i_end == ide) i_end = i_end - 1
845 ENDIF
846
847 i_start_up = i_start
848 i_end_up = i_endu
849 j_start_up = j_start
850 j_end_up = j_end
851
852 i_start_vp = i_start
853 i_end_vp = i_end
854 j_start_vp = j_start
855 j_end_vp = j_endv
856
857 IF ( (config_flags%open_xs .or. &
858 config_flags%symmetric_xs ) &
859 .and. (its == ids) ) &
860 i_start_up = i_start_up + 1
861
862 IF ( (config_flags%open_xe .or. &
863 config_flags%symmetric_xe ) &
864 .and. (ite == ide) ) &
865 i_end_up = i_end_up - 1
866
867 IF ( (config_flags%open_ys .or. &
868 config_flags%symmetric_ys ) &
869 .and. (jts == jds) ) &
870 j_start_vp = j_start_vp + 1
871
872 IF ( (config_flags%open_ye .or. &
873 config_flags%symmetric_ye ) &
874 .and. (jte == jde) ) &
875 j_end_vp = j_end_vp - 1
876
877 i_start_u_tend = i_start
878 i_end_u_tend = i_endu
879 j_start_v_tend = j_start
880 j_end_v_tend = j_endv
881
882 IF ( config_flags%symmetric_xs .and. (its == ids) ) &
883 i_start_u_tend = i_start_u_tend+1
884 IF ( config_flags%symmetric_xe .and. (ite == ide) ) &
885 i_end_u_tend = i_end_u_tend-1
886 IF ( config_flags%symmetric_ys .and. (jts == jds) ) &
887 j_start_v_tend = j_start_v_tend+1
888 IF ( config_flags%symmetric_ye .and. (jte == jde) ) &
889 j_end_v_tend = j_end_v_tend-1
890
891 dx = 1./rdx
892 dy = 1./rdy
893
894 ! start real calculations.
895 ! first, u
896
897 u_outer_j_loop: DO j = j_start, j_end
898
899 DO k = k_start, k_end
900 DO i = i_start_u_tend, i_end_u_tend
901 u(i,k,j) = u(i,k,j) + dts*ru_tend(i,k,j)
902 ENDDO
903 ENDDO
904
905 DO i = i_start_up, i_end_up
906 mudf_xy(i)= -emdiv*dx*(mudf(i,j)-mudf(i-1,j))
907 ENDDO
908
909 DO k = k_start, k_end
910 DO i = i_start_up, i_end_up
911
912 dpxy(i,k)= .5*rdx*muu(i,j)*( &
913 ((ph (i,k+1,j)-ph (i-1,k+1,j))+(ph (i,k,j)-ph (i-1,k,j))) &
914 +(alt(i,k ,j)+alt(i-1,k ,j))*(p (i,k,j)-p (i-1,k,j)) &
915 +(al (i,k ,j)+al (i-1,k ,j))*(pb (i,k,j)-pb (i-1,k,j)) )
916
917 ENDDO
918 ENDDO
919
920 IF (non_hydrostatic) THEN
921
922 DO i = i_start_up, i_end_up
923 dpn(i,1) = .5*( cf1*(p(i,1,j)+p(i-1,1,j)) &
924 +cf2*(p(i,2,j)+p(i-1,2,j)) &
925 +cf3*(p(i,3,j)+p(i-1,3,j)) )
926 dpn(i,kde) = 0.
927 ENDDO
928
929
930 DO k = k_start+1, k_end
931 DO i = i_start_up, i_end_up
932 dpn(i,k) = .5*( fnm(k)*(p(i,k ,j)+p(i-1,k ,j)) &
933 +fnp(k)*(p(i,k-1,j)+p(i-1,k-1,j)) )
934 ENDDO
935 ENDDO
936
937 DO k = k_start, k_end
938 DO i = i_start_up, i_end_up
939 dpxy(i,k)=dpxy(i,k) + rdx*(php(i,k,j)-php(i-1,k,j))* &
940 (rdnw(k)*(dpn(i,k+1)-dpn(i,k))-.5*(mu(i-1,j)+mu(i,j)))
941 ENDDO
942 ENDDO
943
944
945 END IF
946
947
948 DO k = k_start, k_end
949 DO i = i_start_up, i_end_up
950 u(i,k,j)=u(i,k,j)-dts*cqu(i,k,j)*dpxy(i,k)+mudf_xy(i)
951 ENDDO
952 ENDDO
953
954 ENDDO u_outer_j_loop
955
956 ! now v
957
958 v_outer_j_loop: DO j = j_start_v_tend, j_end_v_tend
959
960
961 DO k = k_start, k_end
962 DO i = i_start, i_end
963 v(i,k,j) = v(i,k,j) + dts*rv_tend(i,k,j)
964 ENDDO
965 ENDDO
966
967 DO i = i_start, i_end
968 mudf_xy(i)= -emdiv*dy*(mudf(i,j)-mudf(i,j-1))
969 ENDDO
970
971 IF ( ( j >= j_start_vp) &
972 .and.( j <= j_end_vp ) ) THEN
973
974 DO k = k_start, k_end
975 DO i = i_start, i_end
976
977 dpxy(i,k)= .5*rdy*muv(i,j)*( &
978 ((ph(i,k+1,j)-ph(i,k+1,j-1))+(ph (i,k,j)-ph (i,k,j-1))) &
979 +(alt(i,k ,j)+alt(i,k ,j-1))*(p (i,k,j)-p (i,k,j-1)) &
980 +(al (i,k ,j)+al (i,k ,j-1))*(pb (i,k,j)-pb (i,k,j-1)) )
981
982 ENDDO
983 ENDDO
984
985
986 IF (non_hydrostatic) THEN
987
988 DO i = i_start, i_end
989 dpn(i,1) = .5*( cf1*(p(i,1,j)+p(i,1,j-1)) &
990 +cf2*(p(i,2,j)+p(i,2,j-1)) &
991 +cf3*(p(i,3,j)+p(i,3,j-1)) )
992 dpn(i,kde) = 0.
993 ENDDO
994
995
996 DO k = k_start+1, k_end
997 DO i = i_start, i_end
998 dpn(i,k) = .5*( fnm(k)*(p(i,k ,j)+p(i,k ,j-1)) &
999 +fnp(k)*(p(i,k-1,j)+p(i,k-1,j-1)) )
1000 ENDDO
1001 ENDDO
1002
1003 DO k = k_start, k_end
1004 DO i = i_start, i_end
1005 dpxy(i,k)=dpxy(i,k) + rdy*(php(i,k,j)-php(i,k,j-1))* &
1006 (rdnw(k)*(dpn(i,k+1)-dpn(i,k))-.5*(mu(i,j-1)+mu(i,j)))
1007 ENDDO
1008 ENDDO
1009
1010
1011 END IF
1012
1013
1014 DO k = k_start, k_end
1015 DO i = i_start, i_end
1016 v(i,k,j)=v(i,k,j)-dts*cqv(i,k,j)*dpxy(i,k)+mudf_xy(i)
1017 ENDDO
1018 ENDDO
1019 END IF
1020
1021 ENDDO v_outer_j_loop
1022
1023 END SUBROUTINE advance_uv
1024
1025 !---------------------------------------------------------------------
1026
1027 SUBROUTINE advance_mu_t( ww, ww_1, u, u_1, v, v_1, &
1028 mu, mut, muave, muts, muu, muv, &
1029 mudf, uam, vam, wwam, t, t_1, &
1030 t_ave, ft, mu_tend, &
1031 rdx, rdy, dts, epssm, &
1032 dnw, fnm, fnp, rdnw, &
1033 msfu, msfv, msft, &
1034 step, config_flags, &
1035 ids, ide, jds, jde, kds, kde, &
1036 ims, ime, jms, jme, kms, kme, &
1037 its, ite, jts, jte, kts, kte )
1038
1039 IMPLICIT NONE ! religion first
1040
1041 ! stuff coming in
1042
1043 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
1044
1045 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
1046 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
1047 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
1048
1049 INTEGER, INTENT(IN ) :: step
1050
1051 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
1052 INTENT(IN ) :: &
1053 u, &
1054 v, &
1055 u_1, &
1056 v_1, &
1057 t_1, &
1058 ft
1059
1060 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
1061 INTENT(INOUT) :: &
1062 ww, &
1063 ww_1, &
1064 t, &
1065 t_ave, &
1066 uam, &
1067 vam, &
1068 wwam
1069
1070 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(IN ) :: muu, &
1071 muv, &
1072 mut, &
1073 msfu, &
1074 msfv, &
1075 msft, &
1076 mu_tend
1077
1078 REAL, DIMENSION( ims:ime , jms:jme ), INTENT( OUT) :: muave, &
1079 muts, &
1080 mudf
1081
1082 REAL, DIMENSION( ims:ime , jms:jme ), INTENT(INOUT) :: mu
1083
1084 REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnm, &
1085 fnp, &
1086 dnw, &
1087 rdnw
1088
1089
1090 REAL, INTENT(IN ) :: rdx, &
1091 rdy, &
1092 dts, &
1093 epssm
1094
1095 ! Local 3d array from the stack (note tile size)
1096
1097 REAL, DIMENSION (its:ite, kts:kte) :: wdtn, dvdxi
1098 REAL, DIMENSION (its:ite) :: dmdt
1099
1100 INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end
1101 INTEGER :: i_endu, j_endv
1102 REAL :: acc
1103
1104 !<DESCRIPTION>
1105 !
1106 ! advance_mu_t advances the explicit perturbation theta equation and the mass
1107 ! conservation equation. In addition, the small timestep omega is updated,
1108 ! and some quantities needed in other places are squirrelled away.
1109 !
1110 !</DESCRIPTION>
1111
1112 ! now, the real work.
1113 ! set the loop bounds taking into account boundary conditions.
1114
1115 i_start = its
1116 i_end = ite
1117 j_start = jts
1118 j_end = jte
1119 k_start = kts
1120 k_end = kte-1
1121
1122 i_endu = i_end
1123 j_endv = j_end
1124
1125 IF(j_end == jde) j_end = j_end - 1
1126 IF(i_end == ide) i_end = i_end - 1
1127
1128 IF ( .NOT. config_flags%periodic_x )THEN
1129 IF ( (config_flags%specified .or. config_flags%nested) .and. (its == ids) ) &
1130 i_start = i_start + 1
1131
1132 IF ( (config_flags%specified .or. config_flags%nested) .and. (ite == ide) ) &
1133 i_end = i_end - 1
1134 ENDIF
1135
1136 IF ( (config_flags%specified .or. config_flags%nested) .and. (jts == jds) ) &
1137 j_start = j_start + 1
1138
1139 IF ( (config_flags%specified .or. config_flags%nested) .and. (jte == jde) ) &
1140 j_end = j_end - 1
1141
1142
1143 ! CALCULATION OF WW (dETA/dt)
1144 DO j = j_start, j_end
1145
1146 DO i=i_start, i_end
1147 dmdt(i) = 0.
1148 ENDDO
1149 ! NOTE: mu is not coupled with the map scale factor.
1150 ! ww (omega) IS coupled with the map scale factor.
1151 ! Being coupled with the map scale factor means
1152 ! multiplication by (1/msft) in this case.
1153
1154 DO k=k_start, k_end
1155 DO i=i_start, i_end
1156 dvdxi(i,k) = msft(i,j)*msft(i,j)*( &
1157 rdy*( (v(i,k,j+1)+muv(i,j+1)*v_1(i,k,j+1)/msfv(i,j+1)) &
1158 -(v(i,k,j )+muv(i,j )*v_1(i,k,j )/msfv(i,j )) ) &
1159 +rdx*( (u(i+1,k,j)+muu(i+1,j)*u_1(i+1,k,j)/msfu(i+1,j)) &
1160 -(u(i,k,j )+muu(i ,j)*u_1(i,k,j )/msfu(i ,j)) ) )
1161 dmdt(i) = dmdt(i) + dnw(k)*dvdxi(i,k)
1162 ENDDO
1163 ENDDO
1164 DO i=i_start, i_end
1165 muave(i,j) = mu(i,j)
1166 mu(i,j) = mu(i,j)+dts*(dmdt(i)+mu_tend(i,j))
1167 mudf(i,j) = (dmdt(i)+mu_tend(i,j)) ! save tendency for div damp filter
1168 muts(i,j) = mut(i,j)+mu(i,j)
1169 muave(i,j) =.5*((1.+epssm)*mu(i,j)+(1.-epssm)*muave(i,j))
1170 ENDDO
1171
1172 DO k=2,k_end
1173 DO i=i_start, i_end
1174 ww(i,k,j)=ww(i,k-1,j)-dnw(k-1)*(dmdt(i)+dvdxi(i,k-1)+mu_tend(i,j))/msft(i,j)
1175 ENDDO
1176 END DO
1177
1178 ! NOTE: ww_1 (large timestep ww) is already coupled with the
1179 ! map scale factor
1180
1181 DO k=1,k_end
1182 DO i=i_start, i_end
1183 ww(i,k,j)=ww(i,k,j)-ww_1(i,k,j)
1184 END DO
1185 END DO
1186
1187 ENDDO
1188
1189 ! CALCULATION OF THETA
1190
1191 ! NOTE: theta'' is not coupled with the map-scale factor,
1192 ! while the theta'' tendency is coupled (i.e., mult by 1/msft)
1193
1194 DO j=j_start, j_end
1195 DO k=1,k_end
1196 DO i=i_start, i_end
1197 t_ave(i,k,j) = t(i,k,j)
1198 t (i,k,j) = t(i,k,j) + msft(i,j)*dts*ft(i,k,j)
1199 END DO
1200 END DO
1201 ENDDO
1202
1203 DO j=j_start, j_end
1204
1205 DO i=i_start, i_end
1206 wdtn(i,1 )=0.
1207 wdtn(i,kde)=0.
1208 ENDDO
1209
1210 DO k=2,k_end
1211 DO i=i_start, i_end
1212 wdtn(i,k)= ww(i,k,j)*(fnm(k)*t_1(i,k ,j)+fnp(k)*t_1(i,k-1,j))
1213 ENDDO
1214 ENDDO
1215
1216 DO k=1,k_end
1217 DO i=i_start, i_end
1218 t(i,k,j) = t(i,k,j) - dts*msft(i,j)*( &
1219 msft(i,j)*( &
1220 .5*rdy* &
1221 ( v(i,k,j+1)*(t_1(i,k,j+1)+t_1(i,k, j )) &
1222 -v(i,k,j )*(t_1(i,k, j )+t_1(i,k,j-1)) ) &
1223 + .5*rdx* &
1224 ( u(i+1,k,j)*(t_1(i+1,k,j)+t_1(i ,k,j)) &
1225 -u(i ,k,j)*(t_1(i ,k,j)+t_1(i-1,k,j)) ) ) &
1226 + rdnw(k)*( wdtn(i,k+1)-wdtn(i,k) ) )
1227 ENDDO
1228 ENDDO
1229
1230 ENDDO
1231
1232 END SUBROUTINE advance_mu_t
1233
1234
1235
1236 !------------------------------------------------------------
1237
1238 SUBROUTINE advance_w( w, rw_tend, ww, w_save, u, v, &
1239 mu1, mut, muave, muts, &
1240 t_2ave, t_2, t_1, &
1241 ph, ph_1, phb, ph_tend, &
1242 ht, c2a, cqw, alt, alb, &
1243 a, alpha, gamma, &
1244 rdx, rdy, dts, t0, epssm, &
1245 dnw, fnm, fnp, rdnw, rdn, &
1246 cf1, cf2, cf3, msft, &
1247 config_flags, &
1248 ids,ide, jds,jde, kds,kde, & ! domain dims
1249 ims,ime, jms,jme, kms,kme, & ! memory dims
1250 its,ite, jts,jte, kts,kte ) ! tile dims
1251
1252 IMPLICIT NONE ! religion first
1253
1254 ! stuff coming in
1255
1256
1257 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
1258
1259 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
1260 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
1261 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
1262
1263 REAL, DIMENSION( ims:ime , kms:kme , jms:jme ), &
1264 INTENT(INOUT) :: &
1265 t_2ave, &
1266 w, &
1267 ph
1268
1269
1270 REAL, DIMENSION( ims:ime , kms:kme, jms:jme ), &
1271 INTENT(IN ) :: &
1272 rw_tend, &
1273 ww, &
1274 w_save, &
1275 u, &
1276 v, &
1277 t_2, &
1278 t_1, &
1279 ph_1, &
1280 phb, &
1281 ph_tend, &
1282 alpha, &
1283 gamma, &
1284 a, &
1285 c2a, &
1286 cqw, &
1287 alb, &
1288 alt
1289
1290 REAL, DIMENSION( ims:ime , jms:jme ), &
1291 INTENT(IN ) :: &
1292 mu1, &
1293 mut, &
1294 muave, &
1295 muts, &
1296 ht, &
1297 msft
1298
1299 REAL, DIMENSION( kms:kme ), INTENT(IN ) :: fnp, &
1300 fnm, &
1301 rdnw, &
1302 rdn, &
1303 dnw
1304
1305 REAL, INTENT(IN ) :: rdx, &
1306 rdy, &
1307 dts, &
1308 cf1, &
1309 cf2, &
1310 cf3, &
1311 t0, &
1312 epssm
1313
1314 ! Stack based 3d data, tile size.
1315
1316 REAL, DIMENSION( its:ite ) :: mut_inv, msft_inv
1317 REAL, DIMENSION( its:ite, kts:kte ) :: rhs, wdwn
1318 INTEGER :: i,j,k, i_start, i_end, j_start, j_end, k_start, k_end
1319 REAL, DIMENSION (kts:kte) :: dampwt
1320 real :: htop,hbot,hdepth,hk
1321 real :: pi,dampmag
1322
1323 !<DESCRIPTION>
1324 !
1325 ! advance_w advances the implicit w and geopotential equations.
1326 !
1327 !</DESCRIPTION>
1328
1329 ! set loop limits.
1330 ! Currently set for periodic boundary conditions
1331
1332 i_start = its
1333 i_end = ite
1334 j_start = jts
1335 j_end = jte
1336 k_start = kts
1337 k_end = kte-1
1338
1339
1340 IF(j_end == jde) j_end = j_end - 1
1341 IF(i_end == ide) i_end = i_end - 1
1342
1343 IF ( .NOT. config_flags%periodic_x )THEN
1344 IF ( (config_flags%specified .or. config_flags%nested) .and. (its == ids) ) &
1345 i_start = i_start + 1
1346
1347 IF ( (config_flags%specified .or. config_flags%nested) .and. (ite == ide) ) &
1348 i_end = i_end - 1
1349 ENDIF
1350
1351 IF ( (config_flags%specified .or. config_flags%nested) .and. (jts == jds) ) &
1352 j_start = j_start + 1
1353
1354 IF ( (config_flags%specified .or. config_flags%nested) .and. (jte == jde) ) &
1355 j_end = j_end - 1
1356
1357 pi = 4.*atan(1.)
1358 dampmag = dts*config_flags%dampcoef
1359 hdepth=config_flags%zdamp
1360
1361 ! calculation of phi and w equations
1362
1363 DO i=i_start, i_end
1364 rhs(i,1) = 0.
1365 ENDDO
1366
1367 j_loop_w: DO j = j_start, j_end
1368 DO i=i_start, i_end
1369 mut_inv(i) = 1./mut(i,j)
1370 msft_inv(i) = 1./msft(i,j)
1371 ENDDO
1372
1373 DO k=1, k_end
1374 DO i=i_start, i_end
1375 t_2ave(i,k,j)=.5*((1.+epssm)*t_2(i,k,j) &
1376 +(1.-epssm)*t_2ave(i,k,j))
1377 t_2ave(i,k,j)=(t_2ave(i,k,j) + muave(i,j)*t0) &
1378 /(muts(i,j)*(t0+t_1(i,k,j)))
1379 wdwn(i,k+1)=.5*(ww(i,k+1,j)+ww(i,k,j))*rdnw(k) &
1380 *(ph_1(i,k+1,j)-ph_1(i,k,j)+phb(i,k+1,j)-phb(i,k,j))
1381 rhs(i,k+1) = dts*(ph_tend(i,k+1,j) + .5*g*(1.-epssm)*w(i,k+1,j))
1382
1383 ENDDO
1384 ENDDO
1385
1386 DO k=2,k_end
1387 DO i=i_start, i_end
1388 rhs(i,k) = rhs(i,k)-dts*( fnm(k)*wdwn(i,k+1) &
1389 +fnp(k)*wdwn(i,k ) )
1390 ENDDO
1391 ENDDO
1392
1393 ! NOTE: phi'' is not coupled with the map-scale factor (1/m),
1394 ! but it's tendency is, so must multiply by msft here
1395
1396 DO k=2,k_end+1
1397 DO i=i_start, i_end
1398 rhs(i,k) = ph(i,k,j) + msft(i,j)*rhs(i,k)*mut_inv(i)
1399 ENDDO
1400 ENDDO
1401
1402 ! lower boundary condition on w
1403
1404 DO i=i_start, i_end
1405 w(i,1,j)= &
1406
1407 .5*rdy*( &
1408 (ht(i,j+1)-ht(i,j )) &
1409 *(cf1*v(i,1,j+1)+cf2*v(i,2,j+1)+cf3*v(i,3,j+1)) &
1410 +(ht(i,j )-ht(i,j-1)) &
1411 *(cf1*v(i,1,j )+cf2*v(i,2,j )+cf3*v(i,3,j )) ) &
1412
1413 +.5*rdx*( &
1414 (ht(i+1,j)-ht(i,j )) &
1415 *(cf1*u(i+1,1,j)+cf2*u(i+1,2,j)+cf3*u(i+1,3,j)) &
1416 +(ht(i,j )-ht(i-1,j)) &
1417 *(cf1*u(i ,1,j)+cf2*u(i ,2,j)+cf3*u(i ,3,j)) )
1418
1419 ENDDO
1420 !
1421 ! Jammed 3 doubly nested loops over k/i into 1 for slight improvement
1422 ! in efficiency. No change in results (bit-for-bit). JM 20040514
1423 ! (left a blank line where the other two k/i-loops were)
1424 !
1425 DO k=2,k_end
1426 DO i=i_start, i_end
1427 w(i,k,j)=w(i,k,j)+dts*rw_tend(i,k,j) &
1428 + msft_inv(i)*cqw(i,k,j)*( &
1429 +.5*dts*g*mut_inv(i)*rdn(k)* &
1430 (c2a(i,k ,j)*rdnw(k ) &
1431 *((1.+epssm)*(rhs(i,k+1 )-rhs(i,k )) &
1432 +(1.-epssm)*(ph(i,k+1,j)-ph(i,k ,j))) &
1433 -c2a(i,k-1,j)*rdnw(k-1) &
1434 *((1.+epssm)*(rhs(i,k )-rhs(i,k-1 )) &
1435 +(1.-epssm)*(ph(i,k ,j)-ph(i,k-1,j))))) &
1436
1437 +dts*g*msft_inv(i)*(rdn(k)* &
1438 (c2a(i,k ,j)*alt(i,k ,j)*t_2ave(i,k ,j) &
1439 -c2a(i,k-1,j)*alt(i,k-1,j)*t_2ave(i,k-1,j)) &
1440 - muave(i,j))
1441 ENDDO
1442 ENDDO
1443
1444 K=k_end+1
1445
1446 DO i=i_start, i_end
1447 w(i,k,j)=w(i,k,j)+dts*rw_tend(i,k,j) &
1448 +msft_inv(i)*( &
1449 -.5*dts*g*mut_inv(i)*rdnw(k-1)**2*2.*c2a(i,k-1,j) &
1450 *((1.+epssm)*(rhs(i,k )-rhs(i,k-1 )) &
1451 +(1.-epssm)*(ph(i,k,j)-ph(i,k-1,j))) &
1452 -dts*g*(2.*rdnw(k-1)* &
1453 c2a(i,k-1,j)*alt(i,k-1,j)*t_2ave(i,k-1,j) &
1454 + muave(i,j)) )
1455 ENDDO
1456
1457 DO k=2,k_end+1
1458 DO i=i_start, i_end
1459 w(i,k,j)=(w(i,k,j)-a(i,k,j)*w(i,k-1,j))*alpha(i,k,j)
1460 ENDDO
1461 ENDDO
1462
1463 DO k=k_end,2,-1
1464 DO i=i_start, i_end
1465 w (i,k,j)=w (i,k,j)-gamma(i,k,j)*w(i,k+1,j)
1466 ENDDO
1467 ENDDO
1468
1469 IF (config_flags%damp_opt .eq. 3) THEN
1470 DO k=k_end+1,2,-1
1471 DO i=i_start, i_end
1472 htop=(ph_1(i,k_end+1,j)+phb(i,k_end+1,j))/g
1473 hk=(ph_1(i,k,j)+phb(i,k,j))/g
1474 hbot=htop-hdepth
1475 dampwt(k) = 0.
1476 if(hk .ge. hbot)then
1477 dampwt(k) = dampmag*sin(0.5*pi*(hk-hbot)/hdepth)*sin(0.5*pi*(hk-hbot)/hdepth)
1478 endif
1479 w(i,k,j) = (w(i,k,j) - dampwt(k)*mut(i,j)*w_save(i,k,j))/(1.+dampwt(k))
1480 ENDDO
1481 ENDDO
1482 ENDIF
1483
1484 DO k=k_end+1,2,-1
1485 DO i=i_start, i_end
1486 ph(i,k,j) = rhs(i,k)+msft(i,j)*.5*dts*g*(1.+epssm) &
1487 *w(i,k,j)/muts(i,j)
1488 ENDDO
1489 ENDDO
1490
1491 ENDDO j_loop_w
1492
1493 END SUBROUTINE advance_w
1494
1495 !---------------------------------------------------------------------
1496
1497 SUBROUTINE sumflux ( ru, rv, ww, &
1498 u_lin, v_lin, ww_lin, &
1499 muu, muv, &
1500 ru_m, rv_m, ww_m, epssm, &
1501 msfu, msfv, &
1502 iteration , number_of_small_timesteps, &
1503 ids,ide, jds,jde, kds,kde, &
1504 ims,ime, jms,jme, kms,kme, &
1505 its,ite, jts,jte, kts,kte )
1506
1507
1508 IMPLICIT NONE ! religion first
1509
1510 ! declarations for the stuff coming in
1511
1512 INTEGER, INTENT(IN ) :: number_of_small_timesteps
1513 INTEGER, INTENT(IN ) :: iteration
1514 INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde
1515 INTEGER, INTENT(IN ) :: ims,ime, jms,jme, kms,kme
1516 INTEGER, INTENT(IN ) :: its,ite, jts,jte, kts,kte
1517
1518 REAL, DIMENSION(ims:ime, kms:kme, jms:jme), INTENT(IN ) :: ru, &
1519 rv, &
1520 ww, &
1521 u_lin, &
1522 v_lin, &
1523 ww_lin
1524
1525
1526 REAL, DIMENSION(ims:ime, kms:kme, jms:jme) , INTENT(INOUT) :: ru_m, &
1527 rv_m, &
1528 ww_m
1529 REAL, DIMENSION(ims:ime, jms:jme) , INTENT(IN ) :: muu, muv, msfu, msfv
1530
1531 INTEGER :: mini, minj, mink
1532
1533
1534 REAL, INTENT(IN ) :: epssm
1535 INTEGER :: i,j,k
1536
1537
1538 !<DESCRIPTION>
1539 !
1540 ! update the small-timestep time-averaged mass fluxes; these
1541 ! are needed for consistent mass-conserving scalar advection.
1542 !
1543 !</DESCRIPTION>
1544
1545 IF (iteration == 1 )THEN
1546 DO j = jts, jte
1547 DO k = kts, kte
1548 DO i = its, ite
1549 ru_m(i,k,j) = 0.
1550 rv_m(i,k,j) = 0.
1551 ww_m(i,k,j) = 0.
1552 ENDDO
1553 ENDDO
1554 ENDDO
1555 ENDIF
1556
1557 mini = min(ide-1,ite)
1558 minj = min(jde-1,jte)
1559 mink = min(kde-1,kte)
1560
1561
1562 DO j = jts, minj
1563 DO k = kts, mink
1564 DO i = its, mini
1565 ru_m(i,k,j) = ru_m(i,k,j) + ru(i,k,j)
1566 rv_m(i,k,j) = rv_m(i,k,j) + rv(i,k,j)
1567 ww_m(i,k,j) = ww_m(i,k,j) + ww(i,k,j)
1568 ENDDO
1569 ENDDO
1570 ENDDO
1571
1572 IF (ite .GT. mini) THEN
1573 DO j = jts, minj
1574 DO k = kts, mink
1575 DO i = mini+1, ite
1576 ru_m(i,k,j) = ru_m(i,k,j) + ru(i,k,j)
1577 ENDDO
1578 ENDDO
1579 ENDDO
1580 END IF
1581 IF (jte .GT. minj) THEN
1582 DO j = minj+1, jte
1583 DO k = kts, mink
1584 DO i = its, mini
1585 rv_m(i,k,j) = rv_m(i,k,j) + rv(i,k,j)
1586 ENDDO
1587 ENDDO
1588 ENDDO
1589 END IF
1590 IF ( kte .GT. mink) THEN
1591 DO j = jts, minj
1592 DO k = mink+1, kte
1593 DO i = its, mini
1594 ww_m(i,k,j) = ww_m(i,k,j) + ww(i,k,j)
1595 ENDDO
1596 ENDDO
1597 ENDDO
1598 END IF
1599
1600 IF (iteration == number_of_small_timesteps) THEN
1601
1602 DO j = jts, minj
1603 DO k = kts, mink
1604 DO i = its, mini
1605 ru_m(i,k,j) = ru_m(i,k,j) / number_of_small_timesteps &
1606 + muu(i,j)*u_lin(i,k,j)/msfu(i,j)
1607 rv_m(i,k,j) = rv_m(i,k,j) / number_of_small_timesteps &
1608 + muv(i,j)*v_lin(i,k,j)/msfv(i,j)
1609 ww_m(i,k,j) = ww_m(i,k,j) / number_of_small_timesteps &
1610 + ww_lin(i,k,j)
1611 ENDDO
1612 ENDDO
1613 ENDDO
1614
1615
1616 IF (ite .GT. mini) THEN
1617 DO j = jts, minj
1618 DO k = kts, mink
1619 DO i = mini+1, ite
1620 ru_m(i,k,j) = ru_m(i,k,j) / number_of_small_timesteps &
1621 + muu(i,j)*u_lin(i,k,j)/msfu(i,j)
1622 ENDDO
1623 ENDDO
1624 ENDDO
1625 END IF
1626 IF (jte .GT. minj) THEN
1627 DO j = minj+1, jte
1628 DO k = kts, mink
1629 DO i = its, mini
1630 rv_m(i,k,j) = rv_m(i,k,j) / number_of_small_timesteps &
1631 + muv(i,j)*v_lin(i,k,j)/msfv(i,j)
1632 ENDDO
1633 ENDDO
1634 ENDDO
1635 END IF
1636 IF ( kte .GT. mink) THEN
1637 DO j = jts, minj
1638 DO k = mink+1, kte
1639 DO i = its, mini
1640 ww_m(i,k,j) = ww_m(i,k,j) / number_of_small_timesteps &
1641 + ww_lin(i,k,j)
1642 ENDDO
1643 ENDDO
1644 ENDDO
1645 END IF
1646
1647 ENDIF
1648
1649
1650 END SUBROUTINE sumflux
1651
1652 !---------------------------------------------------------------------
1653
1654 SUBROUTINE init_module_small_step
1655 END SUBROUTINE init_module_small_step
1656
1657 END MODULE module_small_step_em