Changeset 5159 for LMDZ6/branches/Amaury_dev/libf/dyn3d_common/ppm3d.f90
- Timestamp:
- Aug 2, 2024, 9:58:25 PM (7 weeks ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
LMDZ6/branches/Amaury_dev/libf/dyn3d_common/ppm3d.f90
r5158 r5159 16 16 17 17 ! ******************************************************************** 18 ! 18 19 19 ! TransPort Core for Goddard Chemistry Transport Model (G-CTM), Goddard 20 20 ! Earth Observing System General Circulation Model (GEOS-GCM), and Data 21 21 ! Assimilation System (GEOS-DAS). 22 ! 22 23 23 ! ******************************************************************** 24 ! 24 25 25 ! Purpose: given horizontal winds on a hybrid sigma-p surfaces, 26 26 ! one CALL to tpcore updates the 3-D mixing ratio … … 28 28 ! internally consistent with the discretized hydrostatic mass 29 29 ! continuity equation of the C-Grid GEOS-GCM (for IGD=1)]. 30 ! 30 31 31 ! Schemes: Multi-dimensional Flux Form Semi-Lagrangian (FFSL) scheme based 32 32 ! on the van Leer or PPM. … … 38 38 ! Subroutines modified: xtp, ytp, fzppm, qckxyz 39 39 ! Subroutines deleted: vanz 40 ! 40 41 41 ! Author: Shian-Jiann Lin 42 42 ! mail address: … … 45 45 ! Phone: 301-286-9540 46 46 ! E-mail: lin@dao.gsfc.nasa.gov 47 ! 47 48 48 ! *affiliation: 49 49 ! Joint Center for Earth Systems Technology … … 51 51 ! NASA - Goddard Space Flight Center 52 52 ! References: 53 ! 53 54 54 ! 1. Lin, S.-J., and R. B. Rood, 1996: Multidimensional flux form semi- 55 55 ! Lagrangian transport schemes. Mon. Wea. Rev., 124, 2046-2070. 56 ! 56 57 57 ! 2. Lin, S.-J., W. C. Chao, Y. C. Sud, and G. K. Walker, 1994: A class of 58 58 ! the van Leer-type transport schemes and its applications to the moist- 59 59 ! ure transport in a General Circulation Model. Mon. Wea. Rev., 122, 60 60 ! 1575-1593. 61 ! 61 62 62 ! ****6***0*********0*********0*********0*********0*********0**********72 63 ! 63 64 64 SUBROUTINE ppm3d(IGD,Q,PS1,PS2,U,V,W,NDT,IORD,JORD,KORD,NC,IMR, & 65 65 JNP,j1,NLAY,AP,BP,PT,AE,fill,dum,Umax) … … 72 72 ! real dtdy,dtdy5,rcap,iml,jn0,imjm,pi,dl,dp 73 73 ! real dt,cr1,maxdt,ztc,d5,sum1,sum2,ru 74 ! 74 75 75 ! ******************************************************************** 76 ! 76 77 77 ! ============= 78 78 ! INPUT: 79 79 ! ============= 80 ! 80 81 81 ! Q(IMR,JNP,NLAY,NC): mixing ratios at current time (t) 82 82 ! NC: total # of constituents … … 86 86 ! the model top to NLAY near the surface (see fig. below). 87 87 ! It is assumed that 6 <= NLAY <= JNP (for dynamic memory allocation) 88 ! 88 89 89 ! PS1(IMR,JNP): surface pressure at current time (t) 90 90 ! PS2(IMR,JNP): surface pressure at mid-time-level (t+NDT/2) … … 92 92 ! Note: surface pressure can have any unit or can be multiplied by any 93 93 ! const. 94 ! 94 95 95 ! The pressure at layer edges are defined as follows: 96 ! 96 97 97 ! p(i,j,k) = AP(k)*PT + BP(k)*PS(i,j) (1) 98 ! 98 99 99 ! Where PT is a constant having the same unit as PS. 100 100 ! AP and BP are unitless constants given at layer edges … … 102 102 ! BP(1) = 0., BP(NLAY+1) = 1. 103 103 ! The pressure at the model top is PTOP = AP(1)*PT 104 ! 104 105 105 ! For pure sigma system set AP(k) = 1 for all k, PT = PTOP, 106 106 ! BP(k) = sige(k) (sigma at edges), PS = Psfc - PTOP. 107 ! 107 108 108 ! Note: the sigma-P coordinate is a subset of Eq. 1, which in turn 109 109 ! is a subset of the following even more general sigma-P-thelta coord. 110 110 ! currently under development. 111 111 ! p(i,j,k) = (AP(k)*PT + BP(k)*PS(i,j))/(D(k)-C(k)*TE**(-1/kapa)) 112 ! 112 113 113 ! ///////////////////////////////// 114 114 ! / \ ------------- PTOP -------------- AP(1), BP(1) … … 117 117 ! | 118 118 ! W(1) \ / --------------------------------- AP(2), BP(2) 119 ! 120 ! 121 ! 119 120 121 122 122 ! W(k-1) / \ --------------------------------- AP(k), BP(k) 123 123 ! | … … 125 125 ! | 126 126 ! W(k) \ / --------------------------------- AP(k+1), BP(k+1) 127 ! 128 ! 129 ! 127 128 129 130 130 ! / \ --------------------------------- AP(NLAY), BP(NLAY) 131 131 ! | … … 134 134 ! W(NLAY)=0 \ / ------------- surface ----------- AP(NLAY+1), BP(NLAY+1) 135 135 ! ////////////////////////////////// 136 ! 136 137 137 ! U(IMR,JNP,NLAY) & V(IMR,JNP,NLAY):winds (m/s) at mid-time-level (t+NDT/2) 138 138 ! U and V may need to be polar filtered in advance in some cases. 139 ! 139 140 140 ! IGD: grid type on which winds are defined. 141 141 ! IGD = 0: A-Grid [all variables defined at the same point from south 142 142 ! pole (j=1) to north pole (j=JNP) ] 143 ! 143 144 144 ! IGD = 1 GEOS-GCM C-Grid 145 145 ! [North] 146 ! 146 147 147 ! V(i,j) 148 148 ! | … … 154 154 ! | 155 155 ! V(i,j-1) 156 ! 156 157 157 ! U(i, 1) is defined at South Pole. 158 158 ! V(i, 1) is half grid north of the South Pole. 159 159 ! V(i,JMR) is half grid south of the North Pole. 160 ! 160 161 161 ! V must be defined at j=1 and j=JMR if IGD=1 162 162 ! V at JNP need not be given. 163 ! 163 164 164 ! NDT: time step in seconds (need not be constant during the course of 165 165 ! the integration). Suggested value: 30 min. for 4x5, 15 min. for 2x2.5 166 166 ! (Lat-Lon) resolution. Smaller values are recommanded if the model 167 167 ! has a well-resolved stratosphere. 168 ! 168 169 169 ! J1 defines the size of the polar cap: 170 170 ! South polar cap edge is located at -90 + (j1-1.5)*180/(JNP-1) deg. … … 172 172 ! There are currently only two choices (j1=2 or 3). 173 173 ! IMR must be an even integer if j1 = 2. Recommended value: J1=3. 174 ! 174 175 175 ! IORD, JORD, and KORD are integers controlling various options in E-W, N-S, 176 176 ! and vertical transport, respectively. Recommended values for positive … … 178 178 ! positive definite scalars or when linear correlation between constituents 179 179 ! is to be maintained. 180 ! 180 181 181 ! _ORD= 182 182 ! 1: 1st order upstream scheme (too diffusive, not a useful option; it … … 193 193 ! positivity not quaranteed. Use this option only when the fields 194 194 ! and winds are very smooth). 195 ! 195 196 196 ! *PPM: Piece-wise Parabolic Method 197 ! 197 198 198 ! Note that KORD <=2 options are no longer supported. DO not use option 4 or 5. 199 199 ! for non-positive definite scalars (such as Ertel Potential Vorticity). 200 ! 200 201 201 ! The implicit numerical diffusion decreases as _ORD increases. 202 202 ! The last two options (ORDER=5, 6) should only be used when there is … … 204 204 ! might get dispersive results otherwise. 205 205 ! No filter of any kind is applied to the constituent fields here. 206 ! 206 207 207 ! AE: Radius of the sphere (meters). 208 208 ! Recommended value for the planet earth: 6.371E6 209 ! 209 210 210 ! fill(logical): flag to do filling for negatives (see note below). 211 ! 211 212 212 ! Umax: Estimate (upper limit) of the maximum U-wind speed (m/s). 213 213 ! (220 m/s is a good value for troposphere model; 280 m/s otherwise) 214 ! 214 215 215 ! ============= 216 216 ! Output 217 217 ! ============= 218 ! 218 219 219 ! Q: mixing ratios at future time (t+NDT) (original values are over-written) 220 220 ! W(NLAY): large-scale vertical mass flux as diagnosed from the hydrostatic … … 227 227 ! ( W > 0 is downward, ie, toward surface) 228 228 ! PS2: predicted PS at t+NDT (original values are over-written) 229 ! 229 230 230 ! ******************************************************************** 231 231 ! NOTES: … … 235 235 ! that the computed vertical velocity to be identical to GEOS-1 GCM 236 236 ! for on-line transport. 237 ! 237 238 238 ! A larger polar cap is used if j1=3 (recommended for C-Grid winds or when 239 239 ! winds are noisy near poles). 240 ! 240 241 241 ! Flux-Form Semi-Lagrangian transport in the East-West direction is used 242 242 ! when and where Courant # is greater than one. 243 ! 243 244 244 ! The user needs to change the parameter Jmax or Kmax if the resolution 245 245 ! is greater than 0.5 deg in N-S or 150 layers in the vertical direction. 246 246 ! (this TransPort Core is otherwise resolution independent and can be used 247 247 ! as a library routine). 248 ! 248 249 249 ! PPM is 4th order accurate when grid spacing is uniform (x & y); 3rd 250 250 ! order accurate for non-uniform grid (vertical sigma coord.). 251 ! 251 252 252 ! Time step is limitted only by transport in the meridional direction. 253 253 ! (the FFSL scheme is not implemented in the meridional direction). 254 ! 254 255 255 ! Since only 1-D limiters are applied, negative values could 256 256 ! potentially be generated when large time step is used and when the … … 259 259 ! These negatives are typically very small. A filling algorithm is 260 260 ! activated if the user set "fill" to be true. 261 ! 261 262 262 ! The van Leer scheme used here is nearly as accurate as the original PPM 263 263 ! due to the use of a 4th order accurate reference slope. The PPM imple- 264 264 ! mented here is an improvement over the original and is also based on 265 265 ! the 4th order reference slope. 266 ! 266 267 267 ! ****6***0*********0*********0*********0*********0*********0**********72 268 ! 268 269 269 ! User modifiable parameters 270 ! 270 271 271 INTEGER,parameter :: Jmax = 361, kmax = 150 272 ! 272 273 273 ! ****6***0*********0*********0*********0*********0*********0**********72 274 ! 274 275 275 ! Input-Output arrays 276 276 ! … … 283 283 REAL :: PT 284 284 LOGICAL :: cross, fill, dum 285 ! 285 286 286 ! Local dynamic arrays 287 ! 287 288 288 REAL :: CRX(IMR,JNP),CRY(IMR,JNP),xmass(IMR,JNP),ymass(IMR,JNP), & 289 289 fx1(IMR+1),DPI(IMR,JNP,NLAY),delp1(IMR,JNP,NLAY), & … … 291 291 delp2(IMR,JNP,NLAY),DQ(IMR,JNP,NLAY,NC),VA(IMR,JNP), & 292 292 UA(IMR,JNP),qtmp(-IMR:2*IMR) 293 ! 293 294 294 ! Local static arrays 295 ! 295 296 296 REAL :: DTDX(Jmax), DTDX5(Jmax), acosp(Jmax), & 297 297 cosp(Jmax), cose(Jmax), DAP(kmax),DBK(Kmax) … … 302 302 SAVE DTDY, DTDY5, RCAP, JS0, JN0, IML, & 303 303 DTDX, DTDX5, ACOSP, COSP, COSE, DAP,DBK 304 ! 304 305 305 INTEGER :: NDT0, NSTEP, j2, k,j,i,ic,l,JS,JN,IMH 306 306 INTEGER :: IU,IIU,JT,iad,jad,krd … … 312 312 j2 = JNP - j1 + 1 313 313 NSTEP = NSTEP + 1 314 ! 314 315 315 ! *********** Initialization ********************** 316 316 IF(NSTEP==1) THEN 317 ! 317 318 318 WRITE(6,*) '------------------------------------ ' 319 319 WRITE(6,*) 'NASA/GSFC Transport Core Version 4.5' 320 320 WRITE(6,*) '------------------------------------ ' 321 ! 321 322 322 WRITE(6,*) 'IMR=',IMR,' JNP=',JNP,' NLAY=',NLAY,' j1=',j1 323 323 WRITE(6,*) 'NC=',NC,IORD,JORD,KORD,NDT 324 ! 324 325 325 ! controles sur les parametres 326 326 IF(NLAY<6) THEN … … 338 338 ENDIF 339 339 340 ! 340 341 341 IF(Jmax<JNP .OR. Kmax<NLAY) THEN 342 342 WRITE(6,*) 'Jmax or Kmax is too small' 343 343 stop 344 344 ENDIF 345 ! 345 346 346 DO k=1,NLAY 347 347 DAP(k) = (AP(k+1) - AP(k))*PT 348 348 DBK(k) = BP(k+1) - BP(k) 349 349 ENDDO 350 ! 350 351 351 PI = 4. * ATAN(1.) 352 352 DL = 2.*PI / REAL(IMR) 353 353 DP = PI / REAL(JMR) 354 ! 354 355 355 IF(IGD==0) THEN 356 356 ! Compute analytic cosine at cell edges … … 360 360 CALL cosc(cosp,cose,JNP,PI,DP) 361 361 ENDIF 362 ! 362 363 363 DO J=2,JMR 364 364 acosp(j) = 1. / cosp(j) 365 365 END DO 366 ! 366 367 367 ! Inverse of the Scaled polar cap area. 368 ! 368 369 369 RCAP = DP / (IMR*(1.-COS((j1-1.5)*DP))) 370 370 acosp(1) = RCAP 371 371 acosp(JNP) = RCAP 372 372 ENDIF 373 ! 373 374 374 IF(NDT0 /= NDT) THEN 375 375 DT = NDT … … 385 385 WRITE(6,*) 'Warning!!! NDT maybe too large!' 386 386 ENDIF 387 ! 387 388 388 IF(CR1>=0.95) THEN 389 389 JS0 = 0 … … 393 393 else 394 394 ZTC = acos(CR1) * (180./PI) 395 ! 395 396 396 JS0 = REAL(JMR)*(90.-ZTC)/180. + 2 397 397 JS0 = max(JS0, J1+1) … … 399 399 JN0 = JNP-JS0+1 400 400 ENDIF 401 ! 402 ! 401 402 403 403 DO J=2,JMR 404 404 DTDX(j) = DT / ( DL*AE*COSP(J) ) … … 412 412 ! PRINT*,'dtdy=',dtdy 413 413 DTDY5 = 0.5*DTDY 414 ! 414 415 415 ! WRITE(6,*) 'J1=',J1,' J2=', J2 416 416 ENDIF 417 ! 417 418 418 ! *********** End Initialization ********************** 419 ! 419 420 420 ! delp = pressure thickness: the psudo-density in a hydrostatic system. 421 421 DO k=1,NLAY … … 428 428 enddo 429 429 430 ! 430 431 431 IF(j1/=2) THEN 432 432 DO IC=1,NC … … 439 439 END DO 440 440 ENDIF 441 ! 441 442 442 ! Compute "tracer density" 443 443 DO IC=1,NC … … 450 450 END DO 451 451 END DO 452 ! 452 453 453 DO k=1,NLAY 454 ! 454 455 455 IF(IGD==0) THEN 456 456 ! Convert winds on A-Grid to Courant # on C-Grid. … … 464 464 END DO 465 465 466 ! 466 467 467 DO j=j1,j2 468 468 CRX(1,J) = dtdx(j)*U(IMR,j,k) 469 469 END DO 470 ! 470 471 471 DO i=1,IMR*JMR 472 472 CRY(i,2) = DTDY*V(i,1,k) 473 473 END DO 474 474 ENDIF 475 ! 475 476 476 ! Determine JS and JN 477 477 JS = j1 478 478 JN = j2 479 ! 479 480 480 DO j=JS0,j1+1,-1 481 481 DO i=1,IMR … … 486 486 enddo 487 487 enddo 488 ! 488 489 489 2222 continue 490 490 DO j=JN0,j2-1 … … 497 497 enddo 498 498 2233 continue 499 ! 499 500 500 IF(j1/=2) then ! Enlarged polar cap. 501 501 DO i=1,IMR … … 504 504 enddo 505 505 ENDIF 506 ! 506 507 507 ! ******* Compute horizontal mass fluxes ************ 508 ! 508 509 509 ! N-S component 510 510 DO j=j1,j2+1 … … 514 514 enddo 515 515 enddo 516 ! 516 517 517 DO j=j1,j2 518 518 DO i=1,IMR … … 520 520 END DO 521 521 END DO 522 ! 522 523 523 ! Poles 524 524 sum1 = ymass(IMR,j1 ) … … 528 528 sum2 = sum2 + ymass(i,J2+1) 529 529 enddo 530 ! 530 531 531 sum1 = - sum1 * RCAP 532 532 sum2 = sum2 * RCAP … … 535 535 DPI(i,JNP,k) = sum2 536 536 enddo 537 ! 537 538 538 ! E-W component 539 ! 539 540 540 DO j=j1,j2 541 541 DO i=2,IMR … … 543 543 enddo 544 544 enddo 545 ! 545 546 546 DO j=j1,j2 547 547 PU(1,j) = 0.5 * (delp2(1,j,k) + delp2(IMR,j,k)) 548 548 enddo 549 ! 549 550 550 DO j=j1,j2 551 551 DO i=1,IMR … … 553 553 END DO 554 554 END DO 555 ! 555 556 556 DO j=j1,j2 557 557 DO i=1,IMR-1 … … 559 559 END DO 560 560 END DO 561 ! 561 562 562 DO j=j1,j2 563 563 DPI(IMR,j,k) = DPI(IMR,j,k) + xmass(IMR,j) - xmass(1,j) 564 564 END DO 565 ! 565 566 566 DO j=j1,j2 567 567 DO i=1,IMR-1 … … 569 569 enddo 570 570 enddo 571 ! 571 572 572 DO j=j1,j2 573 573 UA(imr,j) = 0.5 * (CRX(imr,j)+CRX(1,j)) … … 585 585 VA(i,2) = 0.5*(CRY(i,2)+CRY(i,3)) 586 586 enddo 587 ! 587 588 588 IF(j1==2) THEN 589 589 IMH = IMR/2 … … 597 597 VA(IMR,JNP)=VA(1,JNP) 598 598 ENDIF 599 ! 599 600 600 ! ****6***0*********0*********0*********0*********0*********0**********72 601 601 DO IC=1,NC 602 ! 602 603 603 DO i=1,IMJM 604 604 wk1(i,1,1) = 0. 605 605 wk1(i,1,2) = 0. 606 606 enddo 607 ! 607 608 608 ! E-W advective cross term 609 609 DO j=J1,J2 610 610 IF(J>JS .AND. J<JN) GO TO 250 611 ! 611 612 612 DO i=1,IMR 613 613 qtmp(i) = q(i,j,k,IC) 614 614 enddo 615 ! 615 616 616 DO i=-IML,0 617 617 qtmp(i) = q(IMR+i,j,k,IC) 618 618 qtmp(IMR+1-i) = q(1-i,j,k,IC) 619 619 enddo 620 ! 620 621 621 DO i=1,IMR 622 622 iu = UA(i,j) … … 632 632 250 continue 633 633 END DO 634 ! 634 635 635 IF(JN/=0) THEN 636 636 DO j=JS+1,JN-1 637 ! 637 638 638 DO i=1,IMR 639 639 qtmp(i) = q(i,j,k,IC) 640 640 enddo 641 ! 641 642 642 qtmp(0) = q(IMR,J,k,IC) 643 643 qtmp(IMR+1) = q( 1,J,k,IC) 644 ! 644 645 645 DO i=1,imr 646 646 iu = i - UA(i,j) … … 655 655 wk1(i,j1,2) = VA(i,j1) * (q(i,jt,k,IC) - q(i,jt+1,k,IC)) 656 656 enddo 657 ! 657 658 658 DO i=1,IMJM 659 659 wk1(i,1,1) = q(i,1,k,IC) + 0.5*wk1(i,1,1) 660 660 wk1(i,1,2) = q(i,1,k,IC) + 0.5*wk1(i,1,2) 661 661 enddo 662 ! 662 663 663 IF(cross) THEN 664 664 ! Add cross terms in the vertical direction. … … 668 668 iad = 1 669 669 endif 670 ! 670 671 671 IF(JORD >= 2) THEN 672 672 jad = 2 … … 682 682 enddo 683 683 ENDIF 684 ! 684 685 685 CALL xtp(IMR,JNP,IML,j1,j2,JN,JS,PU,DQ(1,1,k,IC),wk1(1,1,2) & 686 686 ,CRX,fx1,xmass,IORD) … … 688 688 CALL ytp(IMR,JNP,j1,j2,acosp,RCAP,DQ(1,1,k,IC),wk1(1,1,1),CRY, & 689 689 DC2,ymass,WK1(1,1,3),wk1(1,1,4),WK1(1,1,5),WK1(1,1,6),JORD) 690 ! 691 END DO 692 END DO 693 ! 690 691 END DO 692 END DO 693 694 694 ! ******* Compute vertical mass flux (same unit as PS) *********** 695 ! 695 696 696 ! 1st step: compute total column mass CONVERGENCE. 697 ! 697 698 698 DO j=1,JNP 699 699 DO i=1,IMR … … 701 701 END DO 702 702 END DO 703 ! 703 704 704 DO k=2,NLAY 705 705 DO j=1,JNP … … 709 709 END DO 710 710 END DO 711 ! 711 712 712 DO j=1,JNP 713 713 DO i=1,IMR 714 ! 714 715 715 ! 2nd step: compute PS2 (PS at n+1) using the hydrostatic assumption. 716 716 ! Changes (increases) to surface pressure = total column mass convergence 717 ! 717 718 718 PS2(i,j) = PS1(i,j) + CRY(i,j) 719 ! 719 720 720 ! 3rd step: compute vertical mass flux from mass conservation principle. 721 ! 721 722 722 W(i,j,1) = DPI(i,j,1) - DBK(1)*CRY(i,j) 723 723 W(i,j,NLAY) = 0. 724 724 END DO 725 725 END DO 726 ! 726 727 727 DO k=2,NLAY-1 728 728 DO j=1,JNP … … 732 732 END DO 733 733 END DO 734 ! 734 735 735 DO k=1,NLAY 736 736 DO j=1,JNP … … 740 740 END DO 741 741 END DO 742 ! 742 743 743 KRD = max(3, KORD) 744 744 DO IC=1,NC 745 ! 745 746 746 !****6***0*********0*********0*********0*********0*********0**********72 747 747 … … 752 752 IF(fill) CALL qckxyz(DQ(1,1,1,IC),DC2,IMR,JNP,NLAY,j1,j2, & 753 753 cosp,acosp,.FALSE.,IC,NSTEP) 754 ! 754 755 755 ! Recover tracer mixing ratio from "density" using predicted 756 756 ! "air density" (pressure thickness) at time-level n+1 757 ! 757 758 758 DO k=1,NLAY 759 759 DO j=1,JNP … … 764 764 enddo 765 765 enddo 766 ! 766 767 767 IF(j1/=2) THEN 768 768 DO k=1,NLAY … … 775 775 ENDIF 776 776 END DO 777 ! 777 778 778 IF(j1/=2) THEN 779 779 DO k=1,NLAY … … 784 784 END DO 785 785 ENDIF 786 ! 786 787 787 RETURN 788 788 END SUBROUTINE ppm3d 789 ! 789 790 790 !****6***0*********0*********0*********0*********0*********0**********72 791 791 SUBROUTINE FZPPM(IMR,JNP,NLAY,j1,DQ,WZ,P,DC,DQDT,AR,AL,A6, & … … 803 803 INTEGER :: JMR,IMJM,NLAYM1,LMT,K,I,J 804 804 REAL :: c0,c1,c2,tmp,qmax,qmin,a,b,fct,a1,a2,cm,cp 805 ! 805 806 806 JMR = JNP - 1 807 807 IMJM = IMR*JNP 808 808 NLAYM1 = NLAY - 1 809 ! 809 810 810 LMT = KORD - 3 811 ! 811 812 812 ! ****6***0*********0*********0*********0*********0*********0**********72 813 813 ! Compute DC for PPM 814 814 ! ****6***0*********0*********0*********0*********0*********0**********72 815 ! 815 816 816 DO k=1,NLAYM1 817 817 DO i=1,IMJM … … 819 819 END DO 820 820 END DO 821 ! 821 822 822 DO k=2,NLAYM1 823 823 DO I=1,IMJM … … 832 832 END DO 833 833 834 ! 834 835 835 ! ****6***0*********0*********0*********0*********0*********0**********72 836 836 ! Loop over latitudes (to save memory) 837 837 ! ****6***0*********0*********0*********0*********0*********0**********72 838 ! 838 839 839 DO j=1,JNP 840 840 IF((j==2 .OR. j==JMR) .AND. j1/=2) goto 2000 841 ! 841 842 842 DO k=1,NLAY 843 843 DO i=1,IMR … … 848 848 enddo 849 849 enddo 850 ! 850 851 851 !****6***0*********0*********0*********0*********0*********0**********72 852 852 ! Compute first guesses at cell interfaces 853 853 ! First guesses are required to be continuous. 854 854 ! ****6***0*********0*********0*********0*********0*********0**********72 855 ! 855 856 856 ! three-cell parabolic subgrid distribution at model top 857 857 ! two-cell parabolic with zero gradient subgrid distribution 858 858 ! at the surface. 859 ! 859 860 860 ! First guess top edge value 861 861 DO i=1,IMR … … 869 869 AL(i,1) = wk1(i,1) - wk2(i,1)*(R3*a*wk2(i,1) + 0.5*b) 870 870 AL(i,2) = wk2(i,1)*(a*wk2(i,1) + b) + AL(i,1) 871 ! 871 872 872 ! Check if change sign 873 873 IF(wk1(i,1)*AL(i,1)<=0.) THEN … … 878 878 endif 879 879 END DO 880 ! 880 881 881 ! Bottom 882 882 DO i=1,IMR 883 883 ! 2-cell PPM with zero gradient right at the surface 884 ! 884 885 885 fct = DQDT(i,j,NLAYM1)*wk2(i,NLAY)**2 / & 886 886 ( (wk2(i,NLAY)+wk2(i,NLAYM1))*(2.*wk2(i,NLAY)+wk2(i,NLAYM1))) … … 891 891 END DO 892 892 893 ! 893 894 894 !****6***0*********0*********0*********0*********0*********0**********72 895 895 ! 4th order interpolation in the interior. 896 896 !****6***0*********0*********0*********0*********0*********0**********72 897 ! 897 898 898 DO k=3,NLAYM1 899 899 DO i=1,IMR … … 908 908 END DO 909 909 END DO 910 ! 910 911 911 DO i=1,IMR*NLAYM1 912 912 AR(i,1) = AL(i,2) 913 913 ! print *,'AR1',i,AR(i,1) 914 914 END DO 915 ! 915 916 916 DO i=1,IMR*NLAY 917 917 A6(i,1) = 3.*(wk1(i,1)+wk1(i,1) - (AL(i,1)+AR(i,1))) 918 918 ! print *,'A61',i,A6(i,1) 919 919 END DO 920 ! 920 921 921 !****6***0*********0*********0*********0*********0*********0**********72 922 922 ! Top & Bot always monotonic … … 924 924 CALL lmtppm(flux(1,NLAY),A6(1,NLAY),AR(1,NLAY),AL(1,NLAY), & 925 925 wk1(1,NLAY),IMR,0) 926 ! 926 927 927 ! Interior depending on KORD 928 928 IF(LMT<=2) & 929 929 CALL lmtppm(flux(1,2),A6(1,2),AR(1,2),AL(1,2),wk1(1,2), & 930 930 IMR*(NLAY-2),LMT) 931 ! 931 932 932 !****6***0*********0*********0*********0*********0*********0**********72 933 ! 933 934 934 DO i=1,IMR*NLAYM1 935 935 IF(wz2(i,1)>0.) THEN … … 944 944 ENDIF 945 945 END DO 946 ! 946 947 947 DO i=1,IMR*NLAYM1 948 948 flux(i,2) = wz2(i,1) * flux(i,2) 949 949 END DO 950 ! 950 951 951 DO i=1,IMR 952 952 DQ(i,j, 1) = DQ(i,j, 1) - flux(i, 2) 953 953 DQ(i,j,NLAY) = DQ(i,j,NLAY) + flux(i,NLAY) 954 954 END DO 955 ! 955 956 956 DO k=2,NLAYM1 957 957 DO i=1,IMR … … 963 963 RETURN 964 964 END SUBROUTINE fzppm 965 ! 965 966 966 SUBROUTINE xtp(IMR,JNP,IML,j1,j2,JN,JS,PU,DQ,Q,UC, & 967 967 fx1,xmass,IORD) … … 976 976 INTEGER :: jvan,j1vl,j2vl,j,i,iu,itmp,ist,imp 977 977 REAL :: rut 978 ! 978 979 979 IMP = IMR + 1 980 ! 980 981 981 ! van Leer at high latitudes 982 982 jvan = max(1,JNP/18) 983 983 j1vl = j1+jvan 984 984 j2vl = j2-jvan 985 ! 985 986 986 DO j=j1,j2 987 ! 987 988 988 DO i=1,IMR 989 989 qtmp(i) = q(i,j) 990 990 enddo 991 ! 991 992 992 IF(j>=JN .OR. j<=JS) goto 2222 993 993 ! ************* Eulerian ********** 994 ! 994 995 995 qtmp(0) = q(IMR,J) 996 996 qtmp(-1) = q(IMR-1,J) 997 997 qtmp(IMP) = q(1,J) 998 998 qtmp(IMP+1) = q(2,J) 999 ! 999 1000 1000 IF(IORD==1 .OR. j==j1 .OR. j==j2) THEN 1001 1001 DO i=1,IMR … … 1006 1006 CALL xmist(IMR,IML,Qtmp,DC) 1007 1007 DC(0) = DC(IMR) 1008 ! 1008 1009 1009 IF(IORD==2 .OR. j<=j1vl .OR. j>=j2vl) THEN 1010 1010 DO i=1,IMR … … 1015 1015 CALL fxppm(IMR,IML,UC(1,j),Qtmp,DC,fx1,IORD) 1016 1016 ENDIF 1017 ! 1018 ENDIF 1019 ! 1017 1018 ENDIF 1019 1020 1020 DO i=1,IMR 1021 1021 fx1(i) = fx1(i)*xmass(i,j) 1022 1022 END DO 1023 ! 1023 1024 1024 goto 1309 1025 ! 1025 1026 1026 ! ***** Conservative (flux-form) Semi-Lagrangian transport ***** 1027 ! 1027 1028 1028 2222 continue 1029 ! 1029 1030 1030 DO i=-IML,0 1031 1031 qtmp(i) = q(IMR+i,j) 1032 1032 qtmp(IMP-i) = q(1-i,j) 1033 1033 enddo 1034 ! 1034 1035 1035 IF(IORD==1 .OR. j==j1 .OR. j==j2) THEN 1036 1036 DO i=1,IMR … … 1042 1042 ELSE 1043 1043 CALL xmist(IMR,IML,Qtmp,DC) 1044 ! 1044 1045 1045 DO i=-IML,0 1046 1046 DC(i) = DC(IMR+i) 1047 1047 DC(IMP-i) = DC(1-i) 1048 1048 enddo 1049 ! 1049 1050 1050 DO i=1,IMR 1051 1051 itmp = INT(uc(i,j)) … … 1056 1056 END DO 1057 1057 ENDIF 1058 ! 1058 1059 1059 DO i=1,IMR 1060 1060 IF(uc(i,j)>1.) THEN … … 1073 1073 fx1(i) = PU(i,j)*fx1(i) 1074 1074 enddo 1075 ! 1075 1076 1076 ! *************************************** 1077 ! 1077 1078 1078 1309 fx1(IMP) = fx1(1) 1079 1079 DO i=1,IMR 1080 1080 DQ(i,j) = DQ(i,j) + fx1(i)-fx1(i+1) 1081 1081 END DO 1082 ! 1082 1083 1083 ! *************************************** 1084 ! 1084 1085 1085 END DO 1086 1086 RETURN 1087 1087 END SUBROUTINE xtp 1088 ! 1088 1089 1089 SUBROUTINE fxppm(IMR,IML,UT,P,DC,flux,IORD) 1090 1090 IMPLICIT NONE … … 1099 1099 ! SAVE LMT 1100 1100 ! IF(first) THEN 1101 ! 1101 1102 1102 ! correction calcul de LMT a chaque passage pour pouvoir choisir 1103 1103 ! plusieurs schemas PPM pour differents traceurs … … 1113 1113 ! LMT = IORD - 3 1114 1114 ! ENDIF 1115 ! 1115 1116 1116 LMT = IORD - 3 1117 1117 ! WRITE(6,*) 'PPM option in E-W direction = ', LMT 1118 1118 ! first = .FALSE. 1119 1119 ! END IF 1120 ! 1120 1121 1121 DO i=1,IMR 1122 1122 AL(i) = 0.5*(p(i-1)+p(i)) + (DC(i-1) - DC(i))*R3 1123 1123 END DO 1124 ! 1124 1125 1125 DO i=1,IMR-1 1126 1126 AR(i) = AL(i+1) 1127 1127 END DO 1128 1128 AR(IMR) = AL(1) 1129 ! 1129 1130 1130 DO i=1,IMR 1131 1131 A6(i) = 3.*(p(i)+p(i) - (AL(i)+AR(i))) 1132 1132 END DO 1133 ! 1133 1134 1134 IF(LMT<=2) CALL lmtppm(DC(1),A6(1),AR(1),AL(1),P(1),IMR,LMT) 1135 ! 1135 1136 1136 AL(0) = AL(IMR) 1137 1137 AR(0) = AR(IMR) 1138 1138 A6(0) = A6(IMR) 1139 ! 1139 1140 1140 DO i=1,IMR 1141 1141 IF(UT(i)>0.) THEN … … 1149 1149 RETURN 1150 1150 END SUBROUTINE fxppm 1151 ! 1151 1152 1152 SUBROUTINE xmist(IMR,IML,P,DC) 1153 1153 IMPLICIT NONE … … 1157 1157 INTEGER :: i 1158 1158 REAL :: tmp,pmax,pmin 1159 ! 1159 1160 1160 DO i=1,IMR 1161 1161 tmp = R24*(8.*(p(i+1) - p(i-1)) + p(i-2) - p(i+2)) … … 1166 1166 RETURN 1167 1167 END SUBROUTINE xmist 1168 ! 1168 1169 1169 SUBROUTINE ytp(IMR,JNP,j1,j2,acosp,RCAP,DQ,P,VC,DC2 & 1170 1170 ,ymass,fx,A6,AR,AL,JORD) … … 1178 1178 INTEGER :: JMR,len,i,jt,j 1179 1179 REAL :: sum1,sum2 1180 ! 1180 1181 1181 JMR = JNP - 1 1182 1182 len = IMR*(J2-J1+2) 1183 ! 1183 1184 1184 IF(JORD==1) THEN 1185 1185 DO i=1,len … … 1190 1190 1191 1191 CALL ymist(IMR,JNP,j1,P,DC2,4) 1192 ! 1192 1193 1193 IF(JORD<=0 .OR. JORD>=3) THEN 1194 1194 CALL fyppm(VC,P,DC2,fx,IMR,JNP,j1,j2,A6,AR,AL,JORD) … … 1201 1201 ENDIF 1202 1202 ENDIF 1203 ! 1203 1204 1204 DO i=1,len 1205 1205 fx(i,j1) = fx(i,j1)*ymass(i,j1) 1206 1206 END DO 1207 ! 1207 1208 1208 DO j=j1,j2 1209 1209 DO i=1,IMR … … 1211 1211 END DO 1212 1212 END DO 1213 ! 1213 1214 1214 ! Poles 1215 1215 sum1 = fx(IMR,j1 ) … … 1219 1219 sum2 = sum2 + fx(i,J2+1) 1220 1220 enddo 1221 ! 1221 1222 1222 sum1 = DQ(1, 1) - sum1 * RCAP 1223 1223 sum2 = DQ(1,JNP) + sum2 * RCAP … … 1226 1226 DQ(i,JNP) = sum2 1227 1227 enddo 1228 ! 1228 1229 1229 IF(j1/=2) THEN 1230 1230 DO i=1,IMR … … 1233 1233 enddo 1234 1234 ENDIF 1235 ! 1235 1236 1236 RETURN 1237 1237 END SUBROUTINE ytp 1238 ! 1238 1239 1239 subroutine ymist(IMR,JNP,j1,P,DC,ID) 1240 1240 IMPLICIT NONE … … 1244 1244 INTEGER :: iimh,jmr,ijm3,imh,i 1245 1245 REAL :: pmax,pmin,tmp 1246 ! 1246 1247 1247 IMH = IMR / 2 1248 1248 JMR = JNP - 1 1249 1249 IJM3 = IMR*(JMR-3) 1250 ! 1250 1251 1251 IF(ID==2) THEN 1252 1252 DO i=1,IMR*(JMR-1) … … 1281 1281 DC(i,JMR) = sign(min(abs(tmp),Pmin,Pmax),tmp) 1282 1282 END DO 1283 ! 1283 1284 1284 DO i=1,IJM3 1285 1285 tmp = (8.*(p(i,4) - p(i,2)) + p(i,1) - p(i,5))*R24 … … 1289 1289 END DO 1290 1290 ENDIF 1291 ! 1291 1292 1292 IF(j1/=2) THEN 1293 1293 DO i=1,IMR … … 1297 1297 else 1298 1298 ! Determine slopes in polar caps for scalars! 1299 ! 1299 1300 1300 DO i=1,IMH 1301 1301 ! South … … 1310 1310 DC(i,JNP) = sign(min(abs(tmp),Pmax,pmin),tmp) 1311 1311 END DO 1312 ! 1312 1313 1313 DO i=imh+1,IMR 1314 1314 DC(i, 1) = - DC(i-imh, 1) … … 1318 1318 RETURN 1319 1319 END SUBROUTINE ymist 1320 ! 1320 1321 1321 SUBROUTINE fyppm(VC,P,DC,flux,IMR,JNP,j1,j2,A6,AR,AL,JORD) 1322 1322 IMPLICIT NONE … … 1331 1331 ! data first /.TRUE./ 1332 1332 ! SAVE LMT 1333 ! 1333 1334 1334 IMH = IMR / 2 1335 1335 JMR = JNP - 1 … … 1349 1349 ! LMT = JORD - 3 1350 1350 ! END IF 1351 ! 1351 1352 1352 ! first = .FALSE. 1353 1353 ! ENDIF 1354 ! 1354 1355 1355 ! modifs pour pouvoir choisir plusieurs schemas PPM 1356 1356 LMT = JORD - 3 1357 ! 1357 1358 1358 DO i=1,IMR*JMR 1359 1359 AL(i,2) = 0.5*(p(i,1)+p(i,2)) + (DC(i,1) - DC(i,2))*R3 1360 1360 AR(i,1) = AL(i,2) 1361 1361 END DO 1362 ! 1362 1363 1363 !Poles: 1364 ! 1364 1365 1365 DO i=1,IMH 1366 1366 AL(i,1) = AL(i+IMH,2) 1367 1367 AL(i+IMH,1) = AL(i,2) 1368 ! 1368 1369 1369 AR(i,JNP) = AR(i+IMH,JMR) 1370 1370 AR(i+IMH,JNP) = AR(i,JMR) … … 1382 1382 A6(i,j11) = 3.*(p(i,j11)+p(i,j11) - (AL(i,j11)+AR(i,j11))) 1383 1383 END DO 1384 ! 1384 1385 1385 IF(LMT<=2) CALL lmtppm(DC(1,j11),A6(1,j11),AR(1,j11) & 1386 1386 ,AL(1,j11),P(1,j11),len,LMT) … … 1398 1398 RETURN 1399 1399 END SUBROUTINE fyppm 1400 ! 1400 1401 1401 SUBROUTINE yadv(IMR,JNP,j1,j2,p,VA,ady,wk,IAD) 1402 1402 IMPLICIT NONE … … 1406 1406 INTEGER :: JMR,IMH,i,j,jp 1407 1407 REAL :: rv,a1,b1,sum1,sum2 1408 ! 1408 1409 1409 JMR = JNP-1 1410 1410 IMH = IMR/2 … … 1443 1443 enddo 1444 1444 ! WRITE(*,*) 'toto 2' 1445 ! 1445 1446 1446 ELSEIF(IAD==1) THEN 1447 1447 DO j=j1-1,j2+1 … … 1452 1452 enddo 1453 1453 ENDIF 1454 ! 1454 1455 1455 IF(j1/=2) THEN 1456 1456 sum1 = 0. … … 1462 1462 sum1 = sum1 / IMR 1463 1463 sum2 = sum2 / IMR 1464 ! 1464 1465 1465 DO i=1,imr 1466 1466 ady(i, 2) = sum1 … … 1479 1479 sum1 = sum1 / IMR 1480 1480 sum2 = sum2 / IMR 1481 ! 1481 1482 1482 DO i=1,imr 1483 1483 ady(i, 1) = sum1 … … 1485 1485 enddo 1486 1486 endif 1487 ! 1487 1488 1488 RETURN 1489 1489 END SUBROUTINE yadv 1490 ! 1490 1491 1491 SUBROUTINE xadv(IMR,JNP,j1,j2,p,UA,JS,JN,IML,adx,IAD) 1492 1492 IMPLICIT NONE … … 1495 1495 INTEGER :: JMR,j,i,ip,iu,iiu 1496 1496 REAL :: ru,a1,b1 1497 ! 1497 1498 1498 JMR = JNP-1 1499 1499 DO j=j1,j2 1500 1500 IF(J>JS .AND. J<JN) GO TO 1309 1501 ! 1501 1502 1502 DO i=1,IMR 1503 1503 qtmp(i) = p(i,j) 1504 1504 enddo 1505 ! 1505 1506 1506 DO i=-IML,0 1507 1507 qtmp(i) = p(IMR+i,j) 1508 1508 qtmp(IMR+1-i) = p(1-i,j) 1509 1509 enddo 1510 ! 1510 1511 1511 IF(IAD==2) THEN 1512 1512 DO i=1,IMR … … 1530 1530 enddo 1531 1531 ENDIF 1532 ! 1532 1533 1533 DO i=1,IMR 1534 1534 adx(i,j) = adx(i,j) - p(i,j) … … 1536 1536 1309 continue 1537 1537 END DO 1538 ! 1538 1539 1539 ! Eulerian upwind 1540 ! 1540 1541 1541 DO j=JS+1,JN-1 1542 ! 1542 1543 1543 DO i=1,IMR 1544 1544 qtmp(i) = p(i,j) 1545 1545 enddo 1546 ! 1546 1547 1547 qtmp(0) = p(IMR,J) 1548 1548 qtmp(IMR+1) = p(1,J) 1549 ! 1549 1550 1550 IF(IAD==2) THEN 1551 1551 qtmp(-1) = p(IMR-1,J) … … 1567 1567 ENDIF 1568 1568 enddo 1569 ! 1569 1570 1570 IF(j1/=2) THEN 1571 1571 DO i=1,IMR … … 1581 1581 RETURN 1582 1582 END SUBROUTINE xadv 1583 ! 1583 1584 1584 SUBROUTINE lmtppm(DC,A6,AR,AL,P,IM,LMT) 1585 1585 IMPLICIT NONE 1586 ! 1586 1587 1587 ! A6 = CURVATURE OF THE TEST PARABOLA 1588 1588 ! AR = RIGHT EDGE VALUE OF THE TEST PARABOLA … … 1591 1591 ! P = CELL-AVERAGED VALUE 1592 1592 ! IM = VECTOR LENGTH 1593 ! 1593 1594 1594 ! OPTIONS: 1595 ! 1595 1596 1596 ! LMT = 0: FULL MONOTONICITY 1597 1597 ! LMT = 1: SEMI-MONOTONIC CONSTRAINT (NO UNDERSHOOTS) 1598 1598 ! LMT = 2: POSITIVE-DEFINITE CONSTRAINT 1599 ! 1599 1600 1600 REAL,parameter :: R12 = 1./12. 1601 1601 REAL :: A6(IM),AR(IM),AL(IM),P(IM),DC(IM) … … 1603 1603 INTEGER :: i 1604 1604 REAL :: da1,da2,a6da,fmin 1605 ! 1605 1606 1606 IF(LMT==0) THEN 1607 1607 ! Full constraint … … 1662 1662 RETURN 1663 1663 END SUBROUTINE lmtppm 1664 ! 1664 1665 1665 SUBROUTINE A2C(U,V,IMR,JMR,j1,j2,CRX,CRY,dtdx5,DTDY5) 1666 1666 IMPLICIT NONE … … 1668 1668 REAL :: U(IMR,*),V(IMR,*),CRX(IMR,*),CRY(IMR,*),DTDX5(*),DTDY5 1669 1669 INTEGER :: i,j 1670 ! 1670 1671 1671 DO j=j1,j2 1672 1672 DO i=2,IMR … … 1674 1674 END DO 1675 1675 END DO 1676 ! 1676 1677 1677 DO j=j1,j2 1678 1678 CRX(1,J) = dtdx5(j)*(U(1,j)+U(IMR,j)) 1679 1679 END DO 1680 ! 1680 1681 1681 DO i=1,IMR*JMR 1682 1682 CRY(i,2) = DTDY5*(V(i,2)+V(i,1)) … … 1684 1684 RETURN 1685 1685 END SUBROUTINE a2c 1686 ! 1686 1687 1687 SUBROUTINE cosa(cosp,cose,JNP,PI,DP) 1688 1688 IMPLICIT NONE … … 1696 1696 cose(j) = cos(ph5) 1697 1697 END DO 1698 ! 1698 1699 1699 JEQ = (JNP+1) / 2 1700 1700 IF(JMR == 2*(JMR/2) ) THEN … … 1709 1709 enddo 1710 1710 ENDIF 1711 ! 1711 1712 1712 DO j=2,JMR 1713 1713 cosp(j) = 0.5*(cose(j)+cose(j+1)) … … 1717 1717 RETURN 1718 1718 END SUBROUTINE cosa 1719 ! 1719 1720 1720 SUBROUTINE cosc(cosp,cose,JNP,PI,DP) 1721 1721 IMPLICIT NONE … … 1724 1724 REAL :: phi 1725 1725 INTEGER :: j 1726 ! 1726 1727 1727 phi = -0.5*PI 1728 1728 DO j=2,JNP-1 … … 1732 1732 cosp( 1) = 0. 1733 1733 cosp(JNP) = 0. 1734 ! 1734 1735 1735 DO j=2,JNP 1736 1736 cose(j) = 0.5*(cosp(j)+cosp(j-1)) 1737 1737 END DO 1738 ! 1738 1739 1739 DO j=2,JNP-1 1740 1740 cosp(j) = 0.5*(cose(j)+cose(j+1)) … … 1742 1742 RETURN 1743 1743 END SUBROUTINE cosc 1744 ! 1744 1745 1745 SUBROUTINE qckxyz(Q,qtmp,IMR,JNP,NLAY,j1,j2,cosp,acosp, & 1746 1746 cross,IC,NSTEP) 1747 ! 1747 1748 1748 REAL,parameter :: tiny = 1.E-60 1749 1749 INTEGER :: IMR,JNP,NLAY,j1,j2,IC,NSTEP … … 1752 1752 INTEGER :: NLAYM1,len,ip,L,icr,ipy,ipx,i 1753 1753 REAL :: qup,qly,dup,sum 1754 ! 1754 1755 1755 NLAYM1 = NLAY-1 1756 1756 len = IMR*(j2-j1+1) 1757 1757 ip = 0 1758 ! 1758 1759 1759 ! Top layer 1760 1760 L = 1 … … 1764 1764 CALL filew(q(1,1,L),qtmp,IMR,JNP,j1,j2,ipx,tiny) 1765 1765 IF(ipx==0) goto 50 1766 ! 1766 1767 1767 IF(cross) THEN 1768 1768 CALL filcr(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,icr,tiny) 1769 1769 ENDIF 1770 1770 IF(icr==0) goto 50 1771 ! 1771 1772 1772 ! Vertical filling... 1773 1773 DO i=1,len … … 1778 1778 ENDIF 1779 1779 enddo 1780 ! 1780 1781 1781 50 continue 1782 1782 DO L = 2,NLAYM1 1783 1783 icr = 1 1784 ! 1784 1785 1785 CALL filns(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,ipy,tiny) 1786 1786 IF(ipy==0) goto 225 … … 1791 1791 ENDIF 1792 1792 IF(icr==0) goto 225 1793 ! 1793 1794 1794 DO i=1,len 1795 1795 IF( Q(I,j1,L)<0.) THEN 1796 ! 1796 1797 1797 ip = ip + 1 1798 1798 ! From above … … 1809 1809 225 CONTINUE 1810 1810 END DO 1811 ! 1811 1812 1812 ! BOTTOM LAYER 1813 1813 sum = 0. 1814 1814 L = NLAY 1815 ! 1815 1816 1816 CALL filns(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,ipy,tiny) 1817 1817 IF(ipy==0) goto 911 1818 1818 CALL filew(q(1,1,L),qtmp,IMR,JNP,j1,j2,ipx,tiny) 1819 1819 IF(ipx==0) goto 911 1820 ! 1820 1821 1821 CALL filcr(q(1,1,L),IMR,JNP,j1,j2,cosp,acosp,icr,tiny) 1822 1822 IF(icr==0) goto 911 1823 ! 1823 1824 1824 DO I=1,len 1825 1825 IF( Q(I,j1,L)<0.) THEN 1826 1826 ip = ip + 1 1827 ! 1827 1828 1828 ! From above 1829 ! 1829 1830 1830 qup = Q(I,j1,NLAYM1) 1831 1831 qly = -Q(I,j1,L) … … 1837 1837 ENDIF 1838 1838 ENDDO 1839 ! 1839 1840 1840 911 continue 1841 ! 1841 1842 1842 IF(ip>IMR) THEN 1843 1843 WRITE(6,*) 'IC=',IC,' STEP=',NSTEP, & 1844 1844 ' Vertical filling pts=',ip 1845 1845 ENDIF 1846 ! 1846 1847 1847 IF(sum>1.e-25) THEN 1848 1848 WRITE(6,*) IC,NSTEP,' Mass source from the ground=',sum … … 1850 1850 RETURN 1851 1851 END SUBROUTINE qckxyz 1852 ! 1852 1853 1853 SUBROUTINE filcr(q,IMR,JNP,j1,j2,cosp,acosp,icr,tiny) 1854 1854 IMPLICIT NONE … … 1937 1937 65 continue 1938 1938 END DO 1939 ! 1939 1940 1940 DO i=1,IMR 1941 1941 IF(q(i,j1)<0. .OR. q(i,j2)<0.) THEN … … 1944 1944 ENDIF 1945 1945 enddo 1946 ! 1946 1947 1947 80 continue 1948 ! 1948 1949 1949 IF(q(1,1)<0. .OR. q(1,jnp)<0.) THEN 1950 1950 icr = 1 1951 1951 ENDIF 1952 ! 1952 1953 1953 RETURN 1954 1954 END SUBROUTINE filcr 1955 ! 1955 1956 1956 SUBROUTINE filns(q,IMR,JNP,j1,j2,cosp,acosp,ipy,tiny) 1957 1957 IMPLICIT NONE … … 1963 1963 ! data first /.TRUE./ 1964 1964 ! save cap1 1965 ! 1965 1966 1966 ! IF(first) THEN 1967 1967 DP = 4.*ATAN(1.)/REAL(JNP-1) … … 1969 1969 ! first = .FALSE. 1970 1970 ! END IF 1971 ! 1971 1972 1972 ipy = 0 1973 1973 DO j=j1+1,j2-1 … … 1991 1991 END DO 1992 1992 END DO 1993 ! 1993 1994 1994 DO i=1,imr 1995 1995 IF(q(i,j1)<0.) THEN … … 2004 2004 ENDIF 2005 2005 enddo 2006 ! 2006 2007 2007 j = j2 2008 2008 DO i=1,imr … … 2018 2018 ENDIF 2019 2019 enddo 2020 ! 2020 2021 2021 ! Check Poles. 2022 2022 IF(q(1,1)<0.) THEN … … 2028 2028 enddo 2029 2029 ENDIF 2030 ! 2030 2031 2031 IF(q(1,JNP)<0.) THEN 2032 2032 dq = q(1,JNP)*cap1/REAL(IMR)*acosp(j2) … … 2037 2037 enddo 2038 2038 ENDIF 2039 ! 2039 2040 2040 RETURN 2041 2041 END SUBROUTINE filns 2042 ! 2042 2043 2043 SUBROUTINE filew(q,qtmp,IMR,JNP,j1,j2,ipx,tiny) 2044 2044 IMPLICIT NONE … … 2047 2047 INTEGER :: i,j 2048 2048 REAL :: d0,d1,d2 2049 ! 2049 2050 2050 ipx = 0 2051 2051 ! Copy & swap direction for vectorization. … … 2055 2055 END DO 2056 2056 END DO 2057 ! 2057 2058 2058 DO i=2,imr-1 2059 2059 DO j=j1,j2 … … 2073 2073 END DO 2074 2074 END DO 2075 ! 2075 2076 2076 i=1 2077 2077 DO j=j1,j2 … … 2087 2087 d2 = min(-qtmp(j,i),d0) 2088 2088 qtmp(j,i+1) = qtmp(j,i+1) - d2 2089 ! 2089 2090 2090 qtmp(j,i) = qtmp(j,i) + d2 + tiny 2091 2091 ENDIF … … 2104 2104 d2 = min(-qtmp(j,i),d0) 2105 2105 qtmp(j,1) = qtmp(j,1) - d2 2106 ! 2106 2107 2107 qtmp(j,i) = qtmp(j,i) + d2 + tiny 2108 2108 ENDIF 2109 2109 END DO 2110 ! 2110 2111 2111 IF(ipx/=0) THEN 2112 2112 DO j=j1,j2 … … 2116 2116 END DO 2117 2117 else 2118 ! 2118 2119 2119 ! Poles. 2120 2120 IF(q(1,1)<0 .OR. q(1,JNP)<0.) ipx = 1 … … 2122 2122 RETURN 2123 2123 END SUBROUTINE filew 2124 ! 2124 2125 2125 SUBROUTINE zflip(q,im,km,nc) 2126 2126 IMPLICIT NONE … … 2131 2131 REAL :: qtmp(im,km) 2132 2132 INTEGER :: IC,k,i 2133 ! 2133 2134 2134 DO IC = 1, nc 2135 ! 2135 2136 2136 DO k=1,km 2137 2137 DO i=1,im … … 2139 2139 END DO 2140 2140 END DO 2141 ! 2141 2142 2142 DO i=1,im*km 2143 2143 q(i,1,IC) = qtmp(i,1)
Note: See TracChangeset
for help on using the changeset viewer.