Scheduled Downtime
On Friday 21 April 2023 @ 5pm MT, this website will be down for maintenance and expected to return online the morning of 24 April 2023 at the latest

RUC land surface scheme is updating the ocean surface roughness

This post was from a previous version of the WRF&MPAS-A Support Forum. New replies have been disabled and if you have follow up questions related to this post, then please start a new thread from the forum home page.


New member
Our group is recently trying to couple WRF with an ocean model. We first used MM5 surface layer scheme + RUC land surface scheme in our simulations. We found that the ZNT (surface roughness) field is not updating in the ocean as we wanted. When we used Noah or Noah MP schemes, the ZNT is what we expected.

We then tried to look at the code ( It seems that the RUC scheme will restore the ZNT to its original value (in SOILVEGEN function, line 6600 to 7076). Is it a bug in the RUC scheme? Should RUC modify the ocean ZNT? Is it OK that we modify the code and do not update ZNT in the ocean?

We were using, but the newest version also had this issue:
The GitHub link you pointed to is an old one that is not actually supported by our group anymore. Try this one:

The code, including that particular subroutine in the RUC LSM file, has been updated quite a bit since then. Can you try the latest version and see if you are still having the same problem? The latest version is V4.1.1.
I installed the up-to-date version of WRF from and tested it again.

I saw a lot of updates in the RUC LSM file, but the RUC LSM is still updating the ocean surface roughness. It is still the problem of SOILVEGIN function. If we comment off this function, we are not going to have this problem (but the RUC is not updating the land).
I just want to get clarification. The first post you made said that the RUC model was NOT updating ZNT. But in the recent post you said the problem still exists in the newer code, and that the RUC model is still updating ZNT. I don't know if one of the posts has a typo, so I just wanted to make sure I understand what you are expecting to see. Do you want ZNT to be updated, or not?
1. We want to hack the ocean ZNT in MM5 and MYNN;
2. The RUC will change the 'hacked ZNT' to the default value in VEGPARM.TBL file.

We don't want RUC to modify the ocean ZNT. We believe RUC is a land surface model, it should not modify the ocean.

When we use RUC, ZNT will set the ocean ZNT to the default value every time step. The RUC is modifying the ZNT in the SOILVEGIN function in both WRF versions. Is it a bug?
Thank you very much for the explanation. That helped me to understand better.
I know you said that you tested out the most recent version of the code, but I found that beginning with V4.0.2, there was actually a bug fix for this in module_sf_ruclsm.F. Inside the SOILVEGIN subroutine, this code is found:

  if( then
!-- 20aug18 - change in LAItoday based on the greenness fraction for the current day
        LAItoday(k) = LAITBL(K) - deltalai(k) * factor

         if(IFORTBL(k) == 7) then
!-- seasonal change of roughness length for crops 
           ZNTtoday(k) = Z0TBL(K) - 0.125 * factor
           ZNTtoday(k) = Z0TBL(K)
        LAItoday(k) = LAITBL(K)
!        ZNTtoday(k) = Z0TBL(K)
        ZNTtoday(k) = ZNT ! do not overwrite z0 over water with the table value

So it looks like it's specifically telling the model that if a point is a water point, to not overwrite it using the table values. Are you certain that it's still being overwritten for these later versions?

Yes, I saw it in line 6800. But the RUC still modifies the ocean in our code experiment.

I am not sure what will happen in line 6839, where 'iswater' mask is not used to protect ZNT from being overwritten.

      if(mosaic_lu == 1) then
      do k = 1,nlcat
        AREA  = AREA + lufrac(k)
        EMISS = EMISS+ LEMITBL(K)*lufrac(k)
        ZNT   = ZNT  + lufrac(k)/ALOG(LB/ZNTtoday(K))**2.
! ZNT1 - weighted average in the grid box, not used, computed for comparison
        ZNT1  = ZNT1 + lufrac(k)*ZNTtoday(K)
        if(.not.rdlai2d) LAI = LAI  + LAItoday(K)*lufrac(k)
        PC    = PC   + PCTBL(K)*lufrac(k)
I apologize for the delay in response. We were out of the office and since returning, have been preparing for our upcoming WRF tutorial next week, so we have gotten a bit behind.

You originally asked if it should be okay to modify the code, manually, to allow ZNT to behave as you'd like. Yes, this should be an okay alternative. Are you able to do this and move forward? If so, just make sure to check the output to verify that everything looks okay.