The problem can be detected very easily since there is both a formulation of the stress for barotropic and baroclinic in nearshore_mellor05.h. Hence if one removes the #ifdef SOLVE3D ... #else ... #endif and rename the variables then one sees that the *2d variables are completely differently. This should not be the case since the formula of Mellor 2003 when vertically integrated gives the Longuet-Higgins Stewart 1962 formulation.
Putting everything together takes time. Here is the result of my investigation:
Issue 1: The fact that Mellor 2003, when vertically integrated gives the classical solution relies on the following integral identities:
Code: Select all
int_0^D FCS FCC dz = 1/(2k) + D/sh(2kD)
int_0^D FSS FCS dz = 1/(2k)
int_0^D FCS FCC - FSS FCS dz = D/sh(kD)
This is not a small problem. The situation below:
Code: Select all
ThetaS=7 ThetaB=0.1 TCLINE=0 Vstretching=2 Vtransform=2
dep=1160m Lwave=10 Hwave=1.01
Sxx(numerical integral)=18 Sxx(2D formula)=0.12
Solution to the problem: First of all the value of kDmax=5 is really extremely conservative. ROMS works in double precision, and SINH(710) is still finite while SINH(711) is infinite. Hence setting kDmax=300 sounds reasonable to me as far as I know.
But setting this does not solve completely the problem. The amplification factor is still 2.5 for kDmax=300. The reason is that the integrals of FCS FCC and others are extremely singular. Thus I propose to replace the value of FCS FCC by their average values over the interval [z_w(i,j,k-1) z_w(i,j,k)]. This is possible since those functions have explicit expressions that can be explicitly integrated easily.
Issue 2: The term rustr3d is multiplied by the quantity
Code: Select all
cff1=0.25_r8*(pm(i,j)+pm(i-1,j))*(pn(i,j)+pn(i-1,j))
Proposed solution: remove the multiplication by this quantity.
Issue 3: after that the vertical integral still diverge. What I think is the problem is that Sxx is multiplied by Hz two times. Once in line 506 and then in line 909. Right now I cannot think why this should be.
Proposed solution: remove the multiplication by cff5 and subsequent averaging. If one does that in line 909 we do
Code: Select all
rustr2d(i,j)=cff5*rustr3d(i,j,1)
Code: Select all
rustr2d(i,j)=rustr3d(i,j,1)
Code: Select all
rustr2d(i,j)=rustr2d(i,j)+cff5*rustr3d(i,j,k)
Code: Select all
rustr2d(i,j)=rustr2d(i,j)+rustr3d(i,j,k)
Code: Select all
rustr2d(i,j)=rustr2d(i,j)*cff3*cff4
Issue 4: After that the term rustr2d still diverge. One reason is that the integral is that the multiplication by Hz are not done in the same way in barotropic and baroclinic for UFe.
Proposed solution: replace
Code: Select all
UFe(i,j)=0.25_r8*(Hz(i,j ,k)+Hz(i-1,j,k)+ &
& Hz(i,j-1,k)+Hz(i-1,j-1,k))* &
& Sxyl_psi(i,j)
Code: Select all
UFe(i,j)=0.25_r8*(Hz(i,j,k)*Sxyl(i,j)+ &
& Hz(i-1,j,k)*Sxyl(i-1,j)+ &
& Hz(i-1,j-1,k)*Sxyl(i-1,j-1)+ &
& Hz(i,j-1,k)*Sxyl(i,j-1))
Issue 6: Now it remains to correct for ubar_stokes. The key formula is
Code: Select all
1/D int_0^D cosh(2kz)/sinh(2kD)dz = 1/(2kD)
Code: Select all
u_stokes(i,j,k)=cff2* &
& (wavenx(i-1,j)+wavenx(i,j))/ &
& (wavec (i-1,j)+wavec (i,j))* &
& COSH(cff3*fac2)*0.5_r8* &
& (o2sinh(i-1,j)+o2sinh(i,j))
Code: Select all
1/sinh((a+b)/2) <= 1/2sinh(a) + 1/2sinh(b)
Code: Select all
1/sinh(7.5) = 0.0011 and (1/sinh(5)+1/sinh(10))/2 = 0.0068
Code: Select all
*0.5_r8*(o2sinh(i-1,j)+o2sinh(i,j))
Code: Select all
/SINH(cff3)
Miscellaneous issues: In the computation of depth, the thermocline is not used. It is as if TCLINE=0. I.e. in the existing code we have
Code: Select all
fac2=1.0_r8+SCALARS(ng)%Cs_r(k)
COSH(kD(i,j)*fac2)
Code: Select all
COSH(waven(i,j)*z_r(i,j,k))
There is a code section #ifdef GEO_ROTATION ... #endif which is actually never triggered (top of file is #undef GEO_ROTATION). What was the idea or the problem there?
Modified file is in attachment. All comments welcomed.