-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CTSM runoff remapping issue again #426
Comments
@nmizukami there's a call in prep_phase for ROF in CMEPS but it's only for the irrigation field. So I don't think that can be the problem. There's also a single call to normalize in med_map_mod.F90 and I think that's the one we should comment out. This means the normalization will be off for all fields passed, but I would expect inland points to be fine. It'll be helpful to see if this makes inland points for mizuRoute look fine as well. Here's the git grep for that call..
|
Hi Erik (@ekluzek), Looks like commenting out /glade/scratch/mizukami/ctsm-mizuRoute/test_f09_f09_rHDMAlk_irr/run/cesm.log.2960367.chadmin1.ib0.cheyenne.ucar.edu.230830-171351 Maybe wondering if it is possible to set lrfaction to 1 everywhere? |
OK, giving you an untested change, didn't work out! I shouldn't have been surprised at that. And the solution is much more complicated, but I have a branch on CMEPS now with things I'm experimenting with that hopefully will help us diagnose the problem. |
Note, that frac_a and frac_b on the mapping files are both identically 1. So the lfrac must be computed based on mapping between the ocean-mask file and mizuRoute. Possibly this might be the problem. We might need to manage that process somehow... |
So here is ppt also including hcru_hcru_mt13, which runs mizuRoute using MOSART 0.5 degree network. Since this network is grid box, so online mapping (ESMF compute weight using ROF and LND mesh) can be done as well as offline mapping (still input weight mapping netcdf generated using my standalone tool). Sum of runoff over the global domain |
In looking at this we think the issue is that there is a mapping between the ocean grid/mask to the mizuRoute grid. The problem there is that mapping is from a complex ocean grid to the mizuRoute complex grid. As we have setup the model now the mizuRoute is expressed as a set of small squares around the center points of the complex HRU's for mizuRoute. Thus we can't really expect the mapping to be done correctly. However, we also can't easily create a mapping file with the script that @nmizukami to map between the CTSM regular grid and the mizuRoute grid. Because of the previous problems with having ESMF read the mizuRoute grid, we also don't think we can expect to have ESMF do the mapping between the ocean grid and mizuRoute to determine the land-frac on the mizuRoute grid. We thought of a few options that might work:
The 5th option may sound easy (and in the long run may still be the right thing to do), but it is a highly intensive operation for someone to simplify the HRU polygons and ensure that the simplified version still fits together exactly. Some work has been done on this and tools to help with this don't ensure that the polygons still fit together exactly. So an intensive operation has to be done to fix each polygon that overlaps another, or leaves free space. Since a lot of this has to be done by hand, it may take weeks to months of painstaking work to get something that will actually work. |
I also think a lot of the underlying issue here is #301. |
@billsacks suggests one way to do option 1, above is to comment out a section of code in CMEPS here... |
Thanks for laying out all of the options above. To clarify my comment: yes, this is the block of code that I'm guessing creates the bad mapping you're seeing, but I suspect you'll run into problems if you remove it... probably the model won't run at all, and if it does, I think you'll be breaking conservation. If you just want to get things running, you could remove that and do something like hard-coding lfrac on the rof grid, but we probably need a different long-term solution. Also note that, in that block of code in med_fraction_mod, it's actually mapping from the lnd grid to the rof grid. Your above comment talks about the problem being a mapping from the ocn grid to the rof grid. I'm not sure if that changes your analysis, or means that I didn't identify the right code that's causing the problem. |
Hi Bill. Thanks for the discussion this is all helpful. I'm unconvinced the problem is based on the mapping from LND to ROF -- because in that case the mapping should be coming from the mapping file we gave it. And we do think that part is working fine. Naoki also ran on the MOSART grid for mizuRoute and showed that the lfrac on the ROF grid in that case looks as expected both for regridding with a mapping file and with regridding on the fly. Which seems to show that both using the mapping file and the online regridding function correctly in terms of handling lfrac. It also verifies that Naoki's mapping file compares well with the ESMF online regridding. I was wondering if there was a problem with our mapping file for the complex grids and this shows that the process works well for the simple grid. And we wanted to make sure that lfrac on the ROF grid looked as expected for the simpler case. So I'm still thinking there must be a mapping from the ocean mask to the ROF grid and that must be where lfrac on the ROF grid comes from..... Does that sound right to you? |
I dug into this more. I can't find any mappings from ocn to rof (based on a search for 'ocn.*rof'), though it's possible that I'm missing something with my search. It sounds like the problem you're seeing is with By adding these extra prints to the code in a case with MOSART (I couldn't get things to run with mizuRoute so just tried with MOSART): diff --git a/mediator/med.F90 b/mediator/med.F90
index e7c6da9d..f17b393d 100644
--- a/mediator/med.F90
+++ b/mediator/med.F90
@@ -1800,6 +1800,7 @@ subroutine DataInitialize(gcomp, rc)
! Initialize route handles and required normalization field bunds
!---------------------------------------
call ESMF_LogWrite("before med_map_RouteHandles_init", ESMF_LOGMSG_INFO)
+ print *, 'WJS: about to call med_map_RouteHandles_init'
call med_map_RouteHandles_init(gcomp, is_local%wrap%flds_scalar_name, logunit, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_LogWrite("after med_map_RouteHandles_init", ESMF_LOGMSG_INFO)
diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90
index 2fd83972..272c5e5a 100644
--- a/mediator/med_fraction_mod.F90
+++ b/mediator/med_fraction_mod.F90
@@ -507,13 +507,18 @@ subroutine med_fraction_init(gcomp, rc)
! Set 'lfrac' in FBFrac(comprof)
if (is_local%wrap%comp_present(complnd)) then
+ print *, 'WJS: setting lfrac for comprof'
maptype = mapconsd
+ print *, 'WJS: checking for RH: ', complnd, comprof, maptype
if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,comprof,:),maptype, rc=rc)) then
+ print *, 'WJS: need to create RH'
call med_map_routehandles_init( complnd, comprof, &
FBSrc=is_local%wrap%FBImp(complnd,complnd), &
FBDst=is_local%wrap%FBImp(complnd,comprof), &
mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ else
+ print *, 'WJS: RH was already created'
end if
call ESMF_FieldBundleGet(is_local%wrap%FBfrac(complnd), 'lfrac', field=field_src, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90
index 18752dc2..096ea2a0 100644
--- a/mediator/med_map_mod.F90
+++ b/mediator/med_map_mod.F90
@@ -167,6 +167,7 @@ subroutine med_map_RouteHandles_initfrom_esmflds(gcomp, flds_scalar_name, llogun
if (mapindex /= mapunset) then
! determine if route handle has already been created
+ print *, 'WJS: in med_map_RouteHandles_initfrom_esmflds, checking mapexists: ', n1, n2, mapindex
mapexists = med_map_RH_is_created(is_local%wrap%RH,n1,n2,mapindex,rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return I think I understand better what's going on. In med_fraction_mod, the mappings are done with mapconsd (ESMF_NORMTYPE_DSTAREA). The other mappings all use mapconsf (ESMF_NORMTYPE_FRACAREA). Those other mappings are what I think you're providing in your pre-computed mapping files. Then the code gets into med_fraction_mod, asks if there is a mapconsd mapping from lnd -> rof, finds that the answer is no (because it only has a mapconsf mapping), and so creates a new lnd -> rof mapconsd mapping at runtime. These different normalization types are described here: But I haven't come to understand this. As a bit of an aside, but possibly relevant, I dug up an email from @mvertens from 3 years ago in the context of the lnd -> glc mapping where I asked about her use of mapconsf vs. mapconsd and she said:
But it seems like at least the lnd <-> rof mappings are still being done with mapconsf. I'm not sure if that's intentional. If the correct thing to do is to change all of these mappings to mapconsd, then I think it would resolve this issue because the mappings from the external mapping file would be taken as mapconsd, which would be consistent with the mapping of lfrac in med_fraction_mod. |
Awesome, thanks for tracking that down. We should be able to easily test if by using mapconsf mapping it resolves the issue with lfrac on the ROF grid for mizuRoute. As you and Mariana point out maybe it's really intended to always be mapconsf anyway. But, if that fixes it, we can at least add an option for it that we can turn on for mizuRoute cases. But, if you are right that it really should always be mapconsf, then we could make it always do that, and make sure it works for other ROF grids. |
To clarify: Mariana's message suggested that everything should be mapconsd. But your idea is still a good one for a test: change mapconsd to mapconsf for now in med_fraction_mod for the lnd -> rof mapping of lfrac and see if that resolves this issue. That may not be the right long-term solution, but it would be a good thing to try. |
@ekluzek and @nmizukami - I talked about this with @mvertens today. We can talk more tomorrow, but we agreed that a good first step would be to try the change suggested above – changing mapconsd to mapconsf for now in med_fraction_mod for the lnd -> rof mapping of lfrac and see if that resolves this issue. That probably isn't the right long-term solution, but in terms of confirming our understanding of what's going on, it would be very helpful to have that test done. Would you be able to do that before our meeting tomorrow? |
OK I ran a test that seems to work with results here: /glade/scratch/erik/SMS_D_Ld1.f09_f09_rHDMAlk_mg17.I2000Clm50SpMizGs.cheyenne_intel.mizuroute-default.20230905_104457_4b4dur/run/ The core code changes to med_fraction_mod.F90 look like this: @@ -508,7 +510,7 @@ subroutine med_fraction_init(gcomp, rc)
! Set 'lfrac' in FBFrac(comprof)
if (is_local%wrap%comp_present(complnd)) then
- maptype = mapconsd
+ maptype = mapconsf
if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,comprof,:),maptype, rc=rc)) then
call med_map_routehandles_init( complnd, comprof, &
FBSrc=is_local%wrap%FBImp(complnd,complnd), &
@@ -518,10 +520,21 @@ subroutine med_fraction_init(gcomp, rc)
end if
call ESMF_FieldBundleGet(is_local%wrap%FBfrac(complnd), 'lfrac', field=field_src, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ call field_getdata1d(field_src, lfrac, rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ if ( (minval(lfrac) < -eps_fraclim) .or. (maxval(lfrac) > 1._r8+eps_fraclim) )then
+ call shr_sys_abort( "lfrac on the LND grid is out of bounds" )
+ end if
call ESMF_FieldBundleGet(is_local%wrap%FBfrac(comprof), 'lfrac', field=field_dst, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call med_map_field(field_src, field_dst, is_local%wrap%RH(complnd,comprof,:), maptype, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ call field_getdata1d(field_dst, lfrac, rc)
+ if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ if ( (minval(lfrac) < -eps_fraclim) .or. (maxval(lfrac) > 1._r8+eps_fraclim) )then
+ write(logunit,*) 'minval, maxval of lfrac = ', minval(lfrac), maxval(lfrac)
+ call shr_sys_abort( "lfrac on the ROF grid is out of bounds" )
+ end if
endif
endif
The reason I say I think it's working is that as you see above I check if the lfrac on ROF and LND grids are out of range and abort if they do. The case before the change to mapconsf that check fails on the ROF grid, but once I set it to mapconsf it PASSes. And I see that the ROF lfrac is within bounds on the CPL hist file. |
Hi @ekluzek and @billsacks, I mapped the Erik's run including the above change (mapconsd -> mapconsf). I plotted Only difference is Erik's run does not have >1 |
I also actually changed My case is |
OK, so in your case you just changed the map type without the other changes I had to check the lfrac range. The only thing I can think of is that maybe the lfrac pointer I got was somehow corrupting the values. A simple change I could make is to nullify the pointer after I do the check. That is of course a good practice to do anyway. And maybe I need to leave it in the state where lfrac is set to the LND version of lfrac, as maybe it needs that later on... |
…onsd mapping, this resolves mizuRoute issue: ESCOMP/mizuRoute#426, which is ESCOMP#409
We found incorrect runoff mapping from LND to ROF again. This powerpoint shows the problem
cmep_history.pptx
What we did:
rofExp_Flrl_rofsub
+rofExp_Flrl_rofsur
+rofExp_Flrl_rofgwl
) in coupler history file to map them on mizuRoute grid and also mapMed_frac_rof_lfrac
What we found:
Med_frac_rof_lfrac
spatial pattern does not look correct and there is also >1 fraction.Additional information:
mizuRoute uses pre-computed mapping file, not internally computed using ROF mesh and LND mesh.
The text was updated successfully, but these errors were encountered: