Is the sign convention for net shortwave and longwave radiation positive upward, or downward? That is, if swrad or lwrad is positive, does that heat the ocean in ROMS?
Any additional info on sign convention and fluxes for ROMS would be greatly appreciated.
Thanks
Steve
sign convention for radiation
Re: sign convention for radiation
There is a bit of logical inconsistency within ROMS convention, but as the result, it makes it more
in line with oceanographic tradition, and somewhat with common sense.
The rules are:
 Positive direction of vertical axis Z is upward.
 Model INTERNAL fluxes are positive if they are pointing UPWARD, e.g., that is positive vertical
velocity is upward; positive diffusive heat flux between two verticallyadjacent grid boxes means
that it moves heat upward, that is it cools lower grid box, and warms up the upper upper.
conversely,
 EXTERNAL forcing fluxes at/near free surface [e.g., wind stress, latent heat flux, salinity flux
(inverted freshwater flux), shortwave radiation, etc] are positive when pointed DOWNWARD. That is,
positive latent heat flux causes warming up the uppermost grid box. Shortwave radiation flux (which
is always positive) moves heat downward, that is, it causes warming up the uppermost grid box, and,
once penetrating below the surface, it moves heat downward by removing it from upper box at each
interface and applying it to the lower grid box.
For this purpose, nonlocal (sometimes called countergradient "ghat") heat flux withing the
unstablyforced boundary layer as parameterized by KPP is considered EXTERNAL forcing, that it is
negative when moving heat upward (which is always the case, because it occurs only when boyancy
forcing is unstable, i.e., cooling at top). "ghat" is always proportional to the corresponding
surface forcing flux times a nonnegative nondimensional shape function.
however,
 Bottom fluxes, like bottom drag are considered as internally generated by the model, and therefore
obey the normal "internal" rules.
Other oceanic models, like MOM/POP, POM, MICOM have their Zaxis pointing downward, which result in
a more consistent rule about the fluxes (internal and external forcing are both positive if pointing downward).
Akwardly, freesurface elevation is still positive, if it is above the mean level. ROMS conventions are
basically like that because of inheritance of many parameterizations from other models.
in line with oceanographic tradition, and somewhat with common sense.
The rules are:
 Positive direction of vertical axis Z is upward.
 Model INTERNAL fluxes are positive if they are pointing UPWARD, e.g., that is positive vertical
velocity is upward; positive diffusive heat flux between two verticallyadjacent grid boxes means
that it moves heat upward, that is it cools lower grid box, and warms up the upper upper.
conversely,
 EXTERNAL forcing fluxes at/near free surface [e.g., wind stress, latent heat flux, salinity flux
(inverted freshwater flux), shortwave radiation, etc] are positive when pointed DOWNWARD. That is,
positive latent heat flux causes warming up the uppermost grid box. Shortwave radiation flux (which
is always positive) moves heat downward, that is, it causes warming up the uppermost grid box, and,
once penetrating below the surface, it moves heat downward by removing it from upper box at each
interface and applying it to the lower grid box.
For this purpose, nonlocal (sometimes called countergradient "ghat") heat flux withing the
unstablyforced boundary layer as parameterized by KPP is considered EXTERNAL forcing, that it is
negative when moving heat upward (which is always the case, because it occurs only when boyancy
forcing is unstable, i.e., cooling at top). "ghat" is always proportional to the corresponding
surface forcing flux times a nonnegative nondimensional shape function.
however,
 Bottom fluxes, like bottom drag are considered as internally generated by the model, and therefore
obey the normal "internal" rules.
Other oceanic models, like MOM/POP, POM, MICOM have their Zaxis pointing downward, which result in
a more consistent rule about the fluxes (internal and external forcing are both positive if pointing downward).
Akwardly, freesurface elevation is still positive, if it is above the mean level. ROMS conventions are
basically like that because of inheritance of many parameterizations from other models.

 Posts: 7
 Joined: Thu Sep 25, 2008 5:47 pm
 Location: FSU COAPS
