WAVEWATCH III  beta 0.0.1
w3psmcmd Module Reference

Spherical Multiple-Cell (SMC) grid routines. More...

Functions/Subroutines

subroutine w3psmc (ISP, DTG, VQ)
 Propagation in phyiscal space for a given spectral component. More...
 
subroutine w3krtn (ISEA, FACTH, FACK, CTHG0, CG, WN, DEPTH, DDDX, DDDY, ALFLMT, CX, CY, DCXDX, DCXDY, DCYDX, DCYDY, DCDX, DCDY, VA)
 Refraction and great-circle turning by spectral rotation. More...
 
subroutine smcxuno2 (NUA, NUB, CF, UC, UFLX, AKDif, FU, FX, FTS)
 Calculate mid-flux values for x dimension. More...
 
subroutine smcyuno2 (NVA, NVB, CF, VC, VFLY, AKDif, FV, FY, FTS)
 Calculate mid-flux values for y dimension. More...
 
subroutine smcxuno2r (NUA, NUB, CF, UC, UFLX, AKDif, FU, FX)
 Calculate mid-flux values for x dimension. More...
 
subroutine smcyuno2r (NVA, NVB, CF, VC, VFLY, AKDif, FV, FY)
 Calculate mid-flux values for y dimension. More...
 
subroutine smcxuno3 (NUA, NUB, CF, UC, UFLX, AKDif, FU, FX, FTS)
 Calculate mid-flux values for x dimension with UNO3 scheme. More...
 
subroutine smcyuno3 (NVA, NVB, CF, VC, VFLY, AKDif, FV, FY, FTS)
 Calculate mid-flux values for y dimension with UNO3 scheme. More...
 
subroutine smcxuno3r (NUA, NUB, CF, UC, UFLX, AKDif, FU, FX)
 Calculate mid-flux values for x dimension with UNO3. More...
 
subroutine smcyuno3r (NVA, NVB, CF, VC, VFLY, AKDif, FV, FY)
 Calculate mid-flux values for y dimension with UNO3. More...
 
subroutine smcgradn (CVQ, GrdX, GrdY, L0r1)
 Evaluate local gradient for sea points. More...
 
subroutine smcaverg (CVQ)
 Average sea point values with a 1-2-1 scheme. More...
 
subroutine smcgtcrfr (CoRfr, SpeTHK)
 Calculate great circle turning (GCT) and refraction. More...
 
subroutine smckuno2 (CoRfr, SpeTHK, DKC, DKS)
 Calculates refraction induced shift in k-space. More...
 
subroutine smcdhxy
 Calculates water-depth gradient for refraction. More...
 
subroutine smcdcxy
 Calculates current velocity gradient for refraction. More...
 
subroutine w3gathsmc (ISPEC, FIELD)
 SMC version of W3GATH. More...
 
subroutine w3scatsmc (ISPEC, MAPSTA, FIELD)
 SMC version of W3GATH. More...
 
subroutine w3smcell (IMOD, NC, IDCl, XLon, YLat)
 Calculate cell centre lat-lon for given ids. More...
 
subroutine w3smcgmp (IMOD, NC, XLon, YLat, IDCl)
 Map lat-lon points to SMC grid cells. More...
 

Detailed Description

Spherical Multiple-Cell (SMC) grid routines.

Bundles routines for SMC advection (UNO2) and diffusion schemes in single module, including great circile turning and refraction rotation schemes.

Author
Jian-Guo Li
Date
23 Mar 2020

Function/Subroutine Documentation

◆ smcaverg()

subroutine w3psmcmd::smcaverg ( real, dimension(-9:nsea), intent(inout)  CVQ)

Average sea point values with a 1-2-1 scheme.

Parameters
[in,out]CVQInput field.
Author
Jian-Guo Li
Date
15-Jan-2019

Definition at line 2543 of file w3psmcmd.F90.

2543 
2544  USE constants
2545  USE w3gdatmd, ONLY: nsea, nufc, nvfc, &
2546  ijkcel, ijkufc, ijkvfc, &
2547  ijkufc5, ijkufc6
2548  USE w3gdatmd, ONLY: arctc
2549  USE w3odatmd, ONLY: ndse, ndst
2550 
2551  IMPLICIT NONE
2552  REAL, INTENT(INOUT) :: CVQ(-9:NSEA)
2553  !
2554  INTEGER :: I, J, K, L, M, N
2555  REAL :: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6
2556 
2557  ! Use a few working arrays
2558  REAL, Dimension(-9:NSEA) :: CVF, AUN, AVN
2559 
2560  ! Two layer of boundary cells are added to each boundary cell face
2561  ! with all boundary cell values stored in CVF(-9:0).
2562  cvf=cvq
2563 
2564  !! Initialize arrays
2565  aun = 0.
2566  avn = 0.
2567 
2568  !!Li Save polar cell value if any.
2569  cnst0 = cvq(nsea)
2570 
2571 #ifdef W3_OMPG
2572  !$OMP Parallel Default(Shared), Private(i, j, L, M, n), &
2573  !$OMP& Private(CNST3,CNST4,CNST5,CNST6)
2574  !$OMP DO
2575 #endif
2576 
2577  !! Calculate x-gradient by averaging U-face gradients.
2578  DO i=1, nufc
2579 
2580  ! Select Upstream, Central and Downstream cells
2581  l=ijkufc5(i)
2582  m=ijkufc6(i)
2583 
2584  ! Multi-resolution SMC grid requires flux multiplied by face factor.
2585  cnst5=real( ijkufc(3,i) )*(cvf(m)+cvf(l))
2586 #ifdef W3_B4B
2587  !OMPG CNST5=int(CNST5 * 1.0e6)
2588 #endif
2589 
2590  !! Replace CRITICAL with ATOMIC. JGLi15Jan2019
2591  !! !$OMP CRITICAL
2592  ! Store side gradient in two neighbouring cells
2593  !! Remove boundary cell flux update or L M > 0. JGLi28Mar2019
2594  IF( l > 0 ) THEN
2595 #ifdef W3_OMPG
2596  !$OMP ATOMIC
2597 #endif
2598  aun(l) = aun(l) + cnst5
2599  ENDIF
2600  IF( m > 0 ) THEN
2601 #ifdef W3_OMPG
2602  !$OMP ATOMIC
2603 #endif
2604  aun(m) = aun(m) + cnst5
2605  ENDIF
2606  !! !$OMP END CRITICAL
2607 
2608  END DO
2609 
2610 #ifdef W3_OMPG
2611  !$OMP END DO
2612 #endif
2613 
2614 #if defined W3_B4B && defined W3_OMPG
2615  !$OMP SINGLE
2616  aun = aun / 1.0e6 !CB B4B
2617  !$OMP END SINGLE
2618 #endif
2619 
2620 #ifdef W3_OMPG
2621  !$OMP DO
2622 #endif
2623 
2624  !! Calculate y-gradient by averaging V-face gradients.
2625  DO j=1, nvfc
2626 
2627  ! Select Central and Downstream cells
2628  l=ijkvfc(5,j)
2629  m=ijkvfc(6,j)
2630 
2631  ! Face size is required for multi-resolution grid.
2632  cnst6=real( ijkvfc(3,j) )*(cvf(m)+cvf(l))
2633 #if defined W3_B4B && defined W3_OMPG
2634  cnst6=int(cnst6 * 1e6)
2635 #endif
2636 
2637  !! Replace CRITICAL with ATOMIC. JGLi15Jan2019
2638  !! !$OMP CRITICAL
2639  ! Store side gradient in two neighbouring cells
2640  !! Remove boundary cell flux update or L M > 0. JGLi28Mar2019
2641  IF( l > 0 ) THEN
2642 #ifdef W3_OMPG
2643  !$OMP ATOMIC
2644 #endif
2645  avn(l) = avn(l) + cnst6
2646  ENDIF
2647  IF( m > 0 ) THEN
2648 #ifdef W3_OMPG
2649  !$OMP ATOMIC
2650 #endif
2651  avn(m) = avn(m) + cnst6
2652  ENDIF
2653  !! !$OMP END CRITICAL
2654 
2655  END DO
2656 
2657 #ifdef W3_OMPG
2658  !$OMP END DO
2659 #endif
2660 
2661 #if defined W3_B4B && defined W3_OMPG
2662  !$OMP SINGLE
2663  avn = avn / 1.0e6 !CB B4B
2664  !$OMP END SINGLE
2665 #endif
2666 
2667 #ifdef W3_OMPG
2668  !$OMP DO
2669 #endif
2670 
2671  ! Assign averaged value back to CVQ.
2672  DO n=1, nsea
2673 
2674  cnst3=0.125/real( ijkcel(3,n) )
2675  cnst4=0.125/real( ijkcel(4,n) )
2676  ! AUN is divided by the cell y-size IJKCel(4,n) and AVN by
2677  ! the cell x-size IJKCel(3,n) to cancel face size factors.
2678  cvq(n)= aun(n)*cnst4 + avn(n)*cnst3
2679 
2680  END DO
2681 
2682 #ifdef W3_OMPG
2683  !$OMP END DO
2684  !$OMP END Parallel
2685 #endif
2686 
2687  !!Li Polar cell (if any) keep original value.
2688  IF( arctc ) cvq(nsea) = cnst0
2689 
2690  ! 999 PRINT*, ' Sub SMCAverg ended.'
2691 
2692  RETURN

References w3gdatmd::arctc, w3gdatmd::ijkcel, w3gdatmd::ijkufc, w3gdatmd::ijkufc5, w3gdatmd::ijkufc6, w3gdatmd::ijkvfc, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nsea, w3gdatmd::nufc, and w3gdatmd::nvfc.

Referenced by w3psmc().

◆ smcdcxy()

subroutine w3psmcmd::smcdcxy

Calculates current velocity gradient for refraction.

For consistency with the lat-lon grid, full grid DCXDXY, DCYDXY are assigned here. They are rotated to map-east system in the Arctic part.

Author
Jian-Guo Li
Date
23 Mar 2016

Definition at line 3042 of file w3psmcmd.F90.

3042  USE constants
3043  USE w3gdatmd, ONLY: nx, ny, nsea, mapsta, mapfs, mrfct, ijkcel
3044  USE w3gdatmd, ONLY: nglo, angarc, arctc
3045  USE w3adatmd, ONLY: cx, cy, dcxdx, dcxdy, dcydx, dcydy
3046  USE w3odatmd, ONLY: ndse, ndst
3047 
3048  IMPLICIT NONE
3049 
3050  INTEGER :: I, J, K, L, M, N
3051  REAL :: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6
3052  REAL, Dimension(NSEA) :: CXCY, GrHx, GrHy
3053  ! REAL, Dimension(-9:NSEA) :: CXCY
3054 
3055  !! Assign current CX speed to CXCY and set negative cells.
3056  ! CXCY(-9:0) = 0.0
3057  !! Use zero-gradient boundary condition or L0r1 > 0
3058  l = 1
3059  cxcy(1:nsea)= cx(1:nsea)
3060 
3061  !! Initialize full grid gradient arrays
3062  dcxdx = 0.0
3063  dcxdy = 0.0
3064 
3065  !! Calculate sea point water depth gradient
3066  CALL smcgradn(cxcy, grhx, grhy, l)
3067 
3068  !! Apply limiter to CX-gradient and copy to full grid.
3069 #ifdef W3_OMPG
3070  !$OMP Parallel DO Private(i, j, k, m, n, CNST0, CNST1, CNST2)
3071 #endif
3072  DO n=1,nsea
3073 
3074  ! A limiter of gradient <= 0.01 is applied.
3075  IF( abs( grhx(n) ) .GT. 0.01) grhx(n)=sign( 0.01, grhx(n) )
3076  IF( abs( grhy(n) ) .GT. 0.01) grhy(n)=sign( 0.01, grhy(n) )
3077 
3078  !Li Current gradient in the Arctic part has to be rotated into
3079  !Li the map-east system for calculation of refraction.
3080  IF( arctc .AND. n .GT. nglo ) THEN
3081  cnst0 = angarc(n - nglo)*dera
3082  cnst1 = grhx(n)*cos(cnst0) - grhy(n)*sin(cnst0)
3083  cnst2 = grhx(n)*sin(cnst0) + grhy(n)*cos(cnst0)
3084  grhx(n) = cnst1
3085  grhy(n) = cnst2
3086  ENDIF
3087 
3088  !! Asign CX gradients to full grid variable DCXDX/Y
3089  i= ijkcel(1,n)/mrfct + 1
3090  j= ijkcel(2,n)/mrfct + 1
3091  k= max(1, ijkcel(3,n)/mrfct)
3092  m= max(1, ijkcel(4,n)/mrfct)
3093  dcxdx(j:j+m-1,i:i+k-1) = grhx(n)
3094  dcxdy(j:j+m-1,i:i+k-1) = grhy(n)
3095 
3096  END DO
3097 #ifdef W3_OMPG
3098  !$OMP END Parallel DO
3099 #endif
3100 
3101  !! Assign current CY speed to CXCY and set negative cells.
3102  ! CXCY(-9:0) = 0.0
3103  !! Use zero-gradient boundary condition or L0r1 > 0
3104  l = 1
3105  cxcy(1:nsea)= cy(1:nsea)
3106 
3107  !! Initialize full grid gradient arrays
3108  dcydx = 0.0
3109  dcydy = 0.0
3110 
3111  !! Calculate sea point water depth gradient
3112  CALL smcgradn(cxcy, grhx, grhy, l)
3113 
3114  !! Apply limiter to CX-gradient and copy to full grid.
3115 #ifdef W3_OMPG
3116  !$OMP Parallel DO Private(i, j, k, m, n, CNST0, CNST1, CNST2)
3117 #endif
3118  DO n=1,nsea
3119 
3120  !! A limiter of gradient <= 0.1 is applied.
3121  IF( abs( grhx(n) ) .GT. 0.01) grhx(n)=sign( 0.01, grhx(n) )
3122  IF( abs( grhy(n) ) .GT. 0.01) grhy(n)=sign( 0.01, grhy(n) )
3123 
3124  !! Current gradient in the Arctic part has to be rotated into
3125  !! the map-east system for calculation of refraction.
3126  IF( arctc .AND. n .GT. nglo ) THEN
3127  cnst0 = angarc(n - nglo)*dera
3128  cnst1 = grhx(n)*cos(cnst0) - grhy(n)*sin(cnst0)
3129  cnst2 = grhx(n)*sin(cnst0) + grhy(n)*cos(cnst0)
3130  grhx(n) = cnst1
3131  grhy(n) = cnst2
3132  ENDIF
3133 
3134  !! Asign CX gradients to full grid variable DCXDX/Y
3135  i= ijkcel(1,n)/mrfct + 1
3136  j= ijkcel(2,n)/mrfct + 1
3137  k= max(1, ijkcel(3,n)/mrfct)
3138  m= max(1, ijkcel(4,n)/mrfct)
3139  dcydx(j:j+m-1,i:i+k-1) = grhx(n)
3140  dcydy(j:j+m-1,i:i+k-1) = grhy(n)
3141 
3142  END DO
3143 #ifdef W3_OMPG
3144  !$OMP END Parallel DO
3145 #endif
3146 
3147 #ifdef W3_T
3148 999 print*, ' Sub SMCDCXY ended.'
3149 #endif
3150 
3151  RETURN

References w3gdatmd::angarc, w3gdatmd::arctc, w3adatmd::cx, w3adatmd::cy, w3adatmd::dcxdx, w3adatmd::dcxdy, w3adatmd::dcydx, w3adatmd::dcydy, constants::dera, w3gdatmd::ijkcel, w3gdatmd::mapfs, w3gdatmd::mapsta, w3gdatmd::mrfct, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nglo, w3gdatmd::nsea, w3gdatmd::nx, w3gdatmd::ny, and smcgradn().

Referenced by w3wavemd::w3wave().

◆ smcdhxy()

subroutine w3psmcmd::smcdhxy

Calculates water-depth gradient for refraction.

For consistency with the lat-lon grid, full grid DDDX, DDDY are also assigned here. DHDX, DHDY are used for refraction at present. It has to be rotated to map-east system in the Arctic part.

Author
Jian-Guo Li
Date
03-Mar-2022

Definition at line 2897 of file w3psmcmd.F90.

2897  USE constants
2898  USE w3gdatmd, ONLY: nx, ny, nsea, mapsta, mapfs, mrfct, ijkcel, &
2899  clats, nth, dth, esin, ecos, refran, dmin
2900  USE w3gdatmd, ONLY: nglo, angarc, arctc
2901  USE w3adatmd, ONLY: dw, dddx, dddy, dhdx, dhdy, dhlmt
2902  USE w3odatmd, ONLY: ndse, ndst
2903 
2904  IMPLICIT NONE
2905 
2906  INTEGER :: I, J, K, L, M, N
2907  REAL :: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6
2908  REAL, Dimension(NSEA) :: HCel, GrHx, GrHy
2909  ! REAL, Dimension(-9:NSEA) :: HCel
2910 
2911  !! Assign water depth to HCel from DW integer values.
2912  !! set half the minimum depth DMIN for negative cells.
2913  ! HCel(-9:0) = 0.5*DMIN
2914  hcel(1:nsea)= dw(1:nsea)
2915 
2916  !! Reset shallow water depth with minimum depth
2917 #ifdef W3_OMPG
2918  !$OMP Parallel DO Private(k)
2919 #endif
2920  DO k=1, nsea
2921  IF(dw(k) .LT. dmin) hcel(k)=dmin
2922  ENDDO
2923 #ifdef W3_OMPG
2924  !$OMP END Parallel DO
2925 #endif
2926 
2927  !! Initialize full grid gradient arrays
2928  dddx = 0.
2929  dddy = 0.
2930 
2931  !! Use zero-gradient boundary condition or L0r1 > 0
2932  l = 1
2933 
2934  !! Calculate sea point water depth gradient
2935  CALL smcgradn(hcel, grhx, grhy, l)
2936 
2937  !! Pass gradient values to DHDX, DHDY
2938  dhdx(1:nsea) = grhx
2939  dhdy(1:nsea) = grhy
2940 
2941  !! Apply limiter to depth-gradient and copy to full grid.
2942 #ifdef W3_OMPG
2943  !$OMP Parallel DO Private(i,j,k,m,n, CNST0, CNST1, CNST2)
2944 #endif
2945  DO n=1,nsea
2946 
2947  ! A limiter of gradient <= 0.1 is applied.
2948  IF( abs( dhdx(n) ) .GT. 0.1) dhdx(n)=sign( 0.1, dhdx(n) )
2949  IF( abs( dhdy(n) ) .GT. 0.1) dhdy(n)=sign( 0.1, dhdy(n) )
2950 
2951  !! Asign DHDX value to full grid variable DDDX
2952  i= ijkcel(1,n)/mrfct + 1
2953  j= ijkcel(2,n)/mrfct + 1
2954  k= max(1, ijkcel(3,n)/mrfct)
2955  m= max(1, ijkcel(4,n)/mrfct)
2956  dddx(j:j+m-1,i:i+k-1) = dhdx(n)
2957  dddy(j:j+m-1,i:i+k-1) = dhdy(n)
2958 
2959  !Li Depth gradient in the Arctic part has to be rotated into
2960  !Li the map-east system for calculation of refraction.
2961  IF( arctc .AND. n .GT. nglo ) THEN
2962  cnst0 = angarc(n - nglo)*dera
2963  cnst1 = dhdx(n)*cos(cnst0) - dhdy(n)*sin(cnst0)
2964  cnst2 = dhdx(n)*sin(cnst0) + dhdy(n)*cos(cnst0)
2965  dhdx(n) = cnst1
2966  dhdy(n) = cnst2
2967  ENDIF
2968 
2969  END DO
2970 #ifdef W3_OMPG
2971  !$OMP END Parallel DO
2972 #endif
2973 
2974  !! Calculate the depth gradient limiter for refraction.
2975 #ifdef W3_T
2976  l = 0 !CB - added T switch
2977 #endif
2978 
2979 #ifdef W3_OMPG
2980  !$OMP Parallel DO Private(i, n, CNST4, CNST6)
2981 #endif
2982  DO n=1,nsea
2983 
2984  !Li Work out magnitude of depth gradient
2985  cnst4 = 1.0001*sqrt(dhdx(n)*dhdx(n) + dhdy(n)*dhdy(n))
2986  !
2987  !Li Directional depedent depth gradient limiter. JGLi16Jun2011
2988  IF ( cnst4 .GT. 1.0e-5 ) THEN
2989 
2990 #if defined W3_T && defined W3_OMPG
2991  !$OMP ATOMIC Update !CB - added T switch
2992 #endif
2993  l = l + 1 !CB - added T switch
2994 #if defined W3_T && defined W3_OMPG
2995  !$OMP END ATOMIC !CB - added T switch
2996 #endif
2997 
2998  DO i=1, nth
2999  !Li Refraction is done only when depth gradient is non-zero.
3000  !Li Note ACOS returns value between [0, Pi), always positive.
3001  cnst6 = acos(-(dhdx(n)*ecos(i)+dhdy(n)*esin(i))/cnst4 )
3002  !Li User-defined refraction limiter added. JGLi09Jan2012
3003  dhlmt(i,n)=min(refran, 0.75*min(cnst6,abs(pi-cnst6)))/dth
3004  END DO
3005  !Li Output some values for inspection. JGLi22Jul2011
3006 #ifdef W3_T
3007  IF( mod(n, 1000) .EQ. 0 ) &
3008  WRITE(ndst,'(i8,18F5.1)' ) n, (dhlmt(i,n), i=1,18)
3009 #endif
3010 
3011  ELSE
3012  dhlmt(:,n) = 0.0
3013  ENDIF
3014 
3015  ENDDO
3016 #ifdef W3_OMPG
3017  !$OMP END Parallel DO
3018 #endif
3019 
3020 #ifdef W3_T
3021  WRITE(ndst,*) ' No. Refraction points =', l
3022 #endif
3023 
3024 #ifdef W3_T
3025 999 print*, ' Sub SMCDHXY ended.'
3026 #endif
3027 
3028  RETURN

References w3gdatmd::angarc, w3gdatmd::arctc, w3gdatmd::clats, w3adatmd::dddx, w3adatmd::dddy, constants::dera, w3adatmd::dhdx, w3adatmd::dhdy, w3adatmd::dhlmt, w3gdatmd::dmin, w3gdatmd::dth, w3adatmd::dw, w3gdatmd::ecos, w3gdatmd::esin, w3gdatmd::ijkcel, w3gdatmd::mapfs, w3gdatmd::mapsta, w3gdatmd::mrfct, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nglo, w3gdatmd::nsea, w3gdatmd::nth, w3gdatmd::nx, w3gdatmd::ny, constants::pi, w3gdatmd::refran, and smcgradn().

Referenced by w3wavemd::w3wave().

◆ smcgradn()

subroutine w3psmcmd::smcgradn ( real, dimension(nsea), intent(in)  CVQ,
real, dimension(nsea), intent(out)  GrdX,
real, dimension(nsea), intent(out)  GrdY,
integer, intent(in)  L0r1 
)

Evaluate local gradient for sea points.

Calculate cell centre gradient for any input variable. Nemerical average is applied to size-changing faces and the gradients are along the lat-lon local east-north directions.