Re: sign convention for radiation
This sign convention is correct for Steve's case (positive radiation is to the ocean, i.e. warms the ocean), when he is using bulk fluxes. However, this does not seem to work in my case. I have a flatbottom stratified ocean. The ocean is forced only by a uniform in space and constant in time heat flux 200 W/m2 (defined SOLAR_SOURCE). This is the only radiation term defined in the model. After 30 days of the run, the surface temperature has cooled by 1.5 degrees. I checked "srflx" and "swdk" in pre_step3d.F and looked at their values printed on the screen during the computation, they are both positive. Somehow they result in ocean cooling. When I switch the sign of the heat flux (200), the ocean starts warming. Any ideas what is going on with heat fluxes?
Re: sign convention for radiation
It depends upon which code are you using. But it easy to track it down
in all three cases.
Let's Check it out.
Rutgers (say. v. 3.1): file pre_step3d.F: array "swdk" is assigned
its value at/near line 345, and it is a positivedefinite field. Then it
is used at about line 784, an now observe the evolution of field "FC" [which
is initialized as "minus diffusive flux" in vertical direction (meaning
positive FC warms upper grid box and cools lower, hence moves hear upward;
also note that the standard definition of diffusive flux in physics would
be flux =  Akt * dT/dz with negative sign in front) starting at
approximately like 763 (I skip all loops comments, and other statements
to keep it clean:
after which FC(:,:) is discarded. So, given that cff3 above is positive
(which is always the case, since lambda < 1.), FC(i,k) at line 763 is
initialized as the explicit portion of minis diffusive flux then NONLOCAL
flux is added [different versions of KPP define "ghats" differently, so
let's ignore it for a moment. A rule of thumb here is that IT MUST ALWAYS
MOVE HEAT UPWARD, since it is either cooling at surface, or "ghats" is zero.
...A useful hint here is that the effect of the nonlocal flux is basically
that it acts as "bodyforce" which removes heat from the entire Surface
Boundary Layer (SBL) in the case of unstable bouyancy forcing instead of
just removing it from the surface, and let diffusion do the rest of the job.
So in the values in array "ghats" in the code above must be negative or
zero. There is also a bit of confusion caused by the formulation of "ghat"
in LMD1994 paper itself: there ghats is proportional to mixing coefficient
"Akt" within SBL, and identically zero below it. This also implies that
the whole nonlocal flux smoothly vanishes at the base of SBL, which is the
case when "Akt" vanishes as well. However, in the general case "Akt" does
not vanish at the base of SBL, but matches the internal mixing coefficient
computed from its own rules (gradient Richardson Number, etc). This cases
an abrupt change in ghats, and, consequently, a spike in the divergence of
the nonlocal flux. The remedy is to compute the nonlocal flux using its
own independent from Akt shape function (which always smoothly goes to zero
at the base of SBL), rather than set it to be proportional to "Akt"].
Then, at line 784 "srflx" is added in. It can be consistently interpreted
as "minus diffusive flux". Then boundary conditions, and finally the fluxes
are applied to each grid box at the line 803.
It is easy to see that in this code: (a) positive stflx(i,j,itrc) increases
t(i,j,k,nnew,itrc); (b) positive srflx(i,j) along with swdk(i,j,k)
decreasing downward warm up all grid boxes below, because the contribution
of srflx(i,j)*swdk(i,j,k) into FC makes a positive contribution
into FC(i,k)FC(i,k1). So everything should be OK.
AGRIF The treatment of stflx, srflx, swdk is basically identical,
except that it is moved from pre_step3d.F to step3d_t.F, and there is no
provision of lambda <1 setting (in essense, the code always use backward
Euler step for diffusion) because long time ago it was identified that
using anything but lambda=1 is a source of vertical gridpoint noise in
the case when Akt has sharp changed in vrtical (always the case at the
base of boundary layer with vertical realistic resolution, say N=20...40).
Consequently, the code corresponding to "1lambda" part of FC was
permanentle deleted.
So in step3d_t of Agrif we see
i.e., all signs are the same as in Rutgers code above.
WARNING: "ghats" stuff is incorrect in this code and cannot be correct
because, because array "ghats" the same for temperature and salinity, so,
consequently, contribution of "ghats" into FC for temperature and FC for
salinity,
and
unavoidably have the same dimension. FCs for T and and FCs for S should
have different dimensions.
UCLA Similarly, stflx, srflx, swdk stuff occurs in step3d_t3S.F, but
the code is simplified by excluding intermediate variables (note that array
"FC" is gone, and bottom boundary consition is always assumed noflux, hence
arrays stflx(i,j,itrc) are eliminated entirely).
Again, now it is VERY obvious that positive stflx warms up
t(i,j,N,nnew,itrc), and so does positive srflx(i,j)*swr_frac(i,j,k)
(the meaning of "swr_frac" is similar to "swdk").
Note that the array "ghats" is also common to temperature and salinity,
but its meaning is entirely different: it is merely a nondimensional
shape function, and it is multiplied by either heat flux (latent part
only) or salinity flux to contribute into each tracer field. It is NOT
multiplied by Akt of that tracer, unlike in LMD1994 paper.
in all three cases.
Let's Check it out.
Rutgers (say. v. 3.1): file pre_step3d.F: array "swdk" is assigned
its value at/near line 345, and it is a positivedefinite field. Then it
is used at about line 784, an now observe the evolution of field "FC" [which
is initialized as "minus diffusive flux" in vertical direction (meaning
positive FC warms upper grid box and cools lower, hence moves hear upward;
also note that the standard definition of diffusive flux in physics would
be flux =  Akt * dT/dz with negative sign in front) starting at
approximately like 763 (I skip all loops comments, and other statements
to keep it clean:
Code: Select all
cff3=dt(ng)*(1.0_r8lambda)
...
cff=1.0_r8/(z_r(i,j,k+1)z_r(i,j,k))
FC(i,k)=cff3*cff*Akt(i,j,k,ltrc)* &
& (t(i,j,k+1,nstp,itrc) &
& t(i,j,k ,nstp,itrc))
# ifdef LMD_NONLOCAL
FC(i,k)=FC(i,k)dt(ng)*Akt(i,j,k,ltrc)*ghats(i,j,k,ltrc)
# endif
.....
FC(i,k)=FC(i,k)+dt(ng)*srflx(i,j)*swdk(i,j,k) !< line 784
.....
FC(i,0)=dt(ng)*btflx(i,j,itrc) !< these are boundary
FC(i,N(ng))=dt(ng)*stflx(i,j,itrc) !< conditions
.....
cff1=Hz(i,j,k)*t(i,j,k,nstp,itrc)
cff2=FC(i,k)FC(i,k1)
t(i,j,k,nnew,itrc)=cff1+cff2 !< line 803
# ifdef TS_MPDATA
t(i,j,k,3,itrc)=t(i,j,k,nnew,itrc)/Hz(i,j,k)
# endif
(which is always the case, since lambda < 1.), FC(i,k) at line 763 is
initialized as the explicit portion of minis diffusive flux then NONLOCAL
flux is added [different versions of KPP define "ghats" differently, so
let's ignore it for a moment. A rule of thumb here is that IT MUST ALWAYS
MOVE HEAT UPWARD, since it is either cooling at surface, or "ghats" is zero.
...A useful hint here is that the effect of the nonlocal flux is basically
that it acts as "bodyforce" which removes heat from the entire Surface
Boundary Layer (SBL) in the case of unstable bouyancy forcing instead of
just removing it from the surface, and let diffusion do the rest of the job.
So in the values in array "ghats" in the code above must be negative or
zero. There is also a bit of confusion caused by the formulation of "ghat"
in LMD1994 paper itself: there ghats is proportional to mixing coefficient
"Akt" within SBL, and identically zero below it. This also implies that
the whole nonlocal flux smoothly vanishes at the base of SBL, which is the
case when "Akt" vanishes as well. However, in the general case "Akt" does
not vanish at the base of SBL, but matches the internal mixing coefficient
computed from its own rules (gradient Richardson Number, etc). This cases
an abrupt change in ghats, and, consequently, a spike in the divergence of
the nonlocal flux. The remedy is to compute the nonlocal flux using its
own independent from Akt shape function (which always smoothly goes to zero
at the base of SBL), rather than set it to be proportional to "Akt"].
Then, at line 784 "srflx" is added in. It can be consistently interpreted
as "minus diffusive flux". Then boundary conditions, and finally the fluxes
are applied to each grid box at the line 803.
It is easy to see that in this code: (a) positive stflx(i,j,itrc) increases
t(i,j,k,nnew,itrc); (b) positive srflx(i,j) along with swdk(i,j,k)
decreasing downward warm up all grid boxes below, because the contribution
of srflx(i,j)*swdk(i,j,k) into FC makes a positive contribution
into FC(i,k)FC(i,k1). So everything should be OK.
AGRIF The treatment of stflx, srflx, swdk is basically identical,
except that it is moved from pre_step3d.F to step3d_t.F, and there is no
provision of lambda <1 setting (in essense, the code always use backward
Euler step for diffusion) because long time ago it was identified that
using anything but lambda=1 is a source of vertical gridpoint noise in
the case when Akt has sharp changed in vrtical (always the case at the
base of boundary layer with vertical realistic resolution, say N=20...40).
Consequently, the code corresponding to "1lambda" part of FC was
permanentle deleted.
So in step3d_t of Agrif we see
Code: Select all
FC(i,N)=dt*stflx(i,j,itrc) !< line 517
....
FC(i,k)=dt*srflx(i,j)*swdk(i,j,k) !< line 533
# ifdef LMD_NONLOCAL
& dt*Akt(i,j,k,itemp)*ghats(i,j,k)
# endif
....
....
t(i,j,k,nnew,itrc)=t(i,j,k,nnew,itrc)+FC(i,k ) !< line 552
& FC(i,k1)
WARNING: "ghats" stuff is incorrect in this code and cannot be correct
because, because array "ghats" the same for temperature and salinity, so,
consequently, contribution of "ghats" into FC for temperature and FC for
salinity,
Code: Select all
dt*Akt(i,j,k,itemp)*ghats(i,j,k)
Code: Select all
dt*Akt(i,j,k,itsalt)*ghats(i,j,k)
have different dimensions.
UCLA Similarly, stflx, srflx, swdk stuff occurs in step3d_t3S.F, but
the code is simplified by excluding intermediate variables (note that array
"FC" is gone, and bottom boundary consition is always assumed noflux, hence
arrays stflx(i,j,itrc) are eliminated entirely).
Code: Select all
do i=istr,iend
t(i,j,N,nnew,itrc)=t(i,j,N,nnew,itrc)+dt*stflx(i,j,itrc)
enddo
# ifdef LMD_KPP
if (itrc.eq.itemp) then
do k=N1,1,1
do i=istr,iend
cff=srflx(i,j)*swr_frac(i,j,k)
# ifdef LMD_NONLOCAL
& ghat(i,j,k)*(stflx(i,j,itemp)srflx(i,j))
# endif
t(i,j,k+1,nnew,itemp)=t(i,j,k+1,nnew,itemp) dt*cff
t(i,j,k ,nnew,itemp)=t(i,j,k ,nnew,itemp) +dt*cff
enddo
enddo
# if defined LMD_NONLOCAL && defined SALINITY
elseif (itrc.eq.isalt) then
do k=N1,1,1
do i=istr,iend
cff=dt*ghat(i,j,k)*stflx(i,j,isalt)
t(i,j,k+1,nnew,isalt)=t(i,j,k+1,nnew,isalt) cff
t(i,j,k ,nnew,isalt)=t(i,j,k ,nnew,isalt) +cff
enddo
enddo
# endif
endif
t(i,j,N,nnew,itrc), and so does positive srflx(i,j)*swr_frac(i,j,k)
(the meaning of "swr_frac" is similar to "swdk").
Note that the array "ghats" is also common to temperature and salinity,
but its meaning is entirely different: it is merely a nondimensional
shape function, and it is multiplied by either heat flux (latent part
only) or salinity flux to contribute into each tracer field. It is NOT
multiplied by Akt of that tracer, unlike in LMD1994 paper.