Parameters
[in]CVQInput cell values.
[out]GrdXGradient along x-axis.
[out]GrdYGradient along y-axis.
[in]L0r1Zero or 1st-order boundary condiiton.
Author
Jian-Guo Li
Date
08 Aug 2017

Definition at line 2335 of file w3psmcmd.F90.

2335 
2336  USE constants
2337  USE w3gdatmd, ONLY: nsea, nufc, nvfc, mrfct, &
2338  ijkcel, ijkufc, ijkvfc, clats, sx, sy
2339  USE w3gdatmd, ONLY: arctc
2340  USE w3odatmd, ONLY: ndse, ndst
2341 
2342  IMPLICIT NONE
2343  !! New boundary conditions depending on user defined L0r1.
2344  !! L0r1 = 0 will set zero at land points while L0r1 > 0 invokes
2345  !! the zero-gradient boundary condition. JGLi08Aug2017
2346  REAL, INTENT( IN):: CVQ(NSEA)
2347  REAL, INTENT(Out):: GrdX(NSEA), GrdY(NSEA)
2348  INTEGER, INTENT( IN):: L0r1
2349  !
2350  INTEGER :: I, J, K, L, M, N
2351  REAL:: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6
2352  REAL :: DX0I, DY0I
2353 
2354  ! Use a few working arrays
2355  REAL, Dimension(-9:NSEA):: CVF, AUN, AVN
2356 
2357  ! Two layer of boundary cells are added to each boundary cell face
2358  ! with all boundary cell default values CVF(-9:0)= 0.0.
2359  cvf(-9:0) = 0.0
2360  cvf(1:nsea)=cvq(1:nsea)
2361 
2362  !! Initialize arrays
2363  aun = 0.
2364  avn = 0.
2365  grdx = 0.
2366  grdy = 0.
2367 
2368  !! Multi-resolution base-cell size defined by refined levels.
2369  !! So the MRFct converts the base cell SX, SY into size-1 cell lenth.
2370  !! Constant size-1 dy=DY0 and dx on Equator DX0, inverted.
2371  dx0i = mrfct/ ( sx * dera * radius )
2372  dy0i = mrfct/ ( sy * dera * radius )
2373 
2374 #ifdef W3_OMPG
2375  !$OMP Parallel Default(Shared), Private(i, j, K, L, M, N), &
2376  !$OMP& Private(CNST,CNST0,CNST1,CNST2,CNST3,CNST4,CNST5,CNST6)
2377  !$OMP DO
2378 #endif
2379 
2380  !! Calculate x-gradient by averaging U-face gradients.
2381  DO i=1, nufc
2382 
2383  ! Select Upstream, Central and Downstream cells
2384  l=ijkufc(5,i)
2385  m=ijkufc(6,i)
2386 
2387  !! For zero-gradient boundary conditions, simply skip boundary faces.
2388  IF( l0r1 .EQ. 0 .OR. (l > 0 .AND. m > 0) ) THEN
2389 
2390  ! Multi-resolution SMC grid requires flux multiplied by face factor.
2391  cnst1=float( ijkufc(3,i) )
2392 
2393  ! Face bounding cell lengths and central gradient
2394  cnst2=float( ijkcel(3,l) )
2395  cnst3=float( ijkcel(3,m) )
2396 
2397  ! Side gradients over 2 cell lengths for central cell.
2398  ! Face size factor is also included for average.
2399  cnst5=cnst1*(cvf(m)-cvf(l))/(cnst2+cnst3)
2400 #if defined W3_B4B && defined W3_OMPG
2401  cnst5=int(cnst5 * 1.0e6) ! CB: B4B
2402 #endif
2403 
2404  !! Replace CRITICAL with ATOMIC. JGLi15Jan2019
2405  !! !$OMP CRITICAL
2406  ! Store side gradient in two neighbouring cells
2407  !! Remove boundary cell flux update or L M > 0. JGLi28Mar2019
2408  IF( l > 0 ) THEN
2409 #ifdef W3_OMPG
2410  !$OMP ATOMIC
2411 #endif
2412  aun(l) = aun(l) + cnst5
2413  ENDIF
2414  IF( m > 0 ) THEN
2415 #ifdef W3_OMPG
2416  !$OMP ATOMIC
2417 #endif
2418  aun(m) = aun(m) + cnst5
2419  ENDIF
2420  !! !$OMP END CRITICAL
2421 
2422  ENDIF
2423  END DO
2424 
2425 #ifdef W3_OMPG
2426  !$OMP END DO
2427 #endif
2428 
2429 #if defined W3_B4B && defined W3_OMPG
2430  !$OMP SINGLE
2431  aun = aun / 1.0e6 ! CB B4B
2432  !$OMP END SINGLE
2433 #endif
2434 
2435  ! Assign averaged side-gradient to GrdX, plus latitude factor
2436  ! Note averaging over 2 times of cell y-width factor but AUN
2437  ! has already been divied by two cell lengths.
2438 
2439 #ifdef W3_OMPG
2440  !$OMP DO
2441 #endif
2442 
2443  DO n=1, nsea
2444  ! Cell y-size IJKCel(4,i) is used to cancel the face size-factor in AUN.
2445  ! Plus the actual physical length scale for size-1 cell.
2446  ! Note polar cell (if any) AUN = 0.0 as it has no U-face.
2447  grdx(n)=dx0i*aun(n)/( clats(n)*ijkcel(4,n) )
2448 
2449  ENDDO
2450 
2451 #ifdef W3_OMPG
2452  !$OMP END DO
2453  !$OMP DO
2454 #endif
2455 
2456  !! Calculate y-gradient by averaging V-face gradients.
2457  DO j=1, nvfc
2458 
2459  ! Select Central and Downstream cells
2460  l=ijkvfc(5,j)
2461  m=ijkvfc(6,j)
2462 
2463  !! For zero-gradient boundary conditions, simply skip boundary faces.
2464  IF( l0r1 .EQ. 0 .OR. (l > 0 .AND. m > 0) ) THEN
2465 
2466  ! Face size is required for multi-resolution grid.
2467  cnst1=real( ijkvfc(3,j) )
2468 
2469  ! Cell y-length of UCD cells
2470  cnst2=real( ijkcel(4,l) )
2471  cnst3=real( ijkcel(4,m) )
2472 
2473  ! Side gradients over 2 cell lengths for central cell.
2474  ! Face size factor is also included for average.
2475  cnst6=cnst1*(cvf(m)-cvf(l))/(cnst2+cnst3)
2476 #if defined W3_B4B && defined W3_OMPG
2477  cnst6 = int(cnst6 * 1.0e6) ! CB B4B
2478 #endif
2479 
2480  !! Replace CRITICAL with ATOMIC. JGLi15Jan2019
2481  !! !$OMP CRITICAL
2482  !! Remove boundary cell flux update or L M > 0. JGLi28Mar2019
2483  IF( l > 0 ) THEN
2484  ! Store side gradient in two neighbouring cells
2485 #ifdef W3_OMPG
2486  !$OMP ATOMIC
2487 #endif
2488  avn(l) = avn(l) + cnst6
2489  ENDIF
2490  IF( m > 0 ) THEN
2491 #ifdef W3_OMPG
2492  !$OMP ATOMIC
2493 #endif
2494  avn(m) = avn(m) + cnst6
2495  ENDIF
2496  !! !$OMP END CRITICAL
2497 
2498  ENDIF
2499  END DO
2500 
2501 #ifdef W3_OMPG
2502  !$OMP END DO
2503 #endif
2504 
2505 #if defined W3_B4B && defined W3_OMPG
2506  !$OMP SINGLE
2507  avn = avn / 1.0e6 !CB B4B
2508  !$OMP END SINGLE
2509 #endif
2510 
2511 #ifdef W3_OMPG
2512  !$OMP DO
2513 #endif
2514 
2515  ! Assign averaged side-gradient to GrdY.
2516  DO n=1, nsea
2517  ! AV is divided by the cell x-size IJKCel(3,i) to cancel face
2518  ! size-factor, and physical y-distance of size-1 cell.
2519  grdy(n)=dy0i*avn(n)/real( ijkcel(3,n) )
2520 
2521  END DO
2522 
2523 #ifdef W3_OMPG
2524  !$OMP END DO
2525  !$OMP END Parallel
2526 #endif
2527 
2528  !!Li Y-gradient for polar cell in Arctic part is set to zero.
2529  IF( arctc ) grdy(nsea) = 0.0
2530 
2531  RETURN

References w3gdatmd::arctc, w3gdatmd::clats, constants::dera, w3gdatmd::ijkcel, w3gdatmd::ijkufc, w3gdatmd::ijkvfc, w3gdatmd::mrfct, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nsea, w3gdatmd::nufc, w3gdatmd::nvfc, constants::radius, w3gdatmd::sx, and w3gdatmd::sy.

Referenced by smcdcxy(), smcdhxy(), and w3smcomd::w3s2xy_smcnn_int().

◆ smcgtcrfr()

subroutine w3psmcmd::smcgtcrfr ( real, dimension(nth, nk), intent(in)  CoRfr,
real, dimension(nth, nk), intent(inout)  SpeTHK 
)

Calculate great circle turning (GCT) and refraction.

The refraction and GCT terms are equivalent to a single rotation by each element and does not need to be calculated as advection. A simple rotation scheme similar to the 1st order upstream scheme but without any restriction on the rotation angle or the CFL limit by an Eulerian advection scheme.

Parameters
[in]CoRfrCourant number for refraction and GCT rotation.
[in]SpeTHKWave spectrum to be rotated and output.
Author
Jian-Guo Li
Date
12 Nov 2010

Definition at line 2711 of file w3psmcmd.F90.

2711  USE constants
2712  USE w3gdatmd, ONLY: nk, nth, dth, ctmax
2713 
2714  IMPLICIT NONE
2715  REAL, INTENT(IN) :: CoRfr(NTH, NK)
2716  REAL, INTENT(INOUT):: SpeTHK(NTH, NK)
2717  INTEGER :: I, J, K, L, M, N
2718  REAL, Dimension(NTH):: SpeGCT, Spectr
2719  REAL:: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6
2720 
2721  ! Loop through NK spectral bins.
2722  DO n=1, nk
2723 
2724  !! Asign cell spectrum to temporary variable Spcetr
2725  spectr=spethk(1:nth,n)
2726  spegct=0.0
2727 
2728  !! Loop through NTH directional bins for each cell spectrum
2729  DO j=1, nth
2730 
2731  ! GCT + refraction Courant number for this dirctional bin
2732  cnst6=corfr(j,n)
2733 
2734  ! Work out integer number of bins to be skipped.
2735  ! If K is great than NTH, full circle turning is removed.
2736  cnst5=abs( cnst6 )
2737  k= mod( int(cnst5), nth )
2738 
2739  ! Partitioning faraction of the spectral component
2740  cnst1=cnst5 - float( int(cnst5) )
2741  cnst2=1.0 - cnst1
2742 
2743  ! For positive turning case
2744  IF(cnst6 > 0.0) THEN
2745 
2746  ! Select the upstream and downstream bins to rotate in, wrap at end
2747  l=j+k
2748  m=j+k+1
2749  IF( l .GT. nth ) l = l - nth
2750  IF( m .GT. nth ) m = m - nth
2751 
2752  !! Divide the j bin energy by fraction of CNST6 and store in SpeGCT
2753  spegct(l)=spegct(l)+spectr(j)*cnst2
2754  spegct(m)=spegct(m)+spectr(j)*cnst1
2755 
2756  ! For negative or no turning case
2757  ELSE
2758 
2759  ! Select the upstream and downstream bins to rotate in, wrap at end
2760  l=j-k
2761  m=j-k-1
2762  IF( l .LT. 1 ) l = l + nth
2763  IF( m .LT. 1 ) m = m + nth
2764 
2765  !! Divide the bin energy by fraction of CNST6 and store in SpeGCT
2766  spegct(l)=spegct(l)+spectr(j)*cnst2
2767  spegct(m)=spegct(m)+spectr(j)*cnst1
2768 
2769  ENDIF
2770 
2771  !! End of directional loop j
2772  END DO
2773 
2774  !! Store GCT spectrum
2775  spethk(1:nth,n) = spegct
2776 
2777  !! End of cell loop n
2778  END DO
2779 
2780  ! 999 PRINT*, ' Sub SMCGtCrfr ended.'
2781 
2782  RETURN

References w3gdatmd::ctmax, w3gdatmd::dth, w3gdatmd::nk, and w3gdatmd::nth.

Referenced by w3krtn().

◆ smckuno2()

subroutine w3psmcmd::smckuno2 ( real, dimension(nth, 0:nk), intent(in)  CoRfr,
real, dimension(nth, nk), intent(inout)  SpeTHK,
real, dimension(0:nk+1), intent(in)  DKC,
real, dimension(-1:nk+1), intent(in)  DKS 
)

Calculates refraction induced shift in k-space.

The term is equivalent to advection on an irregular k-space grid. The UNO2 scheme on irregular grid is used for this term.

Cell and side indices for k-dimension are arranged as:

    Cell:    | -1 | 0 | 1 | 2 | ... | NK | NK+1 | NK+2 |
    Side:        -1   0   1   2 ...     NK     NK+1

The wave action in k-space is extended at the high-wavenumber (frequency) end by the (m+2)th negative power of frequency for boundary conditions. Outside low-wavenumber (frequncy) end, wave action is assumed to be zero.

Parameters
[in]CoRfrCourant number for refraction k-shift.
[in,out]SpeTHKSpectrum to be shifted and output.
[in]DKCWave number increment at k-bin centre.
[in]DKSWave number increment at k-bin edges.
Author
Jian-Guo Li
Date
15 Nov 2010

Definition at line 2815 of file w3psmcmd.F90.

2815 
2816  USE constants
2817  USE w3gdatmd, ONLY: nk, nk2, nth, dth, xfr, ctmax
2818 
2819  IMPLICIT NONE
2820  REAL, INTENT(IN) :: CoRfr(NTH, 0:NK), DKC(0:NK+1), DKS(-1:NK+1)
2821  REAL, INTENT(INOUT):: SpeTHK(NTH, NK)
2822  INTEGER :: I, J, K, L, M, N
2823  REAL, Dimension(-1:NK+2):: SpeRfr, Spectr, SpeFlx
2824  REAL:: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6
2825 
2826  cnst=xfr**(-7)
2827 
2828  DO n=1, nth
2829 
2830  !! Asign cell spectrum to temporary variable Spcetr
2831  spectr(-1) =0.0
2832  spectr( 0) =0.0
2833  spectr(1:nk)=spethk(n,1:nk)
2834  spectr(nk+1)=spectr(nk )*cnst
2835  spectr(nk+2)=spectr(nk+1)*cnst
2836 
2837  !! Calculate k-space gradient for NK+2 faces by UNO2 scheme
2838  sperfr(-1)= 0.0
2839  DO j=-1, nk+1
2840  sperfr(j)=(spectr(j+1)-spectr(j))/dks(j)
2841  ENDDO
2842 
2843  !! Calculate k-space fluxes for NK+1 faces by UNO2 scheme
2844  DO j=0, nk
2845 
2846  ! Final refraction Courant number for this k-space face
2847  cnst6=corfr(n,j)
2848  !! Note CoRfr is CFL for k but without dividing dk.
2849 
2850  ! For positive case
2851  IF(cnst6 > 0.0) THEN
2852 
2853  cnst0 = min( ctmax*dkc(j), cnst6 )
2854  speflx(j) = cnst0*( spectr(j) + sign(0.5, sperfr(j))*(dkc(j)-cnst0) &
2855  *min( abs(sperfr(j-1)), abs(sperfr(j)) ) )
2856 
2857  ! For negative or no turning case
2858  ELSE
2859 
2860  cnst0 = min( ctmax*dkc(j+1), -cnst6 )
2861  speflx(j) = -cnst0*( spectr(j+1) - sign(0.5, sperfr(j))*(dkc(j+1)-cnst0) &
2862  *min( abs(sperfr(j+1)), abs(sperfr(j)) ) )
2863 
2864  ENDIF
2865 
2866  !! End of flux loop j
2867  END DO
2868 
2869  !! Update spectrum for the given direction
2870  DO j=1, nk
2871  ! Final refraction Courant number for this k-space face
2872  ! SpeTHK(n, j) = Spectr(j) + (SpeFlx(j-1) - SpeFlx(j))/DKC(j)
2873  ! Add positive filter in case negative values. JGLi27Jun2017
2874  spethk(n, j) = max( 0.0, spectr(j)+(speflx(j-1)-speflx(j))/dkc(j) )
2875  END DO
2876 
2877  !! End of directional loop n
2878  END DO
2879 
2880  ! 999 PRINT*, ' Sub SMCkUNO2 ended.'
2881 
2882  RETURN

References w3gdatmd::ctmax, w3gdatmd::dth, w3gdatmd::nk, w3gdatmd::nk2, w3gdatmd::nth, and w3gdatmd::xfr.

Referenced by w3krtn().

◆ smcxuno2()

subroutine w3psmcmd::smcxuno2 ( integer, intent(in)  NUA,
integer, intent(in)  NUB,
real, dimension(-9:ncel), intent(in)  CF,
real, dimension(-9:ncel), intent(in)  UC,
real, dimension(nufc), intent(out)  UFLX,
real, intent(in)  AKDif,
real, dimension(nufc), intent(out)  FU,
real, dimension(nufc), intent(out)  FX,
real, intent(in)  FTS 
)

Calculate mid-flux values for x dimension.

Parameters
[in]NUAStart number of U-face list.
[in]NUBEnd number of U-face list.
[in]CFTransported variable.
[in]UCVeclocity U-component at cell centre.
[out]UFLXMid-flux U-component on U-face.
[in]AKDifDiffusion coefficient.
[out]FUAdvection Mid-flux on U-face.
[out]FXDiffusion Mid-flux on U-face.
[in]FTSTimestep fraction for sub-timestep.
Author
Jian-Guo Li
Date
03-Mar-2022

Definition at line 1291 of file w3psmcmd.F90.

1291 
1292  USE constants
1293  USE w3gdatmd, ONLY: ncel, mrfct, nufc, ijkcel, ijkufc, clats, &
1294  ijkcel3, ijkcel4
1295  USE w3odatmd, ONLY: ndse, ndst
1296 
1297  IMPLICIT NONE
1298  INTEGER, INTENT( IN):: NUA, NUB
1299  REAL, INTENT( IN):: CF(-9:NCel), UC(-9:NCel), AKDif, FTS
1300  REAL, INTENT(Out):: UFLX(NUFc), FU(NUFc), FX(NUFc)
1301  !
1302  INTEGER :: i, j, k, L, M, N, ij
1303  REAL:: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6, CNST8, CNST9
1304 
1305  ! Two layer of boundary cells are added to each boundary cell face
1306  ! with all boundary cell values CF(-9:0)=0.0.
1307 
1308  ! Diffusion Fourier no. at sub-time-step, proportional to face size,
1309  ! which is also equal to the sub-time-step factor FTS.
1310  cnst0=akdif*fts*fts
1311  ! Uniform diffusion coefficient for all sizes. JGLi24Feb2012
1312  ! CNST0=AKDif*MRFct*FTS
1313 
1314 #ifdef W3_OMPG
1315  !$OMP Parallel Default(Shared), Private(i, ij, K, L, M, N), &
1316  !$OMP& Private(CNST,CNST1,CNST2,CNST3,CNST4,CNST5,CNST6,CNST8,CNST9)
1317 #endif
1318 
1319  ! Notice an extra side length L is multiplied to mid-flux to give correct
1320  ! proportion of flux into the cells. This length will be removed by the
1321  ! cell length when the tracer concentration is updated.
1322 
1323 #ifdef W3_OMPG
1324  !$OMP DO
1325 #endif
1326 
1327  DO i=nua, nub
1328 
1329  ! Select Upstream, Central and Downstream cells
1330  k=ijkufc(4,i)
1331  l=ijkufc(5,i)
1332  m=ijkufc(6,i)
1333  n=ijkufc(7,i)
1334 
1335  ! Face bounding cell lengths and central gradient
1336  cnst2=float( ijkcel3(l) )
1337  cnst3=float( ijkcel3(m) )
1338  cnst5=(cf(m)-cf(l))/( cnst2 + cnst3 )
1339 
1340  ! Courant number in local size-1 cell, arithmetic average.
1341  cnst6=0.5*( uc(l)+uc(m) )*fts
1342  uflx(i) = cnst6
1343 
1344  ! Multi-resolution SMC grid requires flux multiplied by face factor.
1345  cnst8 = float( ijkufc(3,i) )
1346 
1347  ! Diffusion factor in local size-1 cell, plus the cosine factors.
1348  ! 2.0 factor to cancel that in gradient CNST5. JGLi08Mar2012
1349  ! The maximum cell number is used to avoid the boundary cell number
1350  ! in selection of the cosine factor.
1351  ij= max(l, m)
1352  cnst9 = 2.0/( clats( ij )*clats( ij ) )
1353 
1354  ! For positive velocity case
1355  IF(cnst6 >= 0.0) THEN
1356 
1357  ! Use central cell velocity for boundary flux. JGLi06Apr2011
1358  IF( m .LE. 0) uflx(i) = uc(l)*fts
1359 
1360  ! Upstream cell length and gradient, depending on UFLX sign.
1361  cnst1=float( ijkcel3(k) )
1362  cnst4=(cf(l)-cf(k))/( cnst2 + cnst1 )
1363 
1364  ! Use minimum gradient all region.
1365  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1366 
1367  ! Mid-flux value inside central cell
1368  fu(i)=(cf(l) + cnst*(cnst2 - uflx(i)))*cnst8
1369 
1370  ! For negative velocity case
1371  ELSE
1372 
1373  ! Use central cell velocity for boundary flux. JGLi06Apr2011
1374  IF( l .LE. 0) uflx(i) = uc(m)*fts
1375 
1376  ! Upstream cell length and gradient, depending on UFLX sign.
1377  cnst1=float( ijkcel3(n) )
1378  cnst4=(cf(n)-cf(m))/( cnst1 + cnst3 )
1379 
1380  ! Use minimum gradient outside monotonic region.
1381  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1382 
1383  ! Mid-flux value inside central cell M
1384  fu(i)=(cf(m) - cnst*(cnst3+uflx(i)))*cnst8
1385 
1386  ENDIF
1387 
1388  ! Diffusion flux by face gradient x DT
1389  fx(i)=cnst0*cnst5*cnst8*cnst9
1390 
1391  END DO
1392 
1393 #ifdef W3_OMPG
1394  !$OMP END DO
1395  !$OMP END Parallel
1396 #endif
1397 
1398  RETURN

References w3gdatmd::clats, w3gdatmd::ijkcel, w3gdatmd::ijkcel3, w3gdatmd::ijkcel4, w3gdatmd::ijkufc, w3gdatmd::mrfct, w3gdatmd::ncel, w3odatmd::ndse, w3odatmd::ndst, and w3gdatmd::nufc.

Referenced by w3psmc().

◆ smcxuno2r()

subroutine w3psmcmd::smcxuno2r ( integer, intent(in)  NUA,
integer, intent(in)  NUB,
real, dimension(-9:ncel), intent(in)  CF,
real, dimension(-9:ncel), intent(in)  UC,
real, dimension(nufc), intent(out)  UFLX,
real, intent(in)  AKDif,
real, dimension(nufc), intent(out)  FU,
real, dimension(nufc), intent(out)  FX 
)

Calculate mid-flux values for x dimension.

Parameters
[in]NUAStart number of U-face list.
[in]NUBEnd number of U-face list.
[in]CFTransported variable.
[in]UCVeclocity U-component at cell centre.
[out]UFLXMid-flux U-component on U-face.
[in]AKDifDiffusion coefficient.
[out]FUAdvection Mid-flux on U-face.
[out]FXDiffusion Mid-flux on U-face.
Author
Jian-Guo Li
Date
03-Mar-2022

Definition at line 1545 of file w3psmcmd.F90.

1545 
1546  USE constants
1547  USE w3gdatmd, ONLY: nsea, ny, ncel, nufc, ijkcel, ijkufc, clats
1548  USE w3gdatmd, ONLY: ijkcel3
1549  USE w3odatmd, ONLY: ndse, ndst
1550 
1551  IMPLICIT NONE
1552  INTEGER, INTENT( IN):: NUA, NUB
1553  REAL, INTENT( IN):: CF(-9:NCel), UC(-9:NCel), AKDif
1554  REAL, INTENT(Out):: UFLX(NUFc), FU(NUFc), FX(NUFc)
1555  !
1556  INTEGER :: i, j, k, L, M, N, ij
1557  REAL:: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6
1558 
1559  ! Two layer of boundary cells are added to each boundary cell face
1560  ! with all boundary cell values CF(-9:0)=0.0.
1561 
1562  ! Notice an extra side length L is multiplied to mid-flux to give correct
1563  ! proportion of flux into the cells. This length will be removed by the
1564  ! cell length when the tracer concentration is updated.
1565 
1566 #ifdef W3_OMPG
1567  !$OMP Parallel Default(Shared), Private(i, ij, K, L, M, N), &
1568  !$OMP& Private(CNST,CNST0,CNST1,CNST2,CNST3,CNST4,CNST5,CNST6)
1569  !$OMP DO
1570 #endif
1571 
1572  DO i=nua, nub
1573 
1574  ! Select Upstream, Central and Downstream cells
1575  k=ijkufc(4,i)
1576  l=ijkufc(5,i)
1577  m=ijkufc(6,i)
1578  n=ijkufc(7,i)
1579 
1580  ! Face bounding cell lengths and gradient
1581  cnst2=float( ijkcel3(l) )
1582  cnst3=float( ijkcel3(m) )
1583  cnst5=(cf(m)-cf(l))
1584 
1585  ! Averaged Courant number for base-level cell face
1586  cnst6= 0.5*( uc(l)+uc(m) )
1587  uflx(i) = cnst6
1588 
1589  ! Diffusion Fourier number in local cell size
1590  ! To avoid boundary cell number, use maximum of L and M.
1591  ij= max(l, m)
1592  cnst0 = 2.0/( clats(ij)*clats(ij) )
1593 
1594  ! For positive velocity case
1595  IF(cnst6 >= 0.0) THEN
1596 
1597  ! Use central cell velocity for boundary flux. JGLi06Apr2011
1598  IF( m .LE. 0) uflx(i) = uc(l)
1599 
1600  ! Side gradient for upstream cell as regular grid.
1601  cnst4=(cf(l)-cf(k))
1602 
1603  ! Use minimum gradient all region with 0.5 factor
1604  cnst=sign(0.5, cnst5)*min( abs(cnst4), abs(cnst5) )
1605 
1606  ! Mid-flux value inside central cell
1607  fu(i)=(cf(l) + cnst*(1.0-uflx(i)/cnst2))
1608 
1609  ! For negative velocity case
1610  ELSE
1611 
1612  ! Use central cell velocity for boundary flux. JGLi06Apr2011
1613  IF( l .LE. 0) uflx(i) = uc(m)
1614 
1615  ! Side gradient for upstream cell, depneding on UFLX sign.
1616  cnst4=(cf(n)-cf(m))
1617 
1618  ! Use minimum gradient outside monotonic region, include 0.5 factor
1619  cnst=sign(0.5, cnst5)*min( abs(cnst4), abs(cnst5) )
1620 
1621  ! Mid-flux value inside central cell M
1622  fu(i)=(cf(m) - cnst*(1.0+uflx(i)/cnst3))
1623 
1624  ENDIF
1625 
1626  ! Diffusion flux by face gradient x DT
1627  fx(i)=akdif*cnst0*cnst5/(cnst2 + cnst3)
1628 
1629  END DO
1630 
1631 #ifdef W3_OMPG
1632  !$OMP END DO
1633  !$OMP END Parallel
1634 #endif
1635 
1636  RETURN

References w3gdatmd::clats, w3gdatmd::ijkcel, w3gdatmd::ijkcel3, w3gdatmd::ijkufc, w3gdatmd::ncel, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nsea, w3gdatmd::nufc, and w3gdatmd::ny.

Referenced by w3psmc().

◆ smcxuno3()

subroutine w3psmcmd::smcxuno3 ( integer, intent(in)  NUA,
integer, intent(in)  NUB,
real, dimension(-9:ncel), intent(in)  CF,
real, dimension(-9:ncel), intent(in)  UC,
real, dimension(nufc), intent(out)  UFLX,
real, intent(in)  AKDif,
real, dimension(nufc), intent(out)  FU,
real, dimension(nufc), intent(out)  FX,
real, intent(in)  FTS 
)

Calculate mid-flux values for x dimension with UNO3 scheme.

Parameters
[in]NUAStart number of U-face list.
[in]NUBEnd number of U-face list.
[in]CFTransported variable.
[in]UCVeclocity U-component at cell centre.
[out]UFLXMid-flux U-component on U-face.
[in]AKDifDiffusion coefficient.
[out]FUAdvection Mid-flux on U-face.
[out]FXDiffusion Mid-flux on U-face.
[in]FTSTimestep fraction for sub-timestep.
Author
Jian-Guo Li
Date
03-Mar-2022

Definition at line 1758 of file w3psmcmd.F90.

1758 
1759  USE constants
1760  USE w3gdatmd, ONLY: ncel, mrfct, nufc, ijkcel, ijkufc, clats
1761  USE w3gdatmd, ONLY: ijkcel3
1762  USE w3odatmd, ONLY: ndse, ndst
1763 
1764  IMPLICIT NONE
1765  INTEGER, INTENT( IN):: NUA, NUB
1766  REAL, INTENT( IN):: CF(-9:NCel), UC(-9:NCel), AKDif, FTS
1767  REAL, INTENT(Out):: UFLX(NUFc), FU(NUFc), FX(NUFc)
1768  !
1769  INTEGER :: i, j, k, L, M, N, ij
1770  REAL :: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6, &
1771  CNST7, CNST8, CNST9
1772 
1773  ! Two layer of boundary cells are added to each boundary cell face
1774  ! with all boundary cell values CF(-9:0)=0.0.
1775 
1776  ! Diffusion Fourier no. at sub-time-step, proportional to face size,
1777  ! which is also equal to the sub-time-step factor FTS.
1778  ! CNST0=AKDif*FTS*FTS
1779  ! 2.0 factor to cancel that in gradient CNST5. JGLi03Sep2015
1780  cnst0=akdif*fts*fts*2.0
1781 
1782  ! Notice an extra side length L is multiplied to mid-flux to give correct
1783  ! proportion of flux into the cells. This length will be removed by the
1784  ! cell length when the tracer concentration is updated.
1785 
1786 #ifdef W3_OMPG
1787  !$OMP Parallel Default(Shared), Private(i, ij, K, L, M, N), &
1788  !$OMP& Private(CNST,CNST1,CNST2,CNST3,CNST4,CNST5,CNST6,CNST7,CNST8,CNST9)
1789  !$OMP DO
1790 #endif
1791 
1792  DO i=nua, nub
1793 
1794  ! Select Upstream, Central and Downstream cells
1795  k=ijkufc(4,i)
1796  l=ijkufc(5,i)
1797  m=ijkufc(6,i)
1798  n=ijkufc(7,i)
1799 
1800  ! Face bounding cell lengths and central gradient
1801  cnst2=float( ijkcel3(l) )
1802  cnst3=float( ijkcel3(m) )
1803  cnst5=(cf(m)-cf(l))/( cnst2 + cnst3 )
1804 
1805  ! Courant number in local size-1 cell, arithmetic average.
1806  cnst6=0.5*( uc(l)+uc(m) )*fts
1807  uflx(i) = cnst6
1808 
1809  ! Multi-resolution SMC grid requires flux multiplied by face factor.
1810  cnst8 = float( ijkufc(3,i) )
1811 
1812  ! Diffusion factor in local size-1 cell, plus the cosine factors.
1813  ! 2.0 factor to cancel that in gradient CNST5. JGLi08Mar2012
1814  ! The maximum cell number is used to avoid the boundary cell number
1815  ! in selection of the cosine factor.
1816  ij= max(l, m)
1817 
1818  ! For positive velocity case
1819  IF(cnst6 >= 0.0) THEN
1820 
1821  ! Use central cell velocity for boundary flux. JGLi06Apr2011
1822  IF( m .LE. 0) uflx(i) = uc(l)*fts
1823 
1824  ! Upstream cell length and gradient, depending on UFLX sign.
1825  cnst1=float( ijkcel3(k) )
1826  cnst4=(cf(l)-cf(k))/( cnst2 + cnst1 )
1827 
1828  ! Second order gradient
1829  cnst7 = cnst5 - cnst4
1830  cnst9 = 2.0/( cnst3+cnst2+cnst2+cnst1 )
1831 
1832  ! Use 3rd order scheme
1833  IF( abs(cnst7) .LT. 0.6*cnst9*abs(cf(m)-cf(k)) ) THEN
1834  cnst= cnst5 - ( cnst3+uflx(i) )*cnst7*cnst9/1.5
1835 
1836  ! Use doubled UNO2 scheme
1837  ELSE IF( dble(cnst4)*dble(cnst5) .GT. 0.d0 ) THEN
1838  cnst=sign(2.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1839 
1840  ELSE
1841  ! Use minimum gradient UNO2 scheme
1842  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1843 
1844  ENDIF
1845 
1846  ! Mid-flux value inside central cell
1847  fu(i)=(cf(l) + cnst*(cnst2 - uflx(i)))*cnst8
1848 
1849  ! For negative velocity case
1850  ELSE
1851 
1852  ! Use central cell velocity for boundary flux. JGLi06Apr2011
1853  IF( l .LE. 0) uflx(i) = uc(m)*fts
1854 
1855  ! Upstream cell length and gradient, depending on UFLX sign.
1856  cnst1=float( ijkcel3(n) )
1857  cnst4=(cf(n)-cf(m))/( cnst1 + cnst3 )
1858 
1859  ! Second order gradient
1860  cnst7 = cnst4 - cnst5
1861  cnst9 = 2.0/( cnst2+cnst3+cnst3+cnst1 )
1862 
1863  ! Use 3rd order scheme
1864  IF( abs(cnst7) .LT. 0.6*cnst9*abs(cf(n)-cf(l)) ) THEN
1865  cnst= cnst5 + ( cnst2-uflx(i) )*cnst7*cnst9/1.5
1866 
1867  ! Use doubled UNO2 scheme
1868  ELSE IF( dble(cnst4)*dble(cnst5) .GT. 0.d0 ) THEN
1869  cnst=sign(2.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1870 
1871  ELSE
1872  ! Use minimum gradient UNO2 scheme.
1873  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1874 
1875  ENDIF
1876 
1877  ! Mid-flux value inside central cell M
1878  fu(i)=(cf(m) - cnst*(cnst3+uflx(i)))*cnst8
1879 
1880  ENDIF
1881 
1882  ! Diffusion flux by face gradient x DT
1883  fx(i)=cnst0*cnst5*cnst8/( clats( ij )*clats( ij ) )
1884 
1885  END DO
1886 
1887 #ifdef W3_OMPG
1888  !$OMP END DO
1889  !$OMP END Parallel
1890 #endif
1891 
1892  RETURN

References w3gdatmd::clats, w3gdatmd::ijkcel, w3gdatmd::ijkcel3, w3gdatmd::ijkufc, w3gdatmd::mrfct, w3gdatmd::ncel, w3odatmd::ndse, w3odatmd::ndst, and w3gdatmd::nufc.

Referenced by w3psmc().

◆ smcxuno3r()

subroutine w3psmcmd::smcxuno3r ( integer, intent(in)  NUA,
integer, intent(in)  NUB,
real, dimension(-9:ncel), intent(in)  CF,
real, dimension(-9:ncel), intent(in)  UC,
real, dimension(nufc), intent(out)  UFLX,
real, intent(in)  AKDif,
real, dimension(nufc), intent(out)  FU,
real, dimension(nufc), intent(out)  FX 
)

Calculate mid-flux values for x dimension with UNO3.

Parameters
[in]NUAStart number of U-face list.
[in]NUBEnd number of U-face list.
[in]CFTransported variable.
[in]UCVeclocity U-component at cell centre.
[out]UFLXMid-flux U-component on U-face.
[in]AKDifDiffusion coefficient.
[out]FUAdvection Mid-flux on U-face.
[out]FXDiffusion Mid-flux on U-face.
Author
Jian-Guo Li
Date
03-Mar-2022

Definition at line 2074 of file w3psmcmd.F90.

2074 
2075  USE constants
2076  USE w3gdatmd, ONLY: nsea, ny, ncel, nufc, ijkcel, ijkufc, clats
2077  USE w3gdatmd, ONLY: ijkcel3
2078  USE w3odatmd, ONLY: ndse, ndst
2079 
2080  IMPLICIT NONE
2081  INTEGER, INTENT( IN):: NUA, NUB
2082  REAL, INTENT( IN):: CF(-9:NCel), UC(-9:NCel), AKDif
2083  REAL, INTENT(Out):: UFLX(NUFc), FU(NUFc), FX(NUFc)
2084  !
2085  INTEGER :: i, j, k, L, M, N, ij
2086  REAL:: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6, &
2087  CNST7, CNST8, CNST9
2088  ! Two layer of boundary cells are added to each boundary cell face
2089  ! with all boundary cell values CF(-9:0)=0.0.
2090 
2091  ! Notice an extra side length L is multiplied to mid-flux to give correct
2092  ! proportion of flux into the cells. This length will be removed by the
2093  ! cell length when the tracer concentration is updated.
2094 
2095 #ifdef W3_OMPG
2096  !$OMP Parallel Default(Shared), Private(i, ij, K, L, M, N), &
2097  !$OMP& Private(CNST,CNST0,CNST1,CNST2,CNST3,CNST4,CNST5,CNST6,CNST7,CNST8,CNST9)
2098  !$OMP DO
2099 #endif
2100 
2101  DO i=nua, nub
2102 
2103  ! Select Upstream, Central and Downstream cells
2104  k=ijkufc(4,i)
2105  l=ijkufc(5,i)
2106  m=ijkufc(6,i)
2107  n=ijkufc(7,i)
2108 
2109  ! Face bounding cell lengths and gradient
2110  cnst2=float( ijkcel3(l) )
2111  cnst3=float( ijkcel3(m) )
2112  cnst5=(cf(m)-cf(l))
2113 
2114  ! Averaged Courant number for base-level cell face
2115  cnst6= 0.5*( uc(l)+uc(m) )
2116  uflx(i) = cnst6
2117 
2118  ! Diffusion Fourier number in local cell size
2119  ! To avoid boundary cell number, use maximum of L and M.
2120  ij= max(l, m)
2121  cnst0 = 2.0/( clats(ij)*clats(ij) )
2122 
2123  ! For positive velocity case
2124  IF(cnst6 >= 0.0) THEN
2125 
2126  ! Use central cell velocity for boundary flux. JGLi06Apr2011
2127  IF( m .LE. 0) uflx(i) = uc(l)
2128 
2129  ! Side gradient for upstream cell as regular grid.
2130  cnst4=(cf(l)-cf(k))
2131  cnst8=(cf(m)-cf(k))
2132  cnst9=(cnst5-cnst4)
2133 
2134  IF( abs(cnst9) <= 0.6*abs(cnst8) ) THEN
2135  ! Use 3rd order scheme in limited zone, note division by 2 grid sizes
2136  cnst=0.5*cnst5 - (1.0+uflx(i)/cnst2)*cnst9/6.0
2137  ELSE IF( dble(cnst4)*dble(cnst5) .GT. 0.d0 ) THEN
2138  ! Use doubled minimum gradient in rest of monotonic region
2139  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
2140  ELSE
2141  ! Use minimum gradient all region with 0.5 factor
2142  cnst=sign(0.5, cnst5)*min( abs(cnst4), abs(cnst5) )
2143  ENDIF
2144  ! Mid-flux value inside central cell
2145  fu(i)=(cf(l) + cnst*(1.0-uflx(i)/cnst2))
2146 
2147  ! For negative velocity case
2148  ELSE
2149 
2150  ! Use central cell velocity for boundary flux. JGLi06Apr2011
2151  IF( l .LE. 0) uflx(i) = uc(m)
2152 
2153  ! Side gradient for upstream cell, depneding on UFLX sign.
2154  cnst4=(cf(n)-cf(m))
2155  cnst8=(cf(n)-cf(l))
2156  cnst9=(cnst4-cnst5)
2157 
2158  IF( abs(cnst9) <= 0.6*abs(cnst8) ) THEN
2159  ! Use 3rd order scheme in limited zone, note division by 2 grid sizes
2160  cnst=0.5*cnst5 + (1.0-uflx(i)/cnst3)*cnst9/6.0
2161  ELSE IF( dble(cnst4)*dble(cnst5) .GT. 0.d0 ) THEN
2162  ! Use doubled minimum gradient in rest of monotonic region
2163  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
2164  ELSE
2165  ! Use minimum gradient outside monotonic region, include 0.5 factor
2166  cnst=sign(0.5, cnst5)*min( abs(cnst4), abs(cnst5) )
2167  ENDIF
2168 
2169  ! Mid-flux value inside central cell M
2170  fu(i)=(cf(m) - cnst*(1.0+uflx(i)/cnst3))
2171 
2172  ENDIF
2173 
2174  ! Diffusion flux by face gradient x DT
2175  fx(i)=akdif*cnst0*cnst5/(cnst2 + cnst3)
2176 
2177  END DO
2178 
2179 #ifdef W3_OMPG
2180  !$OMP END DO
2181  !$OMP END Parallel
2182 #endif
2183 
2184  ! 999 PRINT*, ' Sub SMCxUNO3r ended.'
2185 
2186  RETURN

References w3gdatmd::clats, w3gdatmd::ijkcel, w3gdatmd::ijkcel3, w3gdatmd::ijkufc, w3gdatmd::ncel, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nsea, w3gdatmd::nufc, and w3gdatmd::ny.

Referenced by w3psmc().

◆ smcyuno2()

subroutine w3psmcmd::smcyuno2 ( integer, intent(in)  NVA,
integer, intent(in)  NVB,
real, dimension(-9:ncel), intent(in)  CF,
real, dimension(-9:ncel), intent(in)  VC,
real, dimension(nvfc), intent(out)  VFLY,
real, intent(in)  AKDif,
real, dimension(nvfc), intent(out)  FV,
real, dimension(nvfc), intent(out)  FY,
real, intent(in)  FTS 
)

Calculate mid-flux values for y dimension.

Parameters
[in]NVAStart number of V-face list.
[in]NVBEnd number of V-face list.
[in]CFTransported variable.
[in]VCVeclocity V-component at cell centre.
[out]VFLYMid-flux V-component on V-face.
[in]AKDifDiffusion coefficient.
[out]FVAdvection Mid-flux on V-face.
[out]FYDiffusion Mid-flux on V-face.
[in]FTSTimestep fraction for sub-timestep.
Author
Jian-Guo Li
Date
03-Mar-2022

Definition at line 1418 of file w3psmcmd.F90.

1418 
1419  USE constants
1420  USE w3gdatmd, ONLY: ncel, mrfct, nvfc, ijkcel, ijkvfc, clatf, ijkcel4
1421  USE w3odatmd, ONLY: ndse, ndst
1422 
1423  IMPLICIT NONE
1424  INTEGER, INTENT( IN):: NVA, NVB
1425  REAL, INTENT( IN):: CF(-9:NCel), VC(-9:NCel), AKDif, FTS
1426  REAL, INTENT(Out):: VFLY(NVFc), FV(NVFc), FY(NVFc)
1427  INTEGER :: i, j, k, L, M, N, ij
1428  REAL:: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6, CNST8
1429 
1430  ! Notice an extra side length L is multiplied to mid-flux to give correct
1431  ! proportion of flux into the cells. This length will be removed by the
1432  ! cell length when the tracer concentration is updated.
1433 
1434  ! Diffusion Fourier no. at sub-time-step, proportional to face size,
1435  ! which is also equal to the sub-time-step factor FTS.
1436  ! CNST0=AKDif*FTS*FTS
1437  ! 2.0 factor to cancel that in gradient CNST5. JGLi08Mar2012
1438  cnst0=akdif*fts*fts*2.0
1439  ! Uniform diffusion coefficient for all sizes. JGLi24Feb2012
1440  ! CNST0=AKDif*MRFct*FTS
1441 
1442 #ifdef W3_OMPG
1443  !$OMP Parallel Default(Shared), Private(j, K, L, M, N), &
1444  !$OMP& Private(CNST,CNST1,CNST2,CNST3,CNST4,CNST5,CNST6,CNST8)
1445  !$OMP DO
1446 #endif
1447 
1448  DO j=nva, nvb
1449 
1450  ! Select Upstream, Central and Downstream cells
1451  k=ijkvfc(4,j)
1452  l=ijkvfc(5,j)
1453  m=ijkvfc(6,j)
1454  n=ijkvfc(7,j)
1455 
1456  ! Face bounding cell lengths and gradient
1457  cnst2=float( ijkcel4(l) )
1458  cnst3=float( ijkcel4(m) )
1459  cnst5=(cf(m)-cf(l))/( cnst2 + cnst3 )
1460 
1461  ! Courant number in local size-1 cell unit
1462  ! Multiply by multi-resolution time step factor FTS
1463  cnst6=0.5*( vc(l)+vc(m) )*fts
1464  vfly(j) = cnst6
1465 
1466  ! Face size integer and cosine factor.
1467  ! CLATF is defined on V-face for SMC grid. JGLi28Feb2012
1468  cnst8=clatf(j)*float( ijkvfc(3,j) )
1469 
1470  ! For positive velocity case
1471  IF(cnst6 >= 0.0) THEN
1472 
1473  ! Boundary cell y-size is set equal to central cell y-size
1474  ! as y-boundary cell sizes are not proportional to refined
1475  ! inner cells but constant of the base cell y-size, and
1476  ! Use central cell speed for face speed. JGLi06Apr2011
1477  IF( m .LE. 0 ) THEN
1478  vfly(j) = vc(l)*fts
1479  cnst3 = cnst2
1480  ENDIF
1481 
1482  ! Upstream cell size and irregular grid gradient, depending on VFLY.
1483  cnst1=float( ijkcel4(k) )
1484  cnst4=(cf(l)-cf(k))/( cnst2 + cnst1 )
1485 
1486  ! Use minimum gradient outside monotonic region
1487  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1488 
1489  ! Mid-flux value multiplied by face width and cosine factor
1490  fv(j)=( cf(l) + cnst*(cnst2 - vfly(j)) )*cnst8
1491 
1492  ! For negative velocity case
1493  ELSE
1494 
1495  ! Set boundary cell y-size equal to central cell y-size and
1496  ! Use central cell speed for flux face speed. JGLi06Apr2011
1497  IF( l .LE. 0 ) THEN
1498  vfly(j) = vc(m)*fts
1499  cnst2 = cnst3
1500  ENDIF
1501 
1502  ! Upstream cell size and gradient, depending on VFLY sign.
1503  ! Side gradients for central cell includs 0.5 factor.
1504  cnst1=float( ijkcel4(n) )
1505  cnst4=(cf(n)-cf(m))/( cnst1 + cnst3 )
1506 
1507  ! Use minimum gradient outside monotonic region
1508  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1509 
1510  ! Mid-flux value multiplied by face width and cosine factor
1511  fv(j)=( cf(m) - cnst*(cnst3 + vfly(j)) )*cnst8
1512 
1513  ENDIF
1514 
1515  ! Diffusion flux by face gradient x DT x face_width x cos(lat)
1516  ! Multiply by multi-resolution time step factor FTS
1517  fy(j)=cnst0*cnst5*cnst8
1518 
1519  END DO
1520 
1521 #ifdef W3_OMPG
1522  !$OMP END DO
1523  !$OMP END Parallel
1524 #endif
1525 
1526  RETURN

References w3gdatmd::clatf, w3gdatmd::ijkcel, w3gdatmd::ijkcel4, w3gdatmd::ijkvfc, w3gdatmd::mrfct, w3gdatmd::ncel, w3odatmd::ndse, w3odatmd::ndst, and w3gdatmd::nvfc.

Referenced by w3psmc().

◆ smcyuno2r()

subroutine w3psmcmd::smcyuno2r ( integer, intent(in)  NVA,
integer, intent(in)  NVB,
real, dimension(-9:ncel), intent(in)  CF,
real, dimension(-9:ncel), intent(in)  VC,
real, dimension(nvfc), intent(out)  VFLY,
real, intent(in)  AKDif,
real, dimension(nvfc), intent(out)  FV,
real, dimension(nvfc), intent(out)  FY 
)

Calculate mid-flux values for y dimension.

Parameters
[in]NVAStart number of V-face list.
[in]NVBEnd number of V-face list.
[in]CFTransported variable.
[in]VCVeclocity V-component at cell centre.
[out]VFLYMid-flux V-component on V-face.
[in]AKDifDiffusion coefficient.
[out]FVAdvection Mid-flux on V-face.
[out]FYDiffusion Mid-flux on V-face.
Author
Jian-Guo Li
Date
03-Mar-2022

Definition at line 1655 of file w3psmcmd.F90.

1655 
1656  USE constants
1657  USE w3gdatmd, ONLY: nsea, ny, ncel, nvfc, ijkcel, ijkvfc, clatf
1658  USE w3odatmd, ONLY: ndse, ndst
1659 
1660  IMPLICIT NONE
1661  INTEGER, INTENT( IN):: NVA, NVB
1662  REAL, INTENT( IN):: CF(-9:NCel), VC(-9:NCel), AKDif
1663  REAL, INTENT(Out):: VFLY(NVFc), FV(NVFc), FY(NVFc)
1664  INTEGER :: i, j, k, L, M, N, ij
1665  REAL:: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6, CNST8
1666 
1667  ! Notice an extra side length L is multiplied to mid-flux to give correct
1668  ! proportion of flux into the cells. This length will be removed by the
1669  ! cell length when the tracer concentration is updated.
1670 
1671 #ifdef W3_OMPG
1672  !$OMP Parallel Default(Shared), Private(j, K, L, M, N), &
1673  !$OMP& Private(CNST,CNST4,CNST5,CNST6,CNST8)
1674  !$OMP DO
1675 #endif
1676 
1677  DO j=nva, nvb
1678 
1679  ! Select Upstream, Central and Downstream cells
1680  k=ijkvfc(4,j)
1681  l=ijkvfc(5,j)
1682  m=ijkvfc(6,j)
1683  n=ijkvfc(7,j)
1684 
1685  ! Central face gradient.
1686  cnst5=(cf(m)-cf(l))
1687 
1688  ! Courant number in basic cell unit as dy is constant
1689  cnst6=0.5*( vc(l)+vc(m) )
1690  vfly(j) = cnst6
1691 
1692  ! Face size integer and cosine factor
1693  ! CLATF is defined on V-face for SMC grid. JGLi28Feb2012
1694  cnst8=clatf(j)*float( ijkvfc(3,j) )
1695 
1696  ! For positive velocity case
1697  IF(cnst6 >= 0.0) THEN
1698 
1699  ! Use central cell speed for flux face speed. JGLi06Apr2011
1700  IF( m .LE. 0 ) vfly(j) = vc(l)
1701 
1702  ! Upstream face gradient, depending on VFLY sign.
1703  cnst4=(cf(l)-cf(k))
1704 
1705  ! Use minimum gradient, including 0.5 factor and central sign.
1706  cnst=sign(0.5, cnst5)*min( abs(cnst4), abs(cnst5) )
1707 
1708  ! Mid-flux value multiplied by face width and cosine factor
1709  fv(j)=( cf(l) + cnst*(1.0-vfly(j)) )*cnst8
1710 
1711  ! For negative velocity case
1712  ELSE
1713 
1714  ! Use central cell speed for flux face speed. JGLi06Apr2011
1715  IF( l .LE. 0 ) vfly(j) = vc(m)
1716 
1717  ! Side gradients for upstream face, depending on VFLY sign.
1718  cnst4=(cf(n)-cf(m))
1719 
1720  ! Use minimum gradient, including 0.5 factor and central sign.
1721  cnst=sign(0.5, cnst5)*min( abs(cnst4), abs(cnst5) )
1722 
1723  ! Mid-flux value multiplied by face width and cosine factor
1724  fv(j)=( cf(m) - cnst*(1.0+vfly(j)) )*cnst8
1725 
1726  ENDIF
1727 
1728  ! Diffusion flux by face gradient x DT x face_width x cos(lat)
1729  fy(j)=akdif*cnst5*cnst8
1730 
1731  END DO
1732 
1733 #ifdef W3_OMPG
1734  !$OMP END DO
1735  !$OMP END Parallel
1736 #endif
1737 
1738  RETURN

References w3gdatmd::clatf, w3gdatmd::ijkcel, w3gdatmd::ijkvfc, w3gdatmd::ncel, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nsea, w3gdatmd::nvfc, and w3gdatmd::ny.

Referenced by w3psmc().

◆ smcyuno3()

subroutine w3psmcmd::smcyuno3 ( integer, intent(in)  NVA,
integer, intent(in)  NVB,
real, dimension(-9:ncel), intent(in)  CF,
real, dimension(-9:ncel), intent(in)  VC,
real, dimension(nvfc), intent(out)  VFLY,
real, intent(in)  AKDif,
real, dimension(nvfc), intent(out)  FV,
real, dimension(nvfc), intent(out)  FY,
real, intent(in)  FTS 
)

Calculate mid-flux values for y dimension with UNO3 scheme.

Parameters
[in]NVAStart number of V-face list.
[in]NVBEnd number of V-face list.
[in]CFTransported variable.
[in]VCVeclocity V-component at cell centre.
[out]VFLYMid-flux V-component on V-face.
[in]AKDifDiffusion coefficient.
[out]FVAdvection Mid-flux on V-face.
[out]FYDiffusion Mid-flux on V-face.
[in]FTSTimestep fraction for sub-timestep.
Author
Jian-Guo Li
Date
03-Mar-2022

Definition at line 1913 of file w3psmcmd.F90.

1913 
1914  USE constants
1915  USE w3gdatmd, ONLY: ncel, mrfct, nvfc, ijkcel, ijkvfc, clatf
1916  USE w3gdatmd, ONLY: ijkcel4
1917  USE w3odatmd, ONLY: ndse, ndst
1918 
1919  IMPLICIT NONE
1920  INTEGER, INTENT( IN):: NVA, NVB
1921  REAL, INTENT( IN):: CF(-9:NCel), VC(-9:NCel), AKDif, FTS
1922  REAL, INTENT(Out):: VFLY(NVFc), FV(NVFc), FY(NVFc)
1923  INTEGER :: i, j, k, L, M, N, ij
1924  REAL:: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6, &
1925  CNST7, CNST8, CNST9
1926 
1927  ! Notice an extra side length L is multiplied to mid-flux to give correct
1928  ! proportion of flux into the cells. This length will be removed by the
1929  ! cell length when the tracer concentration is updated.
1930 
1931  ! Diffusion Fourier no. at sub-time-step, proportional to face size,
1932  ! which is also equal to the sub-time-step factor FTS.
1933  ! CNST0=AKDif*FTS*FTS
1934  ! 2.0 factor to cancel that in gradient CNST5. JGLi08Mar2012
1935  cnst0=akdif*fts*fts*2.0
1936  ! Uniform diffusion coefficient for all sizes. JGLi24Feb2012
1937  ! CNST0=AKDif*MRFct*FTS
1938 
1939 #ifdef W3_OMPG
1940  !$OMP Parallel Default(Shared), Private(j, K, L, M, N), &
1941  !$OMP& Private(CNST,CNST1,CNST2,CNST3,CNST4,CNST5,CNST6,CNST7,CNST8,CNST9)
1942  !$OMP DO
1943 #endif
1944 
1945  DO j=nva, nvb
1946 
1947  ! Select Upstream, Central and Downstream cells
1948  k=ijkvfc(4,j)
1949  l=ijkvfc(5,j)
1950  m=ijkvfc(6,j)
1951  n=ijkvfc(7,j)
1952 
1953  ! Face bounding cell lengths and gradient
1954  cnst2=float( ijkcel4(l) )
1955  cnst3=float( ijkcel4(m) )
1956  cnst5=(cf(m)-cf(l))/( cnst2 + cnst3 )
1957 
1958  ! Courant number in local size-1 cell unit
1959  ! Multiply by multi-resolution time step factor FTS
1960  cnst6=0.5*( vc(l)+vc(m) )*fts
1961  vfly(j) = cnst6
1962 
1963  ! Face size integer and cosine factor.
1964  ! CLATF is defined on V-face for SMC grid. JGLi28Feb2012
1965  cnst8=clatf(j)*float( ijkvfc(3,j) )
1966 
1967  ! For positive velocity case
1968  IF(cnst6 >= 0.0) THEN
1969 
1970  ! Boundary cell y-size is set equal to central cell y-size
1971  ! as y-boundary cell sizes are not proportional to refined
1972  ! inner cells but constant of the base cell y-size, and
1973  ! Use central cell speed for face speed. JGLi06Apr2011
1974  IF( m .LE. 0 ) THEN
1975  vfly(j) = vc(l)*fts
1976  cnst3 = cnst2
1977  ENDIF
1978 
1979  ! Upstream cell size and irregular grid gradient, depending on VFLY.
1980  cnst1=float( ijkcel4(k) )
1981  cnst4=(cf(l)-cf(k))/( cnst2 + cnst1 )
1982 
1983  ! Second order gradient
1984  cnst7 = cnst5 - cnst4
1985  cnst9 = 2.0/( cnst3+cnst2+cnst2+cnst1 )
1986 
1987  ! Use 3rd order scheme
1988  IF( abs(cnst7) .LT. 0.6*cnst9*abs(cf(m)-cf(k)) ) THEN
1989  cnst= cnst5 - ( cnst3+vfly(j) )*cnst7*cnst9/1.5
1990 
1991  ! Use doubled UNO2 scheme
1992  ELSE IF( dble(cnst4)*dble(cnst5) .GT. 0.d0 ) THEN
1993  cnst=sign(2.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1994 
1995  ELSE
1996 
1997  ! Use minimum gradient outside monotonic region
1998  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
1999 
2000  ENDIF
2001 
2002  ! Mid-flux value multiplied by face width and cosine factor
2003  fv(j)=( cf(l) + cnst*(cnst2 - vfly(j)) )*cnst8
2004 
2005  ! For negative velocity case
2006  ELSE
2007 
2008  ! Set boundary cell y-size equal to central cell y-size and
2009  ! Use central cell speed for flux face speed. JGLi06Apr2011
2010  IF( l .LE. 0 ) THEN
2011  vfly(j) = vc(m)*fts
2012  cnst2 = cnst3
2013  ENDIF
2014 
2015  ! Upstream cell size and gradient, depending on VFLY sign.
2016  ! Side gradients for central cell includs 0.5 factor.
2017  cnst1=float( ijkcel4(n) )
2018  cnst4=(cf(n)-cf(m))/( cnst1 + cnst3 )
2019 
2020  ! Second order gradient
2021  cnst7 = cnst4 - cnst5
2022  cnst9 = 2.0/( cnst2+cnst3+cnst3+cnst1 )
2023 
2024  ! Use 3rd order scheme
2025  IF( abs(cnst7) .LT. 0.6*cnst9*abs(cf(n)-cf(l)) ) THEN
2026  cnst= cnst5 + ( cnst2-vfly(j) )*cnst7*cnst9/1.5
2027 
2028  ! Use doubled UNO2 scheme
2029  ELSE IF( dble(cnst4)*dble(cnst5) .GT. 0.d0 ) THEN
2030  cnst=sign(2.0, cnst5)*min( abs(cnst4), abs(cnst5) )
2031 
2032  ELSE
2033 
2034  ! Use minimum gradient outside monotonic region
2035  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
2036 
2037  ENDIF
2038 
2039  ! Mid-flux value multiplied by face width and cosine factor
2040  fv(j)=( cf(m) - cnst*(cnst3 + vfly(j)) )*cnst8
2041 
2042  ENDIF
2043 
2044  ! Diffusion flux by face gradient x DT x face_width x cos(lat)
2045  ! Multiply by multi-resolution time step factor FTS
2046  fy(j)=cnst0*cnst5*cnst8
2047 
2048  END DO
2049 
2050 #ifdef W3_OMPG
2051  !$OMP END DO
2052  !$OMP END Parallel
2053 #endif
2054 
2055  RETURN

References w3gdatmd::clatf, w3gdatmd::ijkcel, w3gdatmd::ijkcel4, w3gdatmd::ijkvfc, w3gdatmd::mrfct, w3gdatmd::ncel, w3odatmd::ndse, w3odatmd::ndst, and w3gdatmd::nvfc.

Referenced by w3psmc().

◆ smcyuno3r()

subroutine w3psmcmd::smcyuno3r ( integer, intent(in)  NVA,
integer, intent(in)  NVB,
real, dimension(-9:ncel), intent(in)  CF,
real, dimension(-9:ncel), intent(in)  VC,
real, dimension(nvfc), intent(out)  VFLY,
real, intent(in)  AKDif,
real, dimension(nvfc), intent(out)  FV,
real, dimension(nvfc), intent(out)  FY 
)

Calculate mid-flux values for y dimension with UNO3.

Parameters
[in]NVAStart number of V-face list.
[in]NVBEnd number of V-face list.
[in]CFTransported variable.
[in]VCVeclocity V-component at cell centre.
[out]VFLYMid-flux V-component on V-face.
[in]AKDifDiffusion coefficient.
[out]FVAdvection Mid-flux on V-face.
[out]FYDiffusion Mid-flux on V-face.
Author
Jian-Guo Li
Date
03-Mar-2022

Definition at line 2205 of file w3psmcmd.F90.

2205 
2206  USE constants
2207  USE w3gdatmd, ONLY: nsea, ny, ncel, nvfc, ijkcel, ijkvfc, clatf
2208  USE w3odatmd, ONLY: ndse, ndst
2209 
2210  IMPLICIT NONE
2211  INTEGER, INTENT( IN):: NVA, NVB
2212  REAL, INTENT( IN):: CF(-9:NCel), VC(-9:NCel), AKDif
2213  REAL, INTENT(Out):: VFLY(NVFc), FV(NVFc), FY(NVFc)
2214  INTEGER :: i, j, k, L, M, N, ij
2215  REAL :: CNST, CNST0, CNST1, CNST2, CNST3, CNST4, CNST5, CNST6, &
2216  CNST7, CNST8, CNST9
2217 
2218  ! Notice an extra side length L is multiplied to mid-flux to give correct
2219  ! proportion of flux into the cells. This length will be removed by the
2220  ! cell length when the tracer concentration is updated.
2221 
2222 #ifdef W3_OMPG
2223  !$OMP Parallel Default(Shared), Private(j, K, L, M, N), &
2224  !$OMP& Private(CNST,CNST4,CNST5,CNST6,CNST7,CNST8,CNST9)
2225  !$OMP DO
2226 #endif
2227 
2228  DO j=nva, nvb
2229 
2230  ! Select Upstream, Central and Downstream cells
2231  k=ijkvfc(4,j)
2232  l=ijkvfc(5,j)
2233  m=ijkvfc(6,j)
2234  n=ijkvfc(7,j)
2235 
2236  ! Central face gradient.
2237  cnst5=(cf(m)-cf(l))
2238 
2239  ! Courant number in basic cell unit as dy is constant
2240  cnst6=0.5*( vc(l)+vc(m) )
2241  vfly(j) = cnst6
2242 
2243  ! Face size integer and cosine factor
2244  ! CLATF is defined on V-face for SMC grid. JGLi28Feb2012
2245  cnst7=clatf(j)*float( ijkvfc(3,j) )
2246 
2247  ! For positive velocity case
2248  IF(cnst6 >= 0.0) THEN
2249 
2250  ! Use central cell speed for flux face speed. JGLi06Apr2011
2251  IF( m .LE. 0 ) vfly(j) = vc(l)
2252 
2253  ! Upstream face gradient, depending on VFLY sign.
2254  cnst4=(cf(l)-cf(k))
2255 
2256  ! Second gradient for 3rd scheme
2257  cnst8=(cf(m)-cf(k))
2258  cnst9=(cnst5-cnst4)
2259 
2260  IF( abs(cnst9) <= 0.6*abs(cnst8) ) THEN
2261  ! Use 3rd order scheme in limited zone, note division by 2 grid sizes
2262  cnst=0.5*cnst5-(1.0+vfly(j))*cnst9/6.0
2263  ELSE IF( dble(cnst4)*dble(cnst5) .GT. 0.d0 ) THEN
2264  ! Use doubled minimum gradient in rest of monotonic region
2265  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
2266  ELSE
2267  ! Use minimum gradient, including 0.5 factor and central sign.
2268  cnst=sign(0.5, cnst5)*min( abs(cnst4), abs(cnst5) )
2269  ENDIF
2270 
2271  ! Mid-flux value multiplied by face width and cosine factor
2272  fv(j)=( cf(l) + cnst*(1.0-vfly(j)) )*cnst7
2273 
2274  ! For negative velocity case
2275  ELSE
2276 
2277  ! Use central cell speed for flux face speed. JGLi06Apr2011
2278  IF( l .LE. 0 ) vfly(j) = vc(m)
2279 
2280  ! Side gradients for upstream face, depending on VFLY sign.
2281  cnst4=(cf(n)-cf(m))
2282 
2283  ! Second gradient for 3rd scheme
2284  cnst8=(cf(n)-cf(l))
2285  cnst9=(cnst4-cnst5)
2286 
2287  IF( abs(cnst9) <= 0.6*abs(cnst8) ) THEN
2288  ! Use 3rd order scheme in limited zone, note division by 2 grid sizes
2289  cnst=0.5*cnst5+(1.0-vfly(j))*cnst9/6.0
2290  ELSE IF( dble(cnst4)*dble(cnst5) .GT. 0.d0 ) THEN
2291  ! Use doubled minimum gradient in rest of monotonic region
2292  cnst=sign(1.0, cnst5)*min( abs(cnst4), abs(cnst5) )
2293  ELSE
2294  ! Use minimum gradient, including 0.5 factor and central sign.
2295  cnst=sign(0.5, cnst5)*min( abs(cnst4), abs(cnst5) )
2296  ENDIF
2297  ! Mid-flux value multiplied by face width and cosine factor
2298  fv(j)=( cf(m) - cnst*(1.0+vfly(j)) )*cnst7
2299 
2300  ENDIF
2301 
2302  ! Diffusion flux by face gradient x DT x face_width x cos(lat)
2303  fy(j)=akdif*cnst5*cnst7
2304 
2305  END DO
2306 
2307 #ifdef W3_OMPG
2308  !$OMP END DO
2309  !$OMP END Parallel
2310 #endif
2311 
2312  RETURN

References w3gdatmd::clatf, w3gdatmd::ijkcel, w3gdatmd::ijkvfc, w3gdatmd::ncel, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nsea, w3gdatmd::nvfc, and w3gdatmd::ny.

Referenced by w3psmc().

◆ w3gathsmc()

subroutine w3psmcmd::w3gathsmc ( integer, intent(in)  ISPEC,
real, dimension(ncel), intent(out)  FIELD 
)

SMC version of W3GATH.

Gather spectral bin information into a propagation field array. Direct copy or communication calls (MPP version).

Remarks
  • The field is extracted but not converted.
  • Array FIELD is not initialized.
  • MPI version requires posing of send and receive calls in W3WAVE to match local calls.
  • MPI version does not require an MPI_TESTALL call for the posted gather operation as MPI_WAITALL is mandatory to reset persistent communication for next time step.
  • MPI version allows only two new pre-fetch postings per call to minimize chances to be slowed down by gathers that are not yet needed, while maximizing the pre-loading during the early (low-frequency) calls to the routine where the amount of calculation needed for proagation is the largest.
Parameters
[in]ISPECSpectral bin considered
[out]FIELDFull field to be propagated
Author
Jian-Guo Li
Date
15 Mar 2011

Definition at line 3185 of file w3psmcmd.F90.

3185  !/
3186  !/ +-----------------------------------+
3187  !/ | WAVEWATCH-III NOAA/NCEP |
3188  !/ | H. L. Tolman |
3189  !/ | FORTRAN 90 |
3190  !/ | Last update : 13-Jun-2006 |
3191  !/ +-----------------------------------+
3192  !/
3193  !/ 04-Jan-1999 : Distributed FORTRAN 77 version. ( version 1.18 )
3194  !/ 13-Jan-2000 : Upgrade to FORTRAN 90 ( version 2.00 )
3195  !/ Major changes to logistics.
3196  !/ 29-Dec-2004 : Multiple grid version. ( version 3.06 )
3197  !/ 13-Jun-2006 : Split STORE in G/SSTORE ( version 3.09 )
3198  !/ 9-Dec-2010 : Adapted for SMC grid propagtion. JGLi
3199  !/
3200  ! 1. Purpose :
3201  !
3202  ! Gather spectral bin information into a propagation field array.
3203  !
3204  ! 2. Method :
3205  !
3206  ! Direct copy or communication calls (MPP version).
3207  !
3208  ! 3. Parameters :
3209  !
3210  ! Parameter list
3211  ! ----------------------------------------------------------------
3212  ! ISPEC Int. I Spectral bin considered.
3213  ! FIELD R.A. O Full field to be propagated.
3214  ! ----------------------------------------------------------------
3215  !
3216  ! 4. Subroutines used :
3217  !
3218  ! Name Type Module Description
3219  ! ----------------------------------------------------------------
3220  ! STRACE Subr. W3SERVMD Subroutine tracing.
3221  !
3222  ! MPI_STARTALL, MPI_WAITALL
3223  ! Subr. mpif.h MPI persistent comm. routines (!/MPI).
3224  ! ----------------------------------------------------------------
3225  !
3226  ! 5. Called by :
3227  !
3228  ! Name Type Module Description
3229  ! ----------------------------------------------------------------
3230  ! W3WAVE Subr. W3WAVEMD Actual wave model routine.
3231  ! ----------------------------------------------------------------
3232  !
3233  ! 6. Error messages :
3234  !
3235  ! None.
3236  !
3237  ! 7. Remarks :
3238  !
3239  ! - The field is extracted but not converted.
3240  ! - Array FIELD is not initialized.
3241  ! - MPI version requires posing of send and receive calls in
3242  ! W3WAVE to match local calls.
3243  ! - MPI version does not require an MPI_TESTALL call for the
3244  ! posted gather operation as MPI_WAITALL is mandatory to
3245  ! reset persistent communication for next time step.
3246  ! - MPI version allows only two new pre-fetch postings per
3247  ! call to minimize chances to be slowed down by gathers that
3248  ! are not yet needed, while maximizing the pre-loading
3249  ! during the early (low-frequency) calls to the routine
3250  ! where the amount of calculation needed for proagation is
3251  ! the largest.
3252  !
3253  ! 8. Structure :
3254  !
3255  ! See source code.
3256  !
3257  ! 9. Switches :
3258  !
3259  ! !/SHRD Switch for message passing method.
3260  ! !/MPI Id.
3261  !
3262  ! !/S Enable subroutine tracing.
3263  ! !/MPIT MPI test output.
3264  !
3265  ! 10. Source code :
3266  !
3267  !/ ------------------------------------------------------------------- /
3268 #ifdef W3_S
3269  USE w3servmd, ONLY: strace
3270 #endif
3271  !/
3272  USE w3gdatmd, ONLY: nspec, nx, ny, nsea, nseal, ncel, mapsf
3273  USE w3wdatmd, ONLY: a => va
3274 #ifdef W3_MPI
3275  USE w3adatmd, ONLY: mpibuf, bstat, ibfloc, isploc, bispl, &
3277  USE w3odatmd, ONLY: ndst, iaproc, naproc
3278 #endif
3279  !/
3280  IMPLICIT NONE
3281  !
3282 #ifdef W3_MPI
3283  include "mpif.h"
3284 #endif
3285  !/
3286  !/ ------------------------------------------------------------------- /
3287  !/ Parameter list
3288  !/
3289  INTEGER, INTENT(IN) :: ISPEC
3290  REAL, INTENT(OUT) :: FIELD(NCel)
3291  !/
3292  !/ ------------------------------------------------------------------- /
3293  !/ Local parameters
3294  !/
3295 #ifdef W3_SHRD
3296  INTEGER :: ISEA, IXY
3297 #endif
3298 #ifdef W3_MPI
3299  INTEGER :: STATUS(MPI_STATUS_SIZE,NSPEC), &
3300  IOFF, IERR_MPI, JSEA, ISEA, &
3301  IXY, IS0, IB0, NPST, J
3302 #endif
3303 #ifdef W3_S
3304  INTEGER, SAVE :: IENT
3305 #endif
3306  !/
3307  !/ ------------------------------------------------------------------- /
3308  !/
3309 #ifdef W3_S
3310  CALL strace (ient, 'W3GATH')
3311 #endif
3312  !
3313  ! FIELD = 0.
3314  !
3315  ! 1. Shared memory version ------------------------------------------ /
3316  !
3317 #ifdef W3_SHRD
3318  DO isea=1, nsea
3319  field(isea) = a(ispec,isea)
3320  END DO
3321  !
3322  RETURN
3323 #endif
3324  !
3325  ! 2. Distributed memory version ( MPI ) ----------------------------- /
3326  ! 2.a Update counters
3327  !
3328 #ifdef W3_MPI
3329  isploc = isploc + 1
3330  ibfloc = ibfloc + 1
3331  IF ( ibfloc .GT. mpibuf ) ibfloc = 1
3332  !
3333  ! 2.b Check status of present buffer
3334  ! 2.b.1 Scatter (send) still in progress, wait to end
3335  !
3336  IF ( bstat(ibfloc) .EQ. 2 ) THEN
3337  ioff = 1 + (bispl(ibfloc)-1)*nrqsg2
3338  IF ( nrqsg2 .GT. 0 ) CALL &
3339  mpi_waitall ( nrqsg2, irqsg2(ioff,2), &
3340  status, ierr_mpi )
3341  bstat(ibfloc) = 0
3342  END IF
3343  !
3344  ! 2.b.2 Gather (recv) not yet posted, post now
3345  !
3346  IF ( bstat(ibfloc) .EQ. 0 ) THEN
3347  bstat(ibfloc) = 1
3348  bispl(ibfloc) = isploc
3349  ioff = 1 + (isploc-1)*nrqsg2
3350  IF ( nrqsg2 .GT. 0 ) CALL &
3351  mpi_startall ( nrqsg2, irqsg2(ioff,1), ierr_mpi )
3352  END IF
3353  !
3354  ! 2.c Put local spectral densities in store
3355  !
3356  DO jsea=1, nseal
3357  gstore(iaproc+(jsea-1)*naproc,ibfloc) = a(ispec,jsea)
3358  END DO
3359  !
3360  ! 2.d Wait for remote spectral densities
3361  !
3362  ioff = 1 + (bispl(ibfloc)-1)*nrqsg2
3363  IF ( nrqsg2 .GT. 0 ) CALL &
3364  mpi_waitall ( nrqsg2, irqsg2(ioff,1), status, ierr_mpi )
3365  !
3366  ! 2.e Convert storage array to field.
3367  !
3368  DO isea=1, nsea
3369  field(isea) = gstore(isea,ibfloc)
3370  END DO
3371  !
3372  ! 2.f Pre-fetch data in available buffers
3373  !
3374  is0 = isploc
3375  ib0 = ibfloc
3376  npst = 0
3377  DO j=1, mpibuf-1
3378  is0 = is0 + 1
3379  IF ( is0 .GT. nsploc ) EXIT
3380  ib0 = 1 + mod(ib0,mpibuf)
3381  IF ( bstat(ib0) .EQ. 0 ) THEN
3382  bstat(ib0) = 1
3383  bispl(ib0) = is0
3384  ioff = 1 + (is0-1)*nrqsg2
3385  IF ( nrqsg2 .GT. 0 ) CALL &
3386  mpi_startall ( nrqsg2, irqsg2(ioff,1), ierr_mpi )
3387  npst = npst + 1
3388  END IF
3389  IF ( npst .GE. 2 ) EXIT
3390  END DO
3391  RETURN
3392 #endif
3393  !
3394  !/ End of W3GATHSMC ----------------------------------------------------- /
3395  !/

References w3adatmd::bispl, w3adatmd::bstat, w3adatmd::gstore, w3odatmd::iaproc, w3adatmd::ibfloc, include(), w3adatmd::irqsg2, w3adatmd::isploc, w3gdatmd::mapsf, w3adatmd::mpibuf, w3odatmd::naproc, w3gdatmd::ncel, w3odatmd::ndst, w3adatmd::nrqsg2, w3gdatmd::nsea, w3gdatmd::nseal, w3gdatmd::nspec, w3adatmd::nsploc, w3gdatmd::nx, w3gdatmd::ny, w3servmd::strace(), and w3wdatmd::va.

Referenced by w3wavemd::w3wave().

◆ w3krtn()

subroutine w3psmcmd::w3krtn ( integer, intent(in)  ISEA,
real, intent(in)  FACTH,
real, intent(in)  FACK,
real, intent(in)  CTHG0,
real, dimension(0:nk+1), intent(in)  CG,
real, dimension(0:nk+1), intent(in)  WN,
real, intent(in)  DEPTH,
real, intent(in)  DDDX,
real, intent(in)  DDDY,
real, dimension(nth), intent(in)  ALFLMT,
real, intent(in)  CX,
real, intent(in)  CY,
real, intent(in)  DCXDX,
real, intent(in)  DCXDY,
real, intent(in)  DCYDX,
real, intent(in)  DCYDY,
real, dimension(0:nk+1), intent(in)  DCDX,
real, dimension(0:nk+1), intent(in)  DCDY,
real, dimension(nspec), intent(inout)  VA 
)

Refraction and great-circle turning by spectral rotation.

Linear interpolation equivalent to 1st order upstream scheme but without restriction on rotation angle. However, refraction is limited towards the depth gradient direction (< 90 degree). Refraction induced spectral shift in the k-space will remain to be advected using the UNO2 scheme.

Parameters
[in]ISEANumber of sea point
[in]FACTHFactor in propagation velocity (th)
[in]FACKFactor in propagation velocity (k)
[in]CTHG0Factor in great circle refraction term
[in]CGLocal group velocities
[in]WNLocal wavenumbers
[in]DEPTHDepth
[in]DDDXDepth x-gradient
[in]DDDYDepth y-gradient
[in]ALFLMTRefraction limiter
[in]CXCurrent x-component
[in]CYCurrent y-component
[in]DCXDXCurrent gradient (dCX/dX)
[in]DCXDYCurrent gradient (dCX/dY)
[in]DCYDXCurrent gradient (dCY/dX)
[in]DCYDYCurrent gradient (dCY/dY)
[in]DCDXPhase speed x-gradient
[in]DCDYPhase speed y-gradient
[in,out]VASpectrum
Author
Jian-Guo Li
Date
06-Jun-2018

Definition at line 969 of file w3psmcmd.F90.

969  !/
970  !/ +------------------------------------+
971  !/ | Spherical Multiple-Cell (SMC) grid |
972  !/ | Refraction and great-cirle turning |
973  !/ | Jian-Guo Li |
974  !/ | First created: 8 Nov 2010 |
975  !/ | Last modified: 06-Jun-2018 |
976  !/ +------------------------------------+
977  !/
978  !/ 08-Nov-2010 : Origination. ( version 1.00 )
979  !/ 10-Jun-2011 : New refraction formulation. ( version 1.10 )
980  !/ 16-Jun-2011 : Add refraction limiter to gradient. ( version 1.20 )
981  !/ 21-Jul-2011 : Old refraction formula + limiter. ( version 1.30 )
982  !/ 26-Jul-2011 : Tidy up refraction schemes. ( version 1.40 )
983  !/ 28-Jul-2011 : Finalise with old refraction. ( version 1.50 )
984  !/ 23-Mar-2016 : Add current option in refraction. ( version 2.30 )
985  !/ 06-Jun-2018 : Add DEBUGDCXDX ( version 6.04 )
986  !/
987  !/
988  ! 1. Purpose :
989  !
990  ! Refraction and great-circle turning by spectral rotation.
991  !
992  ! 2. Method :
993  !
994  ! Linear interpolation equivalent to 1st order upstream scheme
995  ! but without restriction on rotation angle. However, refraction
996  ! is limited towards the depth gradient direction (< 90 degree).
997  ! Refraction induced spectral shift in the k-space will remain
998  ! to be advected using the UNO2 scheme.
999  !
1000  ! 3. Parameters :
1001  !
1002  ! Parameter list
1003  ! ----------------------------------------------------------------
1004  ! ISEA Int. I Number of sea point.
1005  ! FACTH/K Real I Factor in propagation velocity.
1006  ! CTHG0 Real I Factor in great circle refracftion term.
1007  ! MAPxx2 I.A. I Propagation and storage maps.
1008  ! CG R.A. I Local group velocities.
1009  ! WN R.A. I Local wavenumbers.
1010  ! DEPTH R.A. I Depth.
1011  ! DDDx Real I Depth gradients.
1012  ! CX/Y Real I Current components.
1013  ! DCxDx Real I Current gradients.
1014  ! DCDx Real I Phase speed gradients.
1015  ! VA R.A. I/O Spectrum.
1016  ! ----------------------------------------------------------------
1017  !
1018  ! Local variables.
1019  ! ----------------------------------------------------------------
1020  ! DPH2K R.A. 2*Depth*Wave_number_K
1021  ! SNH2K R.A. SINH(2*Depth*Wave_number_K)
1022  ! FDD, FDU, FGC, FCD, FCU
1023  ! R.A. Directionally varying part of depth, current and
1024  ! great-circle refraction terms and of consit.
1025  ! of Ck term.
1026  ! CFLT-K R.A. Propagation velocities of local fluxes.
1027  ! DB R.A. Wavenumber band widths at cell centers.
1028  ! DM R.A. Wavenumber band widths between cell centers and
1029  ! next cell center.
1030  ! Q R.A. Extracted spectrum
1031  ! ----------------------------------------------------------------
1032  !
1033  ! 4. Subroutines used :
1034  !
1035  ! SMCGtCrfr Refraction and GCT rotation in theta.
1036  ! SMCkUNO2 Refraction shift in k-space by UNO2.
1037  ! STRACE Service routine.
1038  !
1039  ! 5. Called by :
1040  !
1041  ! W3WAVE Wave model routine.
1042  !
1043  ! 6. Error messages :
1044  !
1045  ! None.
1046  !
1047  ! 8. Structure :
1048  !
1049  ! -----------------------------------------------------------------
1050  ! 1. Preparations
1051  ! a Initialize arrays
1052  ! b Set constants and counters
1053  ! 2. Point preparations
1054  ! a Calculate SNH2K
1055  ! b Extract spectrum
1056  ! 3. Refraction velocities
1057  ! a Filter level depth reffraction.
1058  ! b Depth refratcion velocity.
1059  ! c Current refraction velocity.
1060  ! 4. Wavenumber shift velocities
1061  ! a Prepare directional arrays
1062  ! b Calcuate velocity.
1063  ! 5. Propagate.
1064  ! 6. Store results.
1065  ! -----------------------------------------------------------------
1066  !
1067  ! 9. Switches :
1068  !
1069  ! !/S Enable subroutine tracing.
1070  ! !/T Enable general test output.
1071  !
1072  ! 10. Source code :
1073  !
1074  !/ ------------------------------------------------------------------- /
1075  USE constants
1076  USE w3gdatmd, ONLY: nk, nth, nspec, sig, dsip, ecos, esin, &
1077  ec2, esc, es2, flcth, flck, ctmax, dth
1078  USE w3adatmd, ONLY: itime
1079  USE w3idatmd, ONLY: flcur
1080  USE w3odatmd, ONLY: ndse, ndst
1081 #ifdef W3_S
1082  USE w3servmd, ONLY: strace
1083 #endif
1084  !/
1085  IMPLICIT NONE
1086  !/
1087  !/ ------------------------------------------------------------------- /
1088  !/ Parameter list
1089  !/
1090  INTEGER, INTENT(IN) :: ISEA
1091 #ifdef W3_S
1092  INTEGER, SAVE :: IENT = 0
1093 #endif
1094  REAL, INTENT(IN) :: FACTH, FACK, CTHG0, CG(0:NK+1), &
1095  WN(0:NK+1), DEPTH, DDDX, DDDY, &
1096  ALFLMT(NTH), CX, CY, DCXDX, DCXDY, &
1097  DCYDX, DCYDY, DCDX(0:NK+1), DCDY(0:NK+1)
1098  REAL, INTENT(INOUT) :: VA(NSPEC)
1099  !/
1100  !/ ------------------------------------------------------------------- /
1101  !/ Local parameters
1102  !/
1103  INTEGER :: ITH, IK, ISP
1104  REAL :: FGC, FKD, FKS, FRK(NK), FRG(NK), DDNorm(NTH), &
1105  FKC(NTH), VQ(NSPEC), VCFLT(NSPEC), DEPTH30, &
1106  DB(0:NK+1), DM(-1:NK+1), CFLK(NTH,0:NK), &
1107  !Li For new refraction scheme using Cg. JGLi26Jul2011
1108  ! DPH2K(0:NK+1), SNH2K(0:NK+1)
1109  !Li For old refraction scheme using phase speed. JGLi26Jul2011
1110  sigsnh(0:nk+1)
1111  !/
1112  !/ ------------------------------------------------------------------- /
1113  !/
1114 #ifdef W3_S
1115  CALL strace (ient, 'W3KRTN')
1116 #endif
1117  !
1118  ! 1. Preparation for point ------------------------------------------ *
1119  ! Array with partial derivative of sigma versus depth
1120  !Li Use of minimum depth 30 m for refraction factor. JGLi12Feb2014
1121  depth30=max(30.0, depth)
1122 
1123  DO ik=0, nk+1
1124  !Li For old refraction scheme using phase speed. JGLi8Jun2011
1125  ! DPH2K(IK) = 2.0*WN(IK)*DEPTH
1126  ! SNH2K(IK) = SINH( DPH2K(IK) )
1127  !Li For new refraction scheme using Cg. JGLi3Jun2011
1128  !! SIGSNH(IK) = SIG(IK)/SINH(2.0*WN(IK)*DEPTH)
1129  !!AC Replacing SIGSINH with a delimiter to prevent the SINH value from
1130  !!AC becoming significantly large. Right now set to a max around 1E21
1131  ! SIGSNH(IK) = SIG(IK)/SINH(MIN(2.0*WN(IK)*DEPTH,50.0))
1132  !Li Refraction factor uses minimum depth of 30 m. JGLi12Feb2014
1133  sigsnh(ik) = sig(ik)/sinh(min(2.0*wn(ik)*depth30,50.0))
1134  END DO
1135  !
1136  ! 2. Extract spectrum without mapping
1137  !
1138  vq = va
1139 
1140  ! 3. Refraction velocities ------------------------------------------ *
1141  !
1142  !
1143  IF ( flcth ) THEN
1144  !
1145  ! 3.a Set slope filter for depth refraction
1146  !
1147  !Li Lift theta-refraction limit and use new formulation. 25 Nov 2010
1148  !Li FACTH = DTG / DTH / REAL(NTLOC), CTHG0 = - TAN(DERA*Y) / RADIUS
1149  fgc = facth * cthg0
1150  !
1151  DO ik=1, nk
1152  !Li New refraction formulation using Cg only. JGLi3Jun2011
1153  ! FRK(IK) = FACTH*2.0*SIG(IK)*(1.-DEPTH*SIG(IK)*SIG(IK)/GRAV) &
1154  ! & /(DPH2K(IK)+SNH2K(IK))
1155  !Li Old refraction formulation using phase speed. JGLi8Jun2011
1156  frk(ik) = facth * sigsnh(ik)
1157  !Li
1158  frg(ik) = fgc * cg(ik)
1159  END DO
1160  !
1161  !Li Current induced refraction stored in FKC. JGLi30Mar2016
1162  IF ( flcur ) THEN
1163  DO ith=1, nth
1164  !Li Put a CTMAX limit on current theta rotation. JGLi02Mar2017
1165  ! FKC(ITH) = FACTH*( DCYDX*ES2(ITH) - DCXDY*EC2(ITH) + &
1166  fgc = facth*( dcydx*es2(ith) - dcxdy*ec2(ith) + &
1167  (dcxdx - dcydy)*esc(ith) )
1168  fkc(ith) = sign( min(abs(fgc), ctmax), fgc )
1169  END DO
1170  ELSE
1171  fkc(:)=0.0
1172  END IF
1173  !
1174  ! 3.b Depth refraction and great-circle turning.
1175  !
1176  DO ith=1, nth
1177  ddnorm(ith)=esin(ith)*dddx-ecos(ith)*dddy
1178  DO ik=1, nk
1179  isp = (ik-1)*nth + ith
1180  !Li Apply depth gradient limited refraction, current and GCT term
1181  vcflt(isp)=frg(ik)*ecos(ith) + fkc(ith) + &
1182  sign( min(abs(frk(ik)*ddnorm(ith)), alflmt(ith)), &
1183  !Li For new refraction scheme using Cg. JGLi26Jul2011
1184  ! FRK(IK)*DDNorm(ITH) )
1185  !Li For old refraction scheme using phase speed. JGLi26Jul2011
1186  ddnorm(ith) )
1187  END DO
1188  END DO
1189 
1190  END IF
1191  !
1192  ! 4. Wavenumber shift velocities due to current refraction ---------- *
1193  !
1194  IF ( flck ) THEN
1195  !
1196  ! 4.a Directionally dependent part
1197  !
1198  DO ith=1, nth
1199  !Li Depth induced refraction is suspended as it is absorbed in
1200  !Li the fixed frequency bin used for wave spectrum. JGLi30Mar2016
1201  ! FKC(ITH) = ( ECOS(ITH)*DDDX + ESIN(ITH)*DDDY )
1202  fkc(ith) = -dcxdx*ec2(ith) -dcydy*es2(ith) &
1203  -(dcxdy + dcydx)*esc(ith)
1204  END DO
1205  fkd = cx*dddx + cy*dddy
1206  !
1207  ! 4.b Band widths
1208  !
1209  !Li Cell and side indices for k-dimension are arranged as
1210  ! Cell: | -1 | 0 | 1 | 2 | ... | NK | NK+1 | NK+2 |
1211  ! Side: -1 0 1 2 ... NK NK+1
1212  !Li DSIP = SIG(K+1) - SIG(K), radian frequency increment
1213  !
1214  DO ik=0, nk
1215  db(ik) = dsip(ik) / cg(ik)
1216  dm(ik) = wn(ik+1) - wn(ik)
1217  END DO
1218  db(nk+1) = dsip(nk+1) / cg(nk+1)
1219  dm(nk+1) = dm(nk)
1220  dm( -1) = dm( 0)
1221 
1222  ! 4.c Courant number of k-velocity without dividing by dk
1223  !!Li FACK = DTG / REAL(NTLOC)
1224  !
1225  DO ik=0, nk
1226  !Li For new refraction scheme using Cg. JGLi3Jun2011
1227  ! FKS = - FACK*WN(IK)*SIG(IK)/SNH2K(IK)
1228  !Li Old refraction formulation using phase speed. JGLi8Jun2011
1229  ! FKS = - FACK*WN(IK)*SIGSNH(IK)
1230  !Li Current induced k-shift. JGLi30Mar2016
1231  fks = max( 0.0, cg(ik)*wn(ik)-0.5*sig(ik) )*fkd / &
1232  ( depth30*cg(ik) )
1233  DO ith=1, nth
1234  cflk(ith,ik) = fack*( fks + fkc(ith)*wn(ik) )
1235  END DO
1236  END DO
1237  !Li No CFL limiter is required here as it is applied in SMCkUNO2.
1238  !
1239  END IF
1240  !
1241  ! 5. Propagate ------------------------------------------------------ *
1242  !
1243  IF ( mod(itime,2) .EQ. 0 ) THEN
1244  IF ( flck ) THEN
1245  !!Li Refraction caused k-space shift.
1246  CALL smckuno2(cflk, vq, db, dm)
1247  END IF
1248  IF ( flcth ) THEN
1249  !!Li GCT and refraction by rotation in theta direction.
1250  CALL smcgtcrfr(vcflt, vq)
1251  END IF
1252  ELSE
1253  IF ( flcth ) THEN
1254  !!Li GCT and refraction by rotation in theta direction.
1255  CALL smcgtcrfr(vcflt, vq)
1256  END IF
1257  IF ( flck ) THEN
1258  !!Li Refraction caused k-space shift.
1259  CALL smckuno2(cflk, vq, db, dm)
1260  END IF
1261  END IF
1262  !
1263  ! 6. Store reults --------------------------------------------------- *
1264  !
1265  va = vq
1266  !
1267  RETURN
1268  !
1269  !/ End of W3KRTN ----------------------------------------------------- /
1270  !/

References w3gdatmd::ctmax, w3gdatmd::dsip, w3gdatmd::dth, w3gdatmd::ec2, w3gdatmd::ecos, w3gdatmd::es2, w3gdatmd::esc, w3gdatmd::esin, w3gdatmd::flck, w3gdatmd::flcth, w3idatmd::flcur, w3adatmd::itime, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nk, w3gdatmd::nspec, w3gdatmd::nth, w3gdatmd::sig, smcgtcrfr(), smckuno2(), and w3servmd::strace().

Referenced by w3wavemd::w3wave().

◆ w3psmc()

subroutine w3psmcmd::w3psmc ( integer, intent(in)  ISP,
real, intent(in)  DTG,
real, dimension(nsea), intent(inout)  VQ 
)

Propagation in phyiscal space for a given spectral component.

Unstructured SMC grid, point-oriented face and cell loops. UNO2 advection scheme and isotropic FTCS diffusion scheme

Parameters
[in]ISPNumber of spectral bin (IK-1)*NTH+ITH
[in]DTGTotal time step.
[in,out]VQField to propagate.
Author
Jian-Guo Li
Date
18 Apr 2018

Definition at line 137 of file w3psmcmd.F90.

137  !/
138  !/ +------------------------------------+
139  !/ | Spherical Multiple-Cell (SMC) grid |
140  !/ | Advection and diffusion sub. |
141  !/ | First created: JG Li 8 Nov 2010 |
142  !/ | Last modified: JG Li 18 Apr 2018 |
143  !/ +------------------------------------+
144  !/
145  !/ 08-Nov-2010 : Origination. JGLi ( version 1.00 )
146  !/ 16-Dec-2010 : Check U/V CFL values. JGLi ( version 1.10 )
147  !/ 18-Mar-2011 : Check MPI communication. JGLi ( version 1.20 )
148  !/ 16-May-2011 : Tidy up diagnosis lines. JGLi ( version 1.30 )
149  !/ 4 Nov-2011 : Separate x and y obstruc. JGLi ( version 1.40 )
150  !/ 5 Jan-2012 : Multi-resolution SMC grid. JGLi ( version 1.50 )
151  !/ 2 Feb-2012 : Separate single multi adv. JGLi ( version 1.60 )
152  !/ 6 Mar-2012 : Minor adjustments of CLATF. JGLi ( version 1.70 )
153  !/ 12 Feb-2012 : Remove net flux bug. JGLi ( version 1.80 )
154  !/ 16 Sep-2013 : Add Arctic part. JGLi ( version 2.00 )
155  !/ 3 Sep-2015 : Gradient, UNO3 and Average. JGLi ( version 2.10 )
156  !/ 26 Feb-2016 : Update boundary spectra. JGLi ( version 2.20 )
157  !/ 23 Mar-2016 : Add current option. JGLi ( version 2.30 )
158  !/ 18 Apr-2018 : Refined sub-grid blocking. JGLi ( version 2.40 )
159  !/
160  ! 1. Purpose :
161  !
162  ! Propagation in phyiscal space for a given spectral component.
163  !
164  ! 2. Method :
165  !
166  ! Unstructured SMC grid, point-oriented face and cell loops.
167  ! UNO2 advection scheme and isotropic FTCS diffusion scheme.
168  !
169  ! 3. Parameters :
170  !
171  ! Parameter list
172  ! ----------------------------------------------------------------
173  ! ISP Int. I Number of spectral bin (IK-1)*NTH+ITH
174  ! FACX/Y Real I Factor in propagation velocity (1 or 0 *DT/DX)
175  ! DTG Real I Total time step.
176  ! MAPSTA I.A. I Grid point status map.
177  ! MAPFS I.A. I Storage map.
178  ! VQ R.A. I/O Field to propagate.
179  ! ----------------------------------------------------------------
180  !
181  ! Local variables.
182  ! ----------------------------------------------------------------
183  ! NTLOC Int Number of local time steps.
184  ! DTLOC Real Local propagation time step.
185  ! CGD Real Deep water group velocity.
186  ! DSSD, DNND Deep water diffusion coefficients.
187  ! ULCFLX R.A. Local courant numbers in 'x' (norm. velocities)
188  ! VLCFLY R.A. Id. in 'y'.
189  ! CXTOT R.A. Propagation velocities in physical space.
190  ! CYTOT R.A.
191  ! DFRR Real Relative frequency increment.
192  ! DX0I Real Inverted grid incremenent in meters (longitude, eq.).
193  ! DY0I Real Inverted grid incremenent in meters (latitude).
194  ! ----------------------------------------------------------------
195  !
196  ! 4. Subroutines used :
197  !
198  ! See module documentation.
199  !
200  ! 5. Called by :
201  !
202  ! Name Type Module Description
203  ! ----------------------------------------------------------------
204  ! W3WAVE Subr. W3WAVEMD Wave model routine.
205  ! ---------------------------------------------------------------
206  !
207  ! 6. Error messages :
208  !
209  ! 7. Remarks :
210  !
211  ! 8. Structure :
212  !
213  ! ---------------------------------------------
214  ! 1. Preparations
215  ! a Set constants
216  ! b Initialize arrays
217  ! 2. Prepare arrays
218  ! a Velocities and 'Q'
219  ! b diffusion coefficients
220  ! 3. Loop over sub-steps
221  ! ----------------------------------------
222  ! a Propagate
223  ! b Update boundary conditions
224  ! c Diffusion correction
225  ! ----------------------------------------
226  ! 4. Store Q field in spectra
227  ! ---------------------------------------------
228  !
229  ! 9. Switches :
230  !
231  ! !/MGP Correct for motion of grid.
232  !
233  ! !/TDYN Dynamic increase of DTME
234  ! !/DSS0 Disable diffusion in propagation direction
235  ! !/XW0 Propagation diffusion only.
236  ! !/XW1 Growth diffusion only.
237  !
238  ! !/S Enable subroutine tracing.
239  !
240  ! !/T Enable general test output.
241  ! !/T1 Dump of input field and fluxes.
242  ! !/T2 Dump of output field.
243  !
244  ! 10. Source code :
245  !
246  !/ ------------------------------------------------------------------- /
247  USE constants
248  !
249  USE w3timemd, ONLY: dsec21
250  !
251  USE w3gdatmd, ONLY: nk, nth, dth, xfr, esin, ecos, sig, nx, ny, &
252  nsea, sx, sy, mapsf, funo3, fverg, &
253  ijkcel, ijkufc, ijkvfc, ncel, nufc, nvfc, &
254  ijkcel3, ijkcel4, &
256  nlvcel, nlvufc, nlvvfc, nrlv, mrfct, &
258  USE w3gdatmd, ONLY: nglo, angarc, arctc
259  USE w3wdatmd, ONLY: time
260  USE w3adatmd, ONLY: cg, wn, u10, cx, cy, atrnx, atrny, itime
261  !
262  USE w3idatmd, ONLY: flcur
263  USE w3odatmd, ONLY: ndse, ndst, flbpi, nbi, tbpi0, tbpin, &
264  isbpi, bbpi0, bbpin
265  !
266 #ifdef W3_S
267  USE w3servmd, ONLY: strace
268 #endif
269  !/
270  IMPLICIT NONE
271  !/
272  !/ ------------------------------------------------------------------- /
273  !/ Parameter list
274  !/
275  INTEGER, INTENT(IN) :: ISP
276  REAL, INTENT(IN) :: DTG
277  REAL, INTENT(INOUT) :: VQ(NSEA)
278  !/
279  !/ ------------------------------------------------------------------- /
280  !/ Local parameters
281  !/
282  INTEGER :: ITH, IK, NTLOC, ITLOC, ISEA, IXY, &
283  IY, IY0, IP, IBI, LvR
284  INTEGER :: i, j, k, L, M, N, LL, MM, NN, LMN, &
285  iuf, juf, ivf, jvf, icl, jcl
286 #ifdef W3_S
287  INTEGER, SAVE :: IENT = 0
288 #endif
289  REAL :: CG0, CGA, CGN, CGX, CGY, FMR, RD1, &
290  RD2, CXMIN, CXMAX, CYMIN, CYMAX, &
291  CXC, CYC, DTLDX, DTLDY
292  REAL :: DTLOC, CGCOS, CGSIN, FUTRN, FVTRN, &
293  DFRR, DX0I, DY0I, CGD, DSSD, &
294  DNND, DCELL, XWIND, TFAC, DSS, DNN
295  REAL :: PCArea, ARCTH
296  LOGICAL :: YFIRST
297  !/
298  !/ Automatic work arrays
299  !
300  REAL, Dimension(-9:NCel) :: FCNt, AFCN, BCNt, UCFL, VCFL, CQ, &
301  CQA, CXTOT, CYTOT
302  REAL, Dimension( NUFc) :: FUMD, FUDIFX, ULCFLX
303  REAL, Dimension( NVFc) :: FVMD, FVDIFY, VLCFLY
304  !/
305  !/ ------------------------------------------------------------------- /
306  !/
307 #ifdef W3_S
308  CALL strace (ient, 'W3PSMC')
309 #endif
310  !
311  ! 1. Preparations --------------------------------------------------- *
312 
313  !!Li Spectral bin direction and frequency indices
314  ith = 1 + mod(isp-1,nth)
315  ik = 1 + (isp-1)/nth
316 
317  !!Li Maximum group speed for 1st and the transported frequency bin
318  !!Li A factor of 1.2 is added to account for the shallow water peak.
319  cg0 = 0.6 * grav / sig(1)
320  cga = 0.6 * grav / sig(ik)
321 
322  !!Li Maximum group speed for given spectral bin. First bin speed is
323  !!Li used to avoid zero speed component.
324  ! CGX = ABS( CGA * ECOS(ITH) )
325  ! CGY = ABS( CGA * ESIN(ITH) )
326  cgx = cga * ecos(ith)
327  cgy = cga * esin(ith)
328 
329  !!Li Add maximum current components to maximum group components.
330  IF ( flcur ) THEN
331  cxmin = minval( cx(1:nsea) )
332  cxmax = maxval( cx(1:nsea) )
333  cymin = minval( cy(1:nsea) )
334  cymax = maxval( cy(1:nsea) )
335  IF ( abs(cgx+cxmin) .GT. abs(cgx+cxmax) ) THEN
336  cgx = cgx + cxmin
337  ELSE
338  cgx = cgx + cxmax
339  END IF
340  IF ( abs(cgy+cymin) .GT. abs(cgy+cymax) ) THEN
341  cgy = cgy + cymin
342  ELSE
343  cgy = cgy + cymax
344  END IF
345  cxc = max( abs(cxmin) , abs(cxmax) )
346  cyc = max( abs(cymin) , abs(cymax) )
347  ELSE
348  cxc = 0.
349  cyc = 0.
350  END IF
351 
352  !!Li Base-cell grid lenth at Equator (size-4 on SMC625 grid).
353  dx0i = 1.0/(sx * dera * radius)
354  dy0i = 1.0/(sy * dera * radius)
355 
356  !!Li Miminum time step determined by Courant number < 0.8
357  !!Li Note, minimum x grid length is half the Equator value.
358  !!Li Minimum time step should not be less than sub w3init requirement,
359  !!Li where IAPPRO array is initialised for propagation parallization.
360  cgn = 0.9999 * max( abs(cgx), abs(cgy), cxc, cyc, 0.001*cg0 )
361  dtloc = dtcfl*cg0/cgn
362  ntloc = 1 + int(dtg/dtloc - 0.001)
363  dtloc = dtg / real(ntloc)
364 
365  !!Li Group speed component common factors, FACX=DTG*DX0I
366  !!Li FACX and FACY are evaluated here directly. JGLi16Jan2013
367  ! CGCOS = FACX * ECOS(ITH) / REAL(NTLOC)
368  ! CGSIN = FACY * ESIN(ITH) / REAL(NTLOC)
369  cgcos = ecos(ith)
370  cgsin = esin(ith)
371  dtldx = dtloc * dx0i
372  dtldy = dtloc * dy0i
373  !
374  yfirst = mod(itime,2) .EQ. 0
375  !
376  !Li Homogenous diffusion Fourier number DNND and DSSD will be used.
377  !Li They have to be divided by base-cell size for size-1 stability.
378  !Li So they are equivalent to the Fourier number in size-1 cell at
379  !Li the sub-time step DTLOC/MRFct.
380  IF ( dtms .GT. 0. ) THEN
381  dfrr = xfr - 1.
382  cgd = 0.5 * grav / sig(ik)
383  dnn = ((dth*cgd)**2)*dtms / 12.
384  dnnd = dnn*dtloc*(dx0i*dx0i)
385  dssd = dnn*dtloc*(dy0i*dy0i)
386  ELSE
387  dssd = 0.0
388  dnnd = 0.0
389  END IF
390  !
391  ! 1.b Initialize arrays
392  !
393 #ifdef W3_T
394  WRITE (ndst,9010)
395 #endif
396  !
397  ulcflx = 0.
398  vlcfly = 0.
399 
400  !Li Pass spectral element VQ to CQ and define size-1 cell CFL
401 #ifdef W3_OMPG
402  !$OMP Parallel DO Private(ISEA)
403 #endif
404  DO isea=1, nsea
405  !Li Transported variable is divided by CG as in WW3.
406  cq(isea) = vq(isea)/cg(ik,isea)
407  !Li Resetting NaNQ VQ to zero if any. JGLi18Mar2013
408  IF( .NOT. (cq(isea) .EQ. cq(isea)) ) cq(isea) = 0.0
409  END DO
410 #ifdef W3_OMPG
411  !$OMP END Parallel DO
412 #endif
413 
414  !Li Add current components if any to wave velocity.
415  IF ( flcur ) THEN
416 #ifdef W3_OMPG
417  !$OMP Parallel DO Private(ISEA)
418 #endif
419  DO isea=1, nsea
420  cxtot(isea) = (cgcos * cg(ik,isea) + cx(isea))
421  cytot(isea) = (cgsin * cg(ik,isea) + cy(isea))
422  ENDDO
423 #ifdef W3_OMPG
424  !$OMP END Parallel DO
425 #endif
426  ELSE
427  !Li No current case use group speed only.
428 #ifdef W3_OMPG
429  !$OMP Parallel DO Private(ISEA)
430 #endif
431  DO isea=1, nsea
432  cxtot(isea) = cgcos * cg(ik,isea)
433  cytot(isea) = cgsin * cg(ik,isea)
434  END DO
435 #ifdef W3_OMPG
436  !$OMP END Parallel DO
437 #endif
438  !Li End of IF( FLCUR ) block.
439  ENDIF
440 
441  !Li Arctic cell velocity components need to be rotated
442  !Li back to local east referenence system for propagation.
443  IF( arctc ) THEN
444  DO isea=nglo+1, nsea
445  arcth = angarc(isea-nglo)*dera
446  cxc = cxtot(isea)*cos(arcth) + cytot(isea)*sin(arcth)
447  cyc = cytot(isea)*cos(arcth) - cxtot(isea)*sin(arcth)
448  cxtot(isea) = cxc
449  cytot(isea) = cyc
450  END DO
451  !Li Polar cell area factor for V-flux update
452  pcarea = dy0i/(mrfct*pi*dx0i*float(ijkcel(4,nsea)))
453  !Li V-component is reset to zero for Polar cell as direction
454  !Li is undefined there.
455  cytot(nsea) = 0.0
456  ENDIF
457 
458 
459  !Li Convert velocity components into CFL factors.
460 #ifdef W3_OMPG
461  !$OMP Parallel DO Private(ISEA)
462 #endif
463  DO isea=1, nsea
464  ucfl(isea) = dtldx*cxtot(isea)/clats(isea)
465  vcfl(isea) = dtldy*cytot(isea)
466  ENDDO
467 #ifdef W3_OMPG
468  !$OMP END Parallel DO
469 #endif
470 
471  !Li Initialise boundary cell CQ and Velocity values.
472  cq(-9:0)=0.0
473  ucfl(-9:0)=0.0
474  vcfl(-9:0)=0.0
475  !
476  ! 3. Loop over frequency-dependent sub-steps -------------------------*
477  !
478  DO itloc=1, ntloc
479  !
480  ! Initialise net flux arrays.
481  fcnt(-9:ncel) = 0.0
482  afcn(-9:ncel) = 0.0
483  bcnt(-9:ncel) = 0.0
484  !
485  ! Single-resolution SMC grid uses regular grid advection with
486  ! partial blocking enabled when NRLv = 1
487  IF ( nrlv .EQ. 1 ) THEN
488  IF( funo3 ) THEN
489  ! Use 3rd order UNO3 scheme. JGLi20Aug2015
490  CALL smcxuno3r(1, nufc, cq, ucfl, ulcflx, dnnd, fumd, fudifx)
491  ELSE
492  ! Call SMCxUNO2 to calculate MFx value
493  CALL smcxuno2r(1, nufc, cq, ucfl, ulcflx, dnnd, fumd, fudifx)
494  ENDIF
495 
496  ! Store conservative flux in FCNt advective one in AFCN
497 #ifdef W3_OMPG
498  !$OMP Parallel DO Private(i, M, N, FUTRN)
499 #endif
500  DO i=1, nufc
501  m=ijkufc5(i)
502  n=ijkufc6(i)
503  futrn = fumd(i)*ulcflx(i) - fudifx(i)
504 
505  !! Add sub-grid transparency for input flux update. JGLi16May2011
506  !! Transparency is also applied on diffusion flux. JGLi12Mar2012
507  !! Replace CRITICAL with ATOMIC. JGLi15Jan2019
508  !! !$OMP CRITICAL
509  !! Remove boundary cell flux update or M N > 0. JGLi28Mar2019
510  IF( m > 0 ) THEN
511  IF( (ctrnx(m)+ctrnx(n)) .GE. 1.96 ) THEN
512 #ifdef W3_OMPG
513  !$OMP ATOMIC
514 #endif
515  fcnt(m) = fcnt(m) - futrn
516  ELSE IF( ulcflx(i) .GE. 0.0 ) THEN
517 #ifdef W3_OMPG
518  !$OMP ATOMIC
519 #endif
520  fcnt(m) = fcnt(m) - futrn*ctrnx(m)
521  ELSE
522 #ifdef W3_OMPG
523  !$OMP ATOMIC
524 #endif
525  fcnt(m) = fcnt(m) - futrn*ctrnx(n)*ctrnx(m)
526  ENDIF
527  ! Also divided by another cell length as UCFL is in basic unit.
528 #ifdef W3_OMPG
529  !$OMP ATOMIC
530 #endif
531  ! ChrisB: Re-arranged the RHS term below to make it
532  ! valid for OMP ATMOIC directive.
533  afcn(m) = afcn(m) - (fumd(i)*ucfl(m) - fudifx(i))
534  ENDIF
535 
536  IF( n > 0 ) THEN
537  IF( (ctrnx(m)+ctrnx(n)) .GE. 1.96 ) THEN
538 #ifdef W3_OMPG
539  !$OMP ATOMIC
540 #endif
541  fcnt(n) = fcnt(n) + futrn
542  ELSE IF( ulcflx(i) .GE. 0.0 ) THEN
543 #ifdef W3_OMPG
544  !$OMP ATOMIC
545 #endif
546  fcnt(n) = fcnt(n) + futrn*ctrnx(m)*ctrnx(n)
547  ELSE
548 #ifdef W3_OMPG
549  !$OMP ATOMIC
550 #endif
551  fcnt(n) = fcnt(n) + futrn*ctrnx(n)
552  ENDIF
553  ! Also divided by another cell length as UCFL is in basic unit.
554 #ifdef W3_OMPG
555  !$OMP ATOMIC
556 #endif
557  afcn(n) = afcn(n) + (fumd(i)*ucfl(n) - fudifx(i))
558  ENDIF
559  !! !$OMP END CRITICAL
560 
561  ENDDO
562 #ifdef W3_OMPG
563  !$OMP END Parallel DO
564 #endif
565 
566  ! Store conservative update in CQA and advective update in CQ
567  ! The side length in MF value has to be cancelled with cell length
568  ! Note ULCFLX has been divided by the cell size inside SMCxUNO2.
569 #ifdef W3_OMPG
570  !$OMP Parallel DO Private(n)
571 #endif
572  DO n=1, nsea
573  cqa(n)=cq(n) + fcnt(n)/float(ijkcel3(n))
574  cq(n)=cq(n) + afcn(n)/float(ijkcel3(n))
575  ENDDO
576 #ifdef W3_OMPG
577  !$OMP END Parallel DO
578 #endif
579 
580  ! Call advection subs.
581  IF( funo3 ) THEN
582  ! Use 3rd order UNO3 scheme. JGLi20Aug2015
583  CALL smcyuno3r(1, nvfc, cq, vcfl, vlcfly, dssd, fvmd, fvdify)
584  ELSE
585  ! Call SMCyUNO2 to calculate MFy value
586  CALL smcyuno2r(1, nvfc, cq, vcfl, vlcfly, dssd, fvmd, fvdify)
587  ENDIF
588 
589 #ifdef W3_OMPG
590  !$OMP Parallel DO Private(j, M, N, FVTRN)
591 #endif
592  DO j=1, nvfc
593  m=ijkvfc5(j)
594  n=ijkvfc6(j)
595  fvtrn = fvmd(j)*vlcfly(j) - fvdify(j)
596 
597  !! Add sub-grid transparency for input flux update. JGLi16May2011
598  !! Transparency is also applied on diffusion flux. JGLi12Mar2012
599  !! Replace CRITICAL with ATOMIC. JGLi15Jan2019
600  !! !$OMP CRITICAL
601  !! Remove boundary cell flux update or M N > 0. JGLi28Mar2019
602  IF( m > 0 ) THEN
603  IF( (ctrny(m)+ctrny(n)) .GE. 1.96 ) THEN
604 #ifdef W3_OMPG
605  !$OMP ATOMIC
606 #endif
607  bcnt(m) = bcnt(m) - fvtrn
608  ELSE IF( vlcfly(j) .GE. 0.0 ) THEN
609 #ifdef W3_OMPG
610  !$OMP ATOMIC
611 #endif
612  bcnt(m) = bcnt(m) - fvtrn*ctrny(m)
613  ELSE
614 #ifdef W3_OMPG
615  !$OMP ATOMIC
616 #endif
617  bcnt(m) = bcnt(m) - fvtrn*ctrny(n)*ctrny(m)
618  ENDIF
619  ENDIF
620  IF( n > 0 ) THEN
621  IF( (ctrny(m)+ctrny(n)) .GE. 1.96 ) THEN
622 #ifdef W3_OMPG
623  !$OMP ATOMIC
624 #endif
625  bcnt(n) = bcnt(n) + fvtrn
626  ELSE IF( vlcfly(j) .GE. 0.0 ) THEN
627 #ifdef W3_OMPG
628  !$OMP ATOMIC
629 #endif
630  bcnt(n) = bcnt(n) + fvtrn*ctrny(m)*ctrny(n)
631  ELSE
632 #ifdef W3_OMPG
633  !$OMP ATOMIC
634 #endif
635  bcnt(n) = bcnt(n) + fvtrn*ctrny(n)
636  ENDIF
637  ENDIF
638  !! !$OMP END CRITICAL
639  ENDDO
640 #ifdef W3_OMPG
641  !$OMP END Parallel DO
642 #endif
643 
644  ! Store conservative update of CQA in CQ
645  ! The v side length in MF value has to be cancelled with cell length
646  !! One cosine factor is also needed to be divided for SMC grid
647 #ifdef W3_OMPG
648  !$OMP Parallel DO Private(n)
649 #endif
650  DO n=1, nsea
651  cq(n)=cqa(n) + bcnt(n)/( clats(n)*float(ijkcel3(n)) )
652  ENDDO
653 #ifdef W3_OMPG
654  !$OMP END Parallel DO
655 #endif
656  ! Polar cell needs a special area factor, one-level case.
657  IF( arctc ) cq(nsea) = cqa(nsea) + bcnt(nsea)*pcarea
658 
659  ! End of single-resolution advection and diffusion.
660  ELSE
661 
662  ! Multi-resolution SMC grid uses irregular grid advection scheme
663  ! without partial blocking when NRLv > 1
664  !
665  ! 3.a Multiresolution sub-steps depend on refined levels MRFct
666  DO lmn = 1, mrfct
667  !
668  ! 3.b Loop over all levels, starting from the finest level.
669  DO ll= 1, nrlv
670 
671  ! Cell size of this level
672  lvr=2**(ll - 1)
673  fmr=float( lvr )
674  !
675  ! 3.c Calculate this level only if size is factor of LMN
676  IF( mod(lmn, lvr) .EQ. 0 ) THEN
677  !
678  ! 3.d Select cell and face ranges
679  icl=nlvcel(ll-1)+1
680  iuf=nlvufc(ll-1)+1
681  ivf=nlvvfc(ll-1)+1
682  jcl=nlvcel(ll)
683  juf=nlvufc(ll)
684  jvf=nlvvfc(ll)
685  !
686  ! Use 3rd order UNO3 scheme. JGLi03Sep2015
687  IF( funo3 ) THEN
688  CALL smcxuno3(iuf, juf, cq, ucfl, ulcflx, dnnd, fumd, fudifx, fmr)
689  ELSE
690  ! Call SMCxUNO2 to calculate finest level (size-1) MFx value
691  CALL smcxuno2(iuf, juf, cq, ucfl, ulcflx, dnnd, fumd, fudifx, fmr)
692  ENDIF
693 
694  ! Store fineset level conservative flux in FCNt advective one in AFCN
695 #ifdef W3_OMPG
696  !$OMP Parallel DO Private(i, L, M, FUTRN)
697 #endif
698  DO i=iuf, juf
699  l=ijkufc5(i)
700  m=ijkufc6(i)
701  futrn = fumd(i)*ulcflx(i) - fudifx(i)
702  !! Replace CRITICAL with ATOMIC. JGLi15Jan2019
703  !! !$OMP CRITICAL
704  !! Remove boundary cell flux update or L M > 0. JGLi28Mar2019
705  IF( l > 0 ) THEN
706  !! Add sub-grid blocking for refined cells. JGLi18Apr2018
707  IF( (ctrnx(m)+ctrnx(l)) .GE. 1.96 ) THEN
708 #ifdef W3_OMPG
709  !$OMP ATOMIC
710 #endif
711  fcnt(l) = fcnt(l) - futrn
712  ELSE IF( ulcflx(i) .GE. 0.0 ) THEN
713 #ifdef W3_OMPG
714  !$OMP ATOMIC
715 #endif
716  fcnt(l) = fcnt(l) - futrn*ctrnx(l)
717  ELSE
718 #ifdef W3_OMPG
719  !$OMP ATOMIC
720 #endif
721  fcnt(l) = fcnt(l) - futrn*ctrnx(l)*ctrnx(m)
722  ENDIF
723 #ifdef W3_OMPG
724  !$OMP ATOMIC
725 #endif
726  ! ChrisB: Re-arranged the RHS term below to make it
727  ! valid for OMP ATMOIC directive.
728  afcn(l) = afcn(l) - (fumd(i)*ucfl(l)*fmr - fudifx(i))
729  ENDIF
730  IF( m > 0 ) THEN
731  !! Add sub-grid blocking for refined cells. JGLi18Apr2018
732  IF( (ctrnx(m)+ctrnx(l)) .GE. 1.96 ) THEN
733 #ifdef W3_OMPG
734  !$OMP ATOMIC
735 #endif
736  fcnt(m) = fcnt(m) + futrn
737  ELSE IF( ulcflx(i) .GE. 0.0 ) THEN
738 #ifdef W3_OMPG
739  !$OMP ATOMIC
740 #endif
741  fcnt(m) = fcnt(m) + futrn*ctrnx(m)*ctrnx(l)
742  ELSE
743 #ifdef W3_OMPG
744  !$OMP ATOMIC
745 #endif
746  fcnt(m) = fcnt(m) + futrn*ctrnx(m)
747  ENDIF
748 #ifdef W3_OMPG
749  !$OMP ATOMIC
750 #endif
751  afcn(m) = afcn(m) + (fumd(i)*ucfl(m)*fmr - fudifx(i))
752  ENDIF
753  !! !$OMP END CRITICAL
754  ENDDO
755 #ifdef W3_OMPG
756  !$OMP END Parallel DO
757 #endif
758 
759  ! Store conservative update in CQA and advective update in CQ
760  ! The side length in MF value has to be cancelled with cell y-length.
761  ! Also divided by another cell x-size as UCFL is in size-1 unit.
762 #ifdef W3_OMPG
763  !$OMP Parallel DO Private(n)
764 #endif
765  DO n=icl, jcl
766  cqa(n)=cq(n) + fcnt(n)/float( ijkcel3(n)*ijkcel4(n) )
767  cq(n)=cq(n) + afcn(n)/float( ijkcel3(n)*ijkcel4(n) )
768  fcnt(n)=0.0
769  afcn(n)=0.0
770  ENDDO
771 #ifdef W3_OMPG
772  !$OMP END Parallel DO
773 #endif
774  !
775  ! Use 3rd order UNO3 scheme. JGLi03Sep2015
776  IF( funo3 ) THEN
777  CALL smcyuno3(ivf, jvf, cq, vcfl, vlcfly, dssd, fvmd, fvdify, fmr)
778  ELSE
779  ! Call SMCyUNO2 to calculate MFy value
780  CALL smcyuno2(ivf, jvf, cq, vcfl, vlcfly, dssd, fvmd, fvdify, fmr)
781  ENDIF
782  !
783  ! Store conservative flux in BCNt
784 #ifdef W3_OMPG
785  !$OMP Parallel DO Private(j, L, M, FVTRN)
786 #endif
787  DO j=ivf, jvf
788  l=ijkvfc5(j)
789  m=ijkvfc6(j)
790  fvtrn = fvmd(j)*vlcfly(j) - fvdify(j)
791  !! Replace CRITICAL with ATOMIC. JGLi15Jan2019
792  !! !$OMP CRITICAL
793  !! Remove boundary cell flux update or L M > 0. JGLi28Mar2019
794  IF( l > 0 ) THEN
795  !! Add sub-grid blocking for refined cells. JGLi18Apr2018
796  IF( (ctrny(m)+ctrny(l)) .GE. 1.96 ) THEN
797 #ifdef W3_OMPG
798  !$OMP ATOMIC
799 #endif
800  bcnt(l) = bcnt(l) - fvtrn
801  ELSE IF( vlcfly(j) .GE. 0.0 ) THEN
802 #ifdef W3_OMPG
803  !$OMP ATOMIC
804 #endif
805  bcnt(l) = bcnt(l) - fvtrn*ctrny(l)
806  ELSE
807 #ifdef W3_OMPG
808  !$OMP ATOMIC
809 #endif
810  bcnt(l) = bcnt(l) - fvtrn*ctrny(l)*ctrny(m)
811  ENDIF
812  ENDIF
813  IF( m > 0 ) THEN
814  !! Add sub-grid blocking for refined cells. JGLi18Apr2018
815  IF( (ctrny(m)+ctrny(l)) .GE. 1.96 ) THEN
816 #ifdef W3_OMPG
817  !$OMP ATOMIC
818 #endif
819  bcnt(m) = bcnt(m) + fvtrn
820  ELSE IF( vlcfly(j) .GE. 0.0 ) THEN
821 #ifdef W3_OMPG
822  !$OMP ATOMIC
823 #endif
824  bcnt(m) = bcnt(m) + fvtrn*ctrny(m)*ctrny(l)
825  ELSE
826 #ifdef W3_OMPG
827  !$OMP ATOMIC
828 #endif
829  bcnt(m) = bcnt(m) + fvtrn*ctrny(m)
830  ENDIF
831  ENDIF
832  !! !$OMP END CRITICAL
833  ENDDO
834 #ifdef W3_OMPG
835  !$OMP END Parallel DO
836 #endif
837 
838  ! Store conservative update of CQA in CQ
839  ! The v side length in MF value has to be cancelled with x-size.
840  ! Also divided by cell y-size as VCFL is in size-1 unit.
841  !! One cosine factor is also needed to be divided for SMC grid.
842 #ifdef W3_OMPG
843  !$OMP Parallel DO Private(n)
844 #endif
845  DO n=icl, jcl
846  cq(n)=cqa(n) + bcnt(n)/( clats(n)* &
847  & float( ijkcel3(n)*ijkcel4(n) ) )
848  bcnt(n)=0.0
849  ENDDO
850 #ifdef W3_OMPG
851  !$OMP END Parallel DO
852 #endif
853  !Li Polar cell needs a special area factor, multi-level case.
854  IF( arctc .AND. jcl .EQ. nsea ) THEN
855  cq(nsea) = cqa(nsea) + bcnt(nsea)*pcarea
856  ENDIF
857  !
858  ! End of refine level if block MOD(LMN, LvR) .EQ. 0
859  ENDIF
860 
861  ! End of refine level loop LL=1, NRLv
862  ENDDO
863  !!
864  !! END of multi-resolution sub-step loop LMN = 1, MRFct
865  ENDDO
866 
867  ! End of multi-resolution advection ELSE block of NRLv > 1
868  ENDIF
869 
870  !! Update boundary spectra if any. JGLi26Feb2016
871  !
872  IF ( flbpi ) THEN
873  rd1 = dsec21(tbpi0, time)-dtg*real(ntloc-itloc)/real(ntloc)
874  rd2 = dsec21(tbpi0, tbpin)
875  IF ( rd2 .GT. 0.001 ) THEN
876  rd2 = min(1.,max(0.,rd1/rd2))
877  rd1 = 1. - rd2
878  ELSE
879  rd1 = 0.
880  rd2 = 1.
881  END IF
882  DO ibi=1, nbi
883  isea = isbpi(ibi)
884  cq(isea) = (rd1*bbpi0(isp,ibi) + rd2*bbpin(isp,ibi)) &
885  /cg(ik,isea)
886  END DO
887  ENDIF
888  !
889  !! End of ITLOC DO
890  ENDDO
891 
892  ! Average with 1-2-1 scheme. JGLi20Aug2015
893  IF(fverg) CALL smcaverg(cq)
894 
895  !
896  ! 4. Store results in VQ in proper format --------------------------- *
897  !
898 #ifdef W3_OMPG
899  !$OMP Parallel DO Private(ISEA)
900 #endif
901  DO isea=1, nsea
902  vq(isea) = max( 0. , cq(isea)*cg(ik,isea) )
903  END DO
904 #ifdef W3_OMPG
905  !$OMP END Parallel DO
906 #endif
907  !
908  RETURN
909  !
910  ! Formats
911  !
912 #ifdef W3_T
913 9001 FORMAT (' TEST W3PSMC : ISP, ITH, IK, COS-SIN :',i8,2i4,2f7.3)
914 9003 FORMAT (' TEST W3PSMC : NO DISPERSION CORRECTION ')
915 9010 FORMAT (' TEST W3PSMC : INITIALIZE ARRAYS')
916 9020 FORMAT (' TEST W3PSMC : CALCULATING LCFLX/Y AND DSS/NN (NSEA=', &
917  i6,')')
918 #endif
919 #ifdef W3_T1
920 9021 FORMAT (1x,i6,2i5,e12.4,2f7.3)
921 #endif
922 #ifdef W3_T
923 9022 FORMAT (' TEST W3PSMC : CORRECTING FOR CURRENT')
924 9040 FORMAT (' TEST W3PSMC : FIELD AFTER PROP. (NSEA=',i6,')')
925 #endif
926 #ifdef W3_T2
927 9041 FORMAT (1x,i6,2i5,e12.4)
928 #endif
929  !/
930  !/ End of W3PSMC ----------------------------------------------------- /
931  !/

References w3gdatmd::angarc, w3gdatmd::arctc, w3adatmd::atrnx, w3adatmd::atrny, w3odatmd::bbpi0, w3odatmd::bbpin, w3adatmd::cg, w3gdatmd::clats, w3gdatmd::ctrnx, w3gdatmd::ctrny, w3adatmd::cx, w3adatmd::cy, constants::dera, w3timemd::dsec21(), w3gdatmd::dtcfl, w3gdatmd::dth, w3gdatmd::dtms, w3gdatmd::ecos, w3gdatmd::esin, w3odatmd::flbpi, w3idatmd::flcur, w3gdatmd::funo3, w3gdatmd::fverg, constants::grav, w3gdatmd::ijkcel, w3gdatmd::ijkcel3, w3gdatmd::ijkcel4, w3gdatmd::ijkufc, w3gdatmd::ijkufc5, w3gdatmd::ijkufc6, w3gdatmd::ijkvfc, w3gdatmd::ijkvfc5, w3gdatmd::ijkvfc6, w3odatmd::isbpi, w3adatmd::itime, w3gdatmd::mapsf, w3gdatmd::mrfct, w3odatmd::nbi, w3gdatmd::ncel, w3odatmd::ndse, w3odatmd::ndst, w3gdatmd::nglo, w3gdatmd::nk, w3gdatmd::nlvcel, w3gdatmd::nlvufc, w3gdatmd::nlvvfc, w3gdatmd::nrlv, w3gdatmd::nsea, w3gdatmd::nth, w3gdatmd::nufc, w3gdatmd::nvfc, w3gdatmd::nx, w3gdatmd::ny, constants::pi, constants::radius, w3gdatmd::sig, smcaverg(), smcxuno2(), smcxuno2r(), smcxuno3(), smcxuno3r(), smcyuno2(), smcyuno2r(), smcyuno3(), smcyuno3r(), w3servmd::strace(), w3gdatmd::sx, w3gdatmd::sy, w3odatmd::tbpi0, w3odatmd::tbpin, w3wdatmd::time, w3adatmd::u10, w3adatmd::wn, and w3gdatmd::xfr.

Referenced by w3wavemd::w3wave().

◆ w3scatsmc()

subroutine w3psmcmd::w3scatsmc ( integer, intent(in)  ISPEC,
integer, dimension(ny*nx), intent(in)  MAPSTA,
real, dimension(ncel), intent(in)  FIELD 
)

SMC version of W3GATH.

'Scatter' data back to spectral storage after propagation. Direct copy or communication calls (MPP version). See also W3GATH.

Parameters
[in]ISPECSpectral bin considered
[in]MAPSTAStatus map for spatial grid
[in]FIELDSMC grid field to be propagated
Remarks
  • The field is put back but not converted !
  • MPI persistent communication calls initialize in W3MPII.
  • See W3GATH and W3MPII for additional comments on data buffering.
Author
Jian-Guo Li
Date
16 Jan 2012

Definition at line 3420 of file w3psmcmd.F90.

3420  !/
3421  !/ +-----------------------------------+
3422  !/ | WAVEWATCH-III NOAA/NCEP |
3423  !/ | H. L. Tolman |
3424  !/ | FORTRAN 90 |
3425  !/ | Last update : 13-Jun-2006 |
3426  !/ +-----------------------------------+
3427  !/
3428  !/ 04-Jan-1999 : Distributed FORTRAN 77 version. ( version 1.18 )
3429  !/ 13-Jan-2000 : Upgrade to FORTRAN 90 ( version 2.00 )
3430  !/ Major changes to logistics.
3431  !/ 28-Dec-2004 : Multiple grid version. ( version 3.06 )
3432  !/ 07-Sep-2005 : Updated boundary conditions. ( version 3.08 )
3433  !/ 13-Jun-2006 : Split STORE in G/SSTORE ( version 3.09 )
3434  !/ 9-Dec-2010 : Adapted for SMC grid propagtion. JGLi09Dec2010
3435  !/ 16-Jan-2012 : Remove MAPSTA checking for SMC grid. JGLi16Jan2012
3436  !/
3437  !/
3438  ! 1. Purpose :
3439  !
3440  ! 'Scatter' data back to spectral storage after propagation.
3441  !
3442  ! 2. Method :
3443  !
3444  ! Direct copy or communication calls (MPP version).
3445  ! See also W3GATH.
3446  !
3447  ! 3. Parameters :
3448  !
3449  ! Parameter list
3450  ! ----------------------------------------------------------------
3451  ! ISPEC Int. I Spectral bin considered.
3452  ! MAPSTA I.A. I Status map for spatial grid.
3453  ! FIELD R.A. I SMC grid field to be propagated.
3454  ! ----------------------------------------------------------------
3455  !
3456  ! 4. Subroutines used :
3457  !
3458  ! Name Type Module Description
3459  ! ----------------------------------------------------------------
3460  ! STRACE Subr. W3SERVMD Subroutine tracing.
3461  !
3462  ! MPI_STARTALL, MPI_WAITALL, MPI_TESTALL
3463  ! Subr. mpif.h MPI persistent comm. routines (!/MPI).
3464  ! ----------------------------------------------------------------
3465  !
3466  ! 5. Called by :
3467  !
3468  ! Name Type Module Description
3469  ! ----------------------------------------------------------------
3470  ! W3WAVE Subr. W3WAVEMD Actual wave model routine.
3471  ! ----------------------------------------------------------------
3472  !
3473  ! 6. Error messages :
3474  !
3475  ! None.
3476  !
3477  ! 7. Remarks :
3478  !
3479  ! - The field is put back but not converted !
3480  ! - MPI persistent communication calls initialize in W3MPII.
3481  ! - See W3GATH and W3MPII for additional comments on data
3482  ! buffering.
3483  !
3484  ! 8. Structure :
3485  !
3486  ! See source code.
3487  !
3488  ! 9. Switches :
3489  !
3490  ! !/SHRD Switch for message passing method.
3491  ! !/MPI Id.
3492  !
3493  ! !/S Enable subroutine tracing.
3494  !
3495  ! 10. Source code :
3496  !
3497  !/ ------------------------------------------------------------------- /
3498 #ifdef W3_S
3499  USE w3servmd, ONLY: strace
3500 #endif
3501  !/
3502  USE w3gdatmd, ONLY: nspec, nx, ny, nsea, ncel, nseal, mapsf
3503  USE w3wdatmd, ONLY: a => va
3504 #ifdef W3_MPI
3505  USE w3adatmd, ONLY: mpibuf, bstat, ibfloc, isploc, bispl, &
3507  USE w3odatmd, ONLY: iaproc, naproc
3508 #endif
3509  USE w3odatmd, ONLY: ndst
3510  !/
3511  IMPLICIT NONE
3512  !
3513 #ifdef W3_MPI
3514  include "mpif.h"
3515 #endif
3516  !/
3517  !/ ------------------------------------------------------------------- /
3518  !/ Parameter list
3519  !/
3520  INTEGER, INTENT(IN) :: ISPEC, MAPSTA(NY*NX)
3521  REAL, INTENT(IN) :: FIELD(NCel)
3522  !/
3523  !/ ------------------------------------------------------------------- /
3524  !/ Local parameters
3525  !/
3526 #ifdef W3_SHRD
3527  INTEGER :: ISEA, IXY
3528 #endif
3529 #ifdef W3_MPI
3530  INTEGER :: ISEA, IXY, IOFF, IERR_MPI, J, &
3531  STATUS(MPI_STATUS_SIZE,NSPEC), &
3532  JSEA, IB0
3533 #endif
3534 #ifdef W3_S
3535  INTEGER, SAVE :: IENT
3536 #endif
3537 #ifdef W3_MPI
3538  LOGICAL :: DONE
3539 #endif
3540  !/
3541  !/ ------------------------------------------------------------------- /
3542  !/
3543 #ifdef W3_S
3544  CALL strace (ient, 'W3SCAT')
3545 #endif
3546  !
3547  ! 1. Shared memory version ------------------------------------------ *
3548  !
3549 #ifdef W3_SHRD
3550  DO isea=1, nsea
3551  ixy = mapsf(isea,3)
3552  IF ( mapsta(ixy) .GE. 1 ) a(ispec,isea) = field(isea)
3553  END DO
3554  !
3555  RETURN
3556 #endif
3557  !
3558  ! 2. Distributed memory version ( MPI ) ----------------------------- *
3559  ! 2.a Initializations
3560  !
3561  ! 2.b Convert full grid to sea grid, active points only
3562  !
3563 #ifdef W3_MPI
3564  DO isea=1, nsea
3565  ixy = mapsf(isea,3)
3566  IF ( mapsta(ixy) .GE. 1 ) sstore(isea,ibfloc) = field(isea)
3567  END DO
3568  !
3569  ! 2.c Send spectral densities to appropriate remote
3570  !
3571  ioff = 1 + (isploc-1)*nrqsg2
3572  IF ( nrqsg2 .GT. 0 ) CALL &
3573  mpi_startall ( nrqsg2, irqsg2(ioff,2), ierr_mpi )
3574  bstat(ibfloc) = 2
3575  !
3576  ! 2.d Save locally stored results
3577  !
3578  DO jsea=1, nseal
3579  !!Li ISEA = IAPROC+(JSEA-1)*NAPROC
3580  isea = min( iaproc+(jsea-1)*naproc, nsea )
3581  a(ispec,jsea) = sstore(isea,ibfloc)
3582  END DO
3583  !
3584  ! 2.e Check if any sends have finished
3585  !
3586  ib0 = ibfloc
3587  !
3588  DO j=1, mpibuf
3589  ib0 = 1 + mod(ib0,mpibuf)
3590  IF ( bstat(ib0) .EQ. 2 ) THEN
3591  ioff = 1 + (bispl(ib0)-1)*nrqsg2
3592  IF ( nrqsg2 .GT. 0 ) THEN
3593  CALL mpi_testall ( nrqsg2, irqsg2(ioff,2), done, &
3594  status, ierr_mpi )
3595  ELSE
3596  done = .true.
3597  END IF
3598  IF ( done .AND. nrqsg2.GT.0 ) CALL &
3599  mpi_waitall ( nrqsg2, irqsg2(ioff,2), &
3600  status, ierr_mpi )
3601  IF ( done ) THEN
3602  bstat(ib0) = 0
3603  END IF
3604  END IF
3605  END DO
3606 #endif
3607  !
3608  ! 2.f Last component, finish message passing, reset buffer control
3609  !
3610 #ifdef W3_MPI
3611  IF ( isploc .EQ. nsploc ) THEN
3612  DO ib0=1, mpibuf
3613  IF ( bstat(ib0) .EQ. 2 ) THEN
3614  ioff = 1 + (bispl(ib0)-1)*nrqsg2
3615  IF ( nrqsg2 .GT. 0 ) CALL &
3616  mpi_waitall ( nrqsg2, irqsg2(ioff,2), &
3617  status, ierr_mpi )
3618  bstat(ib0) = 0
3619  END IF
3620  END DO
3621  isploc = 0
3622  ibfloc = 0
3623  END IF
3624  RETURN
3625 #endif
3626  !
3627  ! Formats
3628  !
3629  !/
3630  !/ End of W3SCATSMC ----------------------------------------------------- /
3631  !/

References w3adatmd::bispl, w3adatmd::bstat, w3odatmd::iaproc, w3adatmd::ibfloc, include(), w3adatmd::irqsg2, w3adatmd::isploc, w3gdatmd::mapsf, w3adatmd::mpibuf, w3odatmd::naproc, w3gdatmd::ncel, w3odatmd::ndst, w3adatmd::nrqsg2, w3gdatmd::nsea, w3gdatmd::nseal, w3gdatmd::nspec, w3adatmd::nsploc, w3gdatmd::nx, w3gdatmd::ny, w3adatmd::sstore, w3servmd::strace(), and w3wdatmd::va.

Referenced by w3wavemd::w3wave().

◆ w3smcell()

subroutine w3psmcmd::w3smcell ( integer, intent(in)  IMOD,
integer, intent(in)  NC,
integer, dimension(nc), intent(in)  IDCl,
real, dimension(nc), intent(out)  XLon,
real, dimension(nc), intent(out)  YLat 
)

Calculate cell centre lat-lon for given ids.

Calculate the cell centre longitude and latitude in degree for a given list of cell identity or sequential numbers in the IMOD sub-grid.

Regular grid SX, SY, X0, Y0 and SMC grid MRFct and IJKCel arrays in W3GDATMD are used to work out SMC grid origin and increments. Then given cell centre coordinates are calculated. Longitude is wrapped into [0, 360) range, latitude in in (-90, 90) range. The polar cell centre is off the N-Pole to avoid singularity but its centre values are not used for propagation schemes.

Parameters
[in]IMODModel number to point to
[in]NCNumcer of cells to be calculated
[in]IDClList of cell id or sequential numbers
[out]XLonX-Longitude in degree of listed cells
[out]YLatY-Latitude in degree of listed cells
Author
Jian-Guo Li
Date
19 Oct 2020

Definition at line 3660 of file w3psmcmd.F90.

3660  !! -------------------------------------------------------------------
3661  !!
3662  !! Generated for WW3 Multi-grid boundary matching. JGLi19Oct2020
3663  !!
3664  !! 1. Purpose:
3665  !
3666  ! Calculate the cell centre longitude and latitude in degree for a given
3667  ! list of cell identity or sequential numbers in the IMOD sub-grid.
3668  !
3669  !! 2. Method:
3670  !
3671  ! Regular grid SX, SY, X0, Y0 and SMC grid MRFct and IJKCel arrays
3672  ! in W3GDATMD are used to work out SMC grid origin and increments.
3673  ! Then given cell centre coordinates are calculated. Longitude is
3674  ! wrapped into [0, 360) range, latitude in in (-90, 90) range.
3675  ! The polar cell centre is off the N-Pole to avoid singularity but
3676  ! its centre values are not used for propagation schemes.
3677  !
3678  !! 3. Parameters:
3679  ! ----------------------------------------------------------------
3680  ! IMOD Int. I Model number to point to.
3681  ! NC Int. I Numcer of cells to be calculated.
3682  ! IDCl Int. I List of cell id or sequential numbers.
3683  ! XLon Real O X-Longitude in degree of listed cells.
3684  ! YLat Real O Y-Latitude in degree of listed cells.
3685  ! ----------------------------------------------------------------
3686  !
3687  !! 4. Subroutines used:
3688  !
3689  ! None
3690  !
3691  !! 5. Called by:
3692  !
3693  ! WMGLOW, W3IOPP, WMIOPP, WW3_GINT
3694  !
3695  !! 6. Error messages:
3696  !
3697  ! - Error checks on previous setting of variable.
3698  !
3699  !! 7. Remarks:
3700  !
3701  !! 8. Structure:
3702  !
3703  !! 9. Switches:
3704  !
3705  ! !/S Enable subroutine tracing.
3706  ! !/T Enable test output
3707  !
3708  ! 10. Source code:
3709  !
3710  !/ ------------------------------------------------------------------- /
3711  USE constants
3712  USE w3gdatmd
3713  USE w3servmd, ONLY: extcde
3714  USE w3odatmd, ONLY: ndse, ndst
3715 #ifdef W3_S
3716  USE w3servmd, ONLY: strace
3717 #endif
3718 
3719  IMPLICIT NONE
3720 
3721  !/ ------------------------------------------------------------------- /
3722  ! Input/Output variables
3723 
3724  INTEGER, INTENT(IN) :: IMOD, NC
3725  INTEGER, INTENT(in), Dimension(NC):: IDCl ! Automatic array
3726  REAL , INTENT(out),Dimension(NC):: XLon, YLat
3727  !/ ------------------------------------------------------------------- /
3728  ! Local variables.
3729 
3730  REAL :: XI0, YJ0, DXG, DYG, DX1, DY1
3731  INTEGER :: I1, I3, J2, J4, MRF, ij, ijp, NSEM
3732 #ifdef W3_S
3733  INTEGER :: IENT = 0
3734  CALL strace (ient, 'W3SMCELL')
3735 #endif
3736 
3737  !! 1. Convert regular grid parameters into SMC grid origin and increments.
3738  dxg = grids(imod)%SX
3739  dyg = grids(imod)%SY
3740  xi0 = grids(imod)%X0 - 0.5*dxg
3741  yj0 = grids(imod)%Y0 - 0.5*dyg
3742  mrf = grids(imod)%MRFct
3743  dx1 = dxg/real(mrf)
3744  dy1 = dyg/real(mrf)
3745  nsem = grids(imod)%NSEA
3746 
3747  !! 2. Loop over listed cells and work out their centre coordinates.
3748 
3749 #ifdef W3_OMPG
3750  !$OMP Parallel DO Private(ij, ijp, I1, J2, I3, J4 )
3751 #endif
3752  DO ij = 1, nc
3753  ijp = idcl(ij)
3754  !!Li Return South Pole lon-lat values for any ids < 1 or > NSEA
3755  !! so these out of range points will not be matched to any cell.
3756  IF( ijp < 1 .OR. ijp > nsem ) THEN
3757  xlon(ij) = 0.0
3758  ylat(ij) = -90.0
3759  ELSE
3760  !! Fetch cell array indexes from given sub-grid.
3761  i1=grids(imod)%IJKCel(1, ijp)
3762  j2=grids(imod)%IJKCel(2, ijp)
3763  i3=grids(imod)%IJKCel(3, ijp)
3764  j4=grids(imod)%IJKCel(4, ijp)
3765 
3766  !! Calculate its cell centre lon-lat values.
3767  xlon(ij) = xi0 + ( float(i1) + 0.5*float(i3) )*dx1
3768  ylat(ij) = yj0 + ( float(j2) + 0.5*float(j4) )*dy1
3769  ENDIF
3770  END DO
3771 #ifdef W3_OMPG
3772  !$OMP END Parallel DO
3773 #endif
3774 
3775  !! 3. Wrap negative logitudes into [0, 360) range.
3776  WHERE( xlon < 0.0 ) xlon = xlon + 360.0
3777  !
3778  RETURN

References w3servmd::extcde(), w3gdatmd::grids, w3odatmd::ndse, w3odatmd::ndst, and w3servmd::strace().

Referenced by wmgridmd::wmsmceql().

◆ w3smcgmp()

subroutine w3psmcmd::w3smcgmp ( integer, intent(in)  IMOD,
integer, intent(in)  NC,
real, dimension(nc), intent(in)  XLon,
real, dimension(nc), intent(in)  YLat,
integer, dimension(nc), intent(out)  IDCl 
)

Map lat-lon points to SMC grid cells.

Determine whether a list of points are inside the IMOD SMC sub-grid and return the IMOD sub-grid cell indexes, if any.

Convert point XLon and YLat values into cell indices i, j. Match with cell ranges (i,i+di) and (j,j+dj) to see i,j in which cell. Return the matched cell number. Otherwise, return an index of 0, or no matching cell found.

Parameters
[in]IMODModel number to point to
[in]XLonX-Longitude in degree of search points
[in]YLatY-Latitude in degree of search points
[in]NCNumber of points to be searched
[out]IDClModel number to point to
Author
Jian-Guo Li
Date
20 Oct 2020

Definition at line 3804 of file w3psmcmd.F90.

3804  !! -------------------------------------------------------------------
3805  !!
3806  !! Generated for WW3 Multi-grid boundary matching. JGLi22Oct2020
3807  !!
3808  !! 1. Purpose:
3809  !
3810  ! Determine whether a list of points are inside the IMOD SMC sub-grid
3811  ! and return the IMOD sub-grid cell indexes, if any.
3812  !
3813  !! 2. Method:
3814  !
3815  ! Convert point XLon and YLat values into cell indices i, j.
3816  ! Match with cell ranges (i,i+di) and (j,j+dj) to see i,j in
3817  ! which cell. Return the matched cell number. Otherwide,
3818  ! return an index of 0, or no matching cell found.
3819  !
3820  !! 3. Parameters:
3821  ! ----------------------------------------------------------------
3822  ! IMOD Int. I Model number to point to.
3823  ! XLon Real I X-Longitude in degree of search points.
3824  ! YLat Real I Y-Latitude in degree of search points.
3825  ! NC Int. I Number of points to be searched.
3826  ! IDCl Int. O Model number to point to.
3827  ! ----------------------------------------------------------------
3828  !
3829  !! 4. Subroutines used:
3830  !
3831  ! None
3832  !
3833  !! 5. Called by:
3834  !
3835  ! WMGLOW, W3IOPP, WMIOPP, WW3_GINT
3836  !
3837  !! 6. Error messages:
3838  !
3839  ! - Error checks on previous setting of variable.
3840  !
3841  !! 7. Remarks:
3842  !
3843  !! 8. Structure:
3844  !
3845  !! 9. Switches:
3846  !
3847  ! !/S Enable subroutine tracing.
3848  ! !/T Enable test output
3849  !
3850  ! 10. Source code:
3851  !
3852  !/ ------------------------------------------------------------------- /
3853  USE constants
3854  USE w3gdatmd
3855  USE w3servmd, ONLY: extcde
3856  USE w3odatmd, ONLY: ndse, ndst
3857 #ifdef W3_S
3858  USE w3servmd, ONLY: strace
3859 #endif
3860 
3861  IMPLICIT NONE
3862 
3863  !/ ------------------------------------------------------------------- /
3864  ! Iuput/Output variables
3865  INTEGER, INTENT(IN) :: IMOD, NC
3866  REAL , INTENT(in), Dimension(NC):: XLon, YLat
3867  INTEGER, INTENT(out), Dimension(NC):: IDCl
3868  !/ ------------------------------------------------------------------- /
3869  ! Local variables
3870  INTEGER, Dimension(NC) :: IX1, JY1
3871  REAL :: XI0, YJ0, DXG, DYG, DX1, DY1, XLow(NC)
3872  INTEGER :: I1, I3, J2, J4, ij, ijp, MRF, NSEM, NFund
3873 #ifdef W3_S
3874  INTEGER :: IENT = 0
3875  CALL strace (ient, 'W3SMCGMP')
3876 #endif
3877 
3878  !! 1. Convert XLon YLat into SMC grid indexes in present SMC grid.
3879  dxg = grids(imod)%SX
3880  dyg = grids(imod)%SY
3881  xi0 = grids(imod)%X0 - 0.5*dxg
3882  yj0 = grids(imod)%Y0 - 0.5*dyg
3883  mrf = grids(imod)%MRFct
3884  dx1 = dxg/real(mrf)
3885  dy1 = dyg/real(mrf)
3886  nsem = grids(imod)%NSEA
3887 
3888  !! Wrap longitude so they are great than XI0.
3889  xlow = xlon
3890  WHERE( xlow < xi0 ) xlow = xlow + 360.0
3891 
3892  !! Convert XLon and YLat into SMC indexes.
3893  ix1 = floor( (xlow - xi0)/dx1 )
3894  jy1 = floor( (ylat - yj0)/dy1 )
3895 
3896  !! Initialise IDCl to be all 0
3897  idcl = 0
3898 
3899  !! 2. Loop over all cells until all input points are found.
3900  nfund = 0
3901  ij = 0
3902  DO WHILE( ij < nsem .AND. nfund < nc )
3903  ij = ij + 1
3904  i1=grids(imod)%IJKCel(1, ij)
3905  j2=grids(imod)%IJKCel(2, ij)
3906  i3=grids(imod)%IJKCel(3, ij)
3907  j4=grids(imod)%IJKCel(4, ij)
3908  lpnbis: DO ijp = 1, nc
3909  IF( idcl(ijp) .EQ. 0 ) THEN
3910  !! Check if IX1 and JY1 fall inside the cell i,j range.
3911  IF((ix1(ijp) .GE. i1) .AND. (ix1(ijp) .LT. i1+i3) .AND. &
3912  (jy1(ijp) .GE. j2) .AND. (jy1(ijp) .LT. j2+j4)) THEN
3913  nfund = nfund + 1
3914  idcl(ijp) = ij
3915  EXIT lpnbis
3916  ENDIF
3917  ENDIF
3918  END DO lpnbis
3919  END DO
3920 
3921  !! If any IDCl element remians to be 0, it means no cell is found
3922  !! covering this point. So check IDCl(ij) > 0 to ensure in grid.
3923 
3924  RETURN
3925 

References w3servmd::extcde(), w3gdatmd::grids, w3odatmd::ndse, w3odatmd::ndst, and w3servmd::strace().

Referenced by w3iobcmd::w3iobc(), and wmgridmd::wmsmceql().

w3gdatmd::esc
real, dimension(:), pointer esc
Definition: w3gdatmd.F90:1234
w3gdatmd::nseal
integer, pointer nseal
Definition: w3gdatmd.F90:1097
w3odatmd::tbpi0
integer, dimension(:), pointer tbpi0
Definition: w3odatmd.F90:464
constants::pi
real, parameter pi
PI Value of Pi.
Definition: constants.F90:71
w3timemd::dsec21
real function dsec21(TIME1, TIME2)
Definition: w3timemd.F90:333
w3gdatmd::funo3
logical, pointer funo3
Definition: w3gdatmd.F90:1264
include
cmake src_list cmake include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/check_switches.cmake) check_switches("$
Definition: CMakeLists.txt:15
w3gdatmd::dth
real, pointer dth
Definition: w3gdatmd.F90:1232
w3adatmd
Define data structures to set up wave model auxiliary data for several models simultaneously.
Definition: w3adatmd.F90:26
w3adatmd::nrqsg2
integer, pointer nrqsg2
Definition: w3adatmd.F90:676
constants::dera
real, parameter dera
DERA Conversion factor from degrees to radians.
Definition: constants.F90:77
w3gdatmd::dmin
real, pointer dmin
Definition: w3gdatmd.F90:1183
w3wdatmd
Define data structures to set up wave model dynamic data for several models simultaneously.
Definition: w3wdatmd.F90:18
w3adatmd::atrnx
real, dimension(:,:), pointer atrnx
Definition: w3adatmd.F90:578
w3adatmd::dhdy
real, dimension(:), pointer dhdy
Definition: w3adatmd.F90:631
w3adatmd::dhlmt
real, dimension(:,:), pointer dhlmt
Definition: w3adatmd.F90:631
w3gdatmd::mrfct
integer, pointer mrfct
Definition: w3gdatmd.F90:1167
w3adatmd::nsploc
integer, pointer nsploc
Definition: w3adatmd.F90:676
w3gdatmd::ctrny
real, dimension(:), pointer ctrny
Definition: w3gdatmd.F90:1202
w3adatmd::bispl
integer, dimension(:), pointer bispl
Definition: w3adatmd.F90:680
w3gdatmd::ijkvfc
integer, dimension(:,:), pointer ijkvfc
Definition: w3gdatmd.F90:1170
w3adatmd::atrny
real, dimension(:,:), pointer atrny
Definition: w3adatmd.F90:578
w3gdatmd::sig
real, dimension(:), pointer sig
Definition: w3gdatmd.F90:1234
w3gdatmd::sy
real, pointer sy
Definition: w3gdatmd.F90:1183
w3gdatmd::flck
logical, pointer flck
Definition: w3gdatmd.F90:1217
w3odatmd::iaproc
integer, pointer iaproc
Definition: w3odatmd.F90:457
w3gdatmd::nlvvfc
integer, dimension(:), pointer nlvvfc
Definition: w3gdatmd.F90:1169
w3wdatmd::time
integer, dimension(:), pointer time
Definition: w3wdatmd.F90:172
w3gdatmd::ecos
real, dimension(:), pointer ecos
Definition: w3gdatmd.F90:1234
w3gdatmd::grids
type(grid), dimension(:), allocatable, target grids
Definition: w3gdatmd.F90:1088
w3odatmd::bbpi0
real, dimension(:,:), pointer bbpi0
Definition: w3odatmd.F90:541
w3gdatmd::clatf
real, dimension(:), pointer clatf
Definition: w3gdatmd.F90:1202
w3odatmd::tbpin
integer, dimension(:), pointer tbpin
Definition: w3odatmd.F90:464
w3gdatmd::dsip
real, dimension(:), pointer dsip
Definition: w3gdatmd.F90:1234
w3odatmd::nbi
integer, pointer nbi
Definition: w3odatmd.F90:530
w3odatmd::flbpi
logical, pointer flbpi
Definition: w3odatmd.F90:546
w3idatmd::flcur
logical, pointer flcur
Definition: w3idatmd.F90:261
w3gdatmd::ijkufc5
integer, dimension(:), pointer ijkufc5
Definition: w3gdatmd.F90:1174
w3gdatmd::nglo
integer, pointer nglo
Definition: w3gdatmd.F90:1168
w3odatmd::ndse
integer, pointer ndse
Definition: w3odatmd.F90:456
w3gdatmd::nufc
integer, pointer nufc
Definition: w3gdatmd.F90:1167
w3gdatmd::es2
real, dimension(:), pointer es2
Definition: w3gdatmd.F90:1234
w3gdatmd::esin
real, dimension(:), pointer esin
Definition: w3gdatmd.F90:1234
w3gdatmd::nvfc
integer, pointer nvfc
Definition: w3gdatmd.F90:1167
w3adatmd::mpibuf
integer, parameter mpibuf
Definition: w3adatmd.F90:376
w3gdatmd::dtms
real, pointer dtms
Definition: w3gdatmd.F90:1263
w3servmd
Definition: w3servmd.F90:3
w3gdatmd::refran
real, pointer refran
Definition: w3gdatmd.F90:1263
w3adatmd::gstore
real, dimension(:,:), pointer gstore
Definition: w3adatmd.F90:682
w3gdatmd::flcth
logical, pointer flcth
Definition: w3gdatmd.F90:1217
w3odatmd
Definition: w3odatmd.F90:3
w3gdatmd::ijkvfc5
integer, dimension(:), pointer ijkvfc5
Definition: w3gdatmd.F90:1174
w3gdatmd::clats
real, dimension(:), pointer clats
Definition: w3gdatmd.F90:1196
w3gdatmd::angarc
real, dimension(:), pointer angarc
Definition: w3gdatmd.F90:1204
w3gdatmd::mapsf
integer, dimension(:,:), pointer mapsf
Definition: w3gdatmd.F90:1163
w3odatmd::naproc
integer, pointer naproc
Definition: w3odatmd.F90:457
w3adatmd::sstore
real, dimension(:,:), pointer sstore
Definition: w3adatmd.F90:682
w3gdatmd::ijkvfc6
integer, dimension(:), pointer ijkvfc6
Definition: w3gdatmd.F90:1174
constants::radius
real, parameter radius
RADIUS Radius of the earth (m).
Definition: constants.F90:79
w3gdatmd::ijkufc6
integer, dimension(:), pointer ijkufc6
Definition: w3gdatmd.F90:1174
w3adatmd::u10
real, dimension(:), pointer u10
Definition: w3adatmd.F90:584
w3gdatmd::ijkcel
integer, dimension(:,:), pointer ijkcel
Definition: w3gdatmd.F90:1170
w3gdatmd::ijkcel4
integer, dimension(:), pointer ijkcel4
Definition: w3gdatmd.F90:1174
w3servmd::strace
subroutine strace(IENT, SNAME)
Definition: w3servmd.F90:148
w3idatmd
Define data structures to set up wave model input data for several models simultaneously.
Definition: w3idatmd.F90:16
w3gdatmd::xfr
real, pointer xfr
Definition: w3gdatmd.F90:1232
w3gdatmd::fverg
logical, pointer fverg
Definition: w3gdatmd.F90:1264
w3gdatmd::sx
real, pointer sx
Definition: w3gdatmd.F90:1183
w3odatmd::ndst
integer, pointer ndst
Definition: w3odatmd.F90:456
constants
Define some much-used constants for global use (all defined as PARAMETER).
Definition: constants.F90:20
w3gdatmd::ijkcel3
integer, dimension(:), pointer ijkcel3
Definition: w3gdatmd.F90:1174
w3gdatmd
Definition: w3gdatmd.F90:16
w3gdatmd::arctc
logical, pointer arctc
Definition: w3gdatmd.F90:1264
w3adatmd::ibfloc
integer, pointer ibfloc
Definition: w3adatmd.F90:676
w3adatmd::bstat
integer, dimension(:), pointer bstat
Definition: w3adatmd.F90:680
w3gdatmd::ncel
integer, pointer ncel
Definition: w3gdatmd.F90:1167
w3adatmd::itime
integer, pointer itime
Definition: w3adatmd.F90:686
w3gdatmd::nlvufc
integer, dimension(:), pointer nlvufc
Definition: w3gdatmd.F90:1169
w3adatmd::irqsg2
integer, dimension(:,:), pointer irqsg2
Definition: w3adatmd.F90:681
w3gdatmd::nrlv
integer, pointer nrlv
Definition: w3gdatmd.F90:1167
w3odatmd::isbpi
integer, dimension(:), pointer isbpi
Definition: w3odatmd.F90:535
w3adatmd::isploc
integer, pointer isploc
Definition: w3adatmd.F90:676
w3gdatmd::ctmax
real, pointer ctmax
Definition: w3gdatmd.F90:1183
w3timemd
Definition: w3timemd.F90:3
w3gdatmd::nlvcel
integer, dimension(:), pointer nlvcel
Definition: w3gdatmd.F90:1169
w3gdatmd::ec2
real, dimension(:), pointer ec2
Definition: w3gdatmd.F90:1234
w3gdatmd::dtcfl
real, pointer dtcfl
Definition: w3gdatmd.F90:1183
w3gdatmd::ijkufc
integer, dimension(:,:), pointer ijkufc
Definition: w3gdatmd.F90:1170
constants::grav
real, parameter grav
GRAV Acc.
Definition: constants.F90:61
w3adatmd::dhdx
real, dimension(:), pointer dhdx
Definition: w3adatmd.F90:631
w3odatmd::bbpin
real, dimension(:,:), pointer bbpin
Definition: w3odatmd.F90:541
w3gdatmd::ctrnx
real, dimension(:), pointer ctrnx
Definition: w3gdatmd.F90:1202