-
Notifications
You must be signed in to change notification settings - Fork 132
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
flwout set to zero at ice free points #994
Comments
I have a solution. Let me know if you think this is ok. Basically, after merge_fluxes where lwout is computed, I make sure it never goes above the open ocean value (negative).
|
@kieranricardo - this might be relevant to you ? |
Actually I have this backwards. The reasonable range of temperatures in sea ice covered regions would be: -80C to 0C or 193.15 to 273.15K. So, this means a range of 79 W/m^2 to 316 W/m2. So, this should be: flwout = min(flwout, -79) since flwout is negative. |
Actually a better option is to add a check in scale_fluxes something like:
This makes sure to catch the one special case of a point going from ice-free to ice-covered and the flwout is zero. Dave |
I have a PR in for this now, but it occurs to me that there may be similar problems with fswabs, fsens, flat ... while a zero value is valid in these fields, we should technically be setting points that go from ice free to ice covered to have an open ocean value for these. For example, you can look in init_coupler_flux for some of these initial settings for different seasons. |
This doesn't solve you problem Dave, but I am slightly confused about the current behavior here. In scale_fluxes, if there is some ice (aice>0) then the exported longwave is the radiation from the ice only and doesn't include the ocean. However if there is no ice, then the exported longwave is the radiation from the ocean. These seems inconsistent. If the ice area is small, then the exported longwave is small (as it doesn't contain ocean longwave). If the ice area is zero, the longwave history output is large! This is in scale_fluxes, so I think it only impacts the history output ? Why isn't CICE/cicecore/cicedyn/general/ice_flux.F90 Lines 1263 to 1267 in 6aa677e
flwout just c0 ? |
This was super confusing! Took me a long time to figure this out. Let me try to explain.
So, for all points this is set to the lwout equivalent to 0C (273.15K)
This is everywhere so that flwout is computed as flwout = flwout + aicen(n)*flwoutn(n) for n=1,ncat in merge_fluxes. Since we are accumulating over subgridscale categories, this has to be initialized to zero.
where aice is the ice area at the end of the step. So, if flwout was not computed at the beginning of the step, then flwout is zero which is not physically possible. Does this make sense? |
It seems like there might be two different issues.
|
This is not really a conservation issue. What the atmosphere is receiving is: flwout_atm = aice * flwout_ice + (1-aice) * flwout_ocn Because aice is non-zero, this means the atmosphere can receive a zero flwout from the ice meaning a temperature of zero degree Kelvin! This is completely unphysical. You might think that aice is very small as it is the growth over one timestep, but in CESM we are seeing the ice area go from zero to 0.8 in a single timestep over all of Hudson Bay! |
It is a conservation error as you describe it. If aice is 0.0001 when ice first grows, one could argue the error is small. If aice is 0.8, that's interesting and significant, but in either case, it seems like the system is not conserving. Changing the flw from zero to something associated with the ocean temperature may be reducing the error, but it's not conserving the heat. The flw*aice that the coupler receives should match exactly the long wave flux "used" in sea ice in order to conserve. Going to and from aice=0 may be a problem that we cannot overcome give the current implementation constraints, so minimizing the error may be the best option. But I'm pretty sure there is a conservation error. I thought we were coupling the ice model each ice timestep to avoid these kinds of problems, in part by avoiding having to average (or similar) an ice fraction when some timesteps have zero ice fraction, but for other reasons related to ice state switching to/from zero ice fraction. I'm a little surprised this error has been in the implementation for so long. It must be quite small most of the time and especially when assessing conservation over longer periods. |
I agree this has been there a long time! They only recently added a check to the atmospheric radiation for this case. You do raise a good point in that the flwout should be computed based on the first temperature of the ice that forms in that timestep. Here we could use the Tsfc that is computed in the thermodynamics. |
When ice goes none->some or some->none, when is this formulated to occur in the timestep? Like, is it at the end of the timestep as a step function? |
So, the idea is that if you have no ice, this doesn't matter for the sea ice model or the atmosphere model. The ocean upward longwave is computed separately. So, it is arbitrary what one sets the open ocean values to. This is for history purposes only. Then the thermodynamics (step_therm1) is called to compute the surface fluxes only when there is ice at the beginning of the timestep. These fluxes are computed over the ITD categories and then a weighted sum to get the grid cell value:
where aicen_init is the category fraction at the beginning of the step. So, the fluxes (including flwout) must be zeroed out before we do this. However, the thermodynamics and then dynamics could create ice in the grid cell. The flux then is sent to the coupler / for history as:
where aice is the ice fraction at the end of the step. So, if aice_init is 0, but aice > 0, then you are never computing flwout and sending 0 to the coupler. This should actually be set to the open ocean value or computed using the updated surface temperature. Now if we have the situation that aice_init > 0, but aice = 0, this is not a problem, because then the flwout is set to the open ocean value in scale_fluxes and is not used by the atmosphere model. So, there is a step function in the first case, but not really in the second except for history output. Dave |
I agree with @apcraig, conservation should guide what the correction should be. Moreover, the conservation check should not be for a particular point in time (beginning/end of time step), but rather across an entire coupling interval and including all components' LW fluxes. Is that what CESM is now doing, @dabail10? The sea ice model was developed in isolation and so it conserves internally (or should), but there are time lags in the coupling that mean something is always going to be inconsistent in the coupled system, unless there's an iterated time barrier when they all resynchronize. E.g. we have what could be considered the first step of an iteration: we calculate albedo at both the beginning and the end of the ice model time step (also the coupling interval), first to have updated SW fluxes for the thermo calculation and then to ensure that the albedo sent to the coupler is consistent with the updated ice thickness distribution at the end of the time step. Perhaps the LW value sent to the coupler could be an average between the beginning of the time step and the end, assuming that the ice area grows or shrinks uniformly through the time step and the surface temperature stays at the value computed in the thermo; then using 0.5*(aice - aice_init) as the scaling factor might be a better approximation. (This could be refined further by assuming that the temperature changes linearly and estimating LW throughout the timestep based on that temperature evolution.) Regardless, I'd be interested in seeing a full conservation analysis to understand what's getting passed when in the coupled system(s), and where the inconsistencies are. |
There is already conservation across the CESM for lw fluxes. The lw that the atmosphere sees is: flwup_atm = fice * flwup_ice + focn * flwup_ocn + flnd * flwup_lnd This is the lower boundary condition for the longwave computation in the atmosphere. They do invert the LW up to check the surface temperature. This was where the issue was discovered. The temperature was far too low because the flwup_ice term was zero. Let's think about the coupling fluxes then. Step 1 (t = 0) fice = 0., focn = 1. flwup_atm = flwup_ocn Step 2 (t = 30min) fice = 0.6, focn = 0.4 flwup_atm = 0.6*flwup_ice + 0.4 * flwup_ocn In this case currently, flwup_ice = 0 which is unphysical. We have a couple of choices.
where flwup_ice* could be based on the freezing point, the current sst (same as flwup_ocn), or an ice surface temperature of 0C (273.15K), or some average of these. Dave |
I guess, I am not thinking of this as a conservation issue. One expects d(flwout) / dt to change from step to step. The atmosphere will use whatever it is given. I guess the "smoothest" transition is to go from SST to Tsfc on the ice? |
I do think there's a conservation issue. Consider I reached this conclusion through a derivation from a completely different direction that considered three area fractions, the ice area that doesn't change during the time step (if any), the ocean area that doesn't change (if any), and a transition area where either ice becomes open water or open water becomes ice. What I came up with is that the coupler should be multiplying the component fluxes by the initial surface area fractions (i.e. at the beginning of the time step) rather than the final fractions, for both ice and ocean. I can type up the derivation if you want to see it. An alternative would be to calculate Let me know if I'm doing something wrong here... |
Well, I should really have @duvivier and @marikaholland chime in here. The reason we divide by aice (and not aice_init) is so that the computation of: flwup_atm = aice * lwup_ice + (1-aice)*lwup_ocn where lwup_ice = sum(aicen_init(n)*flwupn_ice(n)) / aice. where aice is cancelled out in the first term as you pointed out. The ice fraction aice is the only fraction the atmosphere sees and is the only thing at a given step that can be used in the coupler. The flwup_ice is computed at the beginning of the timestep in the sea ice before the ice state changes. It is the surface energy budget that drives the thermodynamic changes to aice. We always have this timestep offset with the fluxes and the ice state at the end of the step. This is why the some of the fluxes used to get passed in the middle of the timestep before the ice state changed. However, all the coupling is done at the end of the timestep now. |
If the longwave the atmosphere receives needs to be lost by the ice (at the beginning of each ice timestep), it seems like aice_init is the relevant coupling ice_fraction (for longwave) Doesn't aice*fill_value send energy to atmosphere without any energy balance from ice or ocean? |
I see a mistake in my derivation, so let me think about this some more. |
In ice_flux.F90 (and icedrv_flux.F90 in icepack) we set flwout to zero so that it can be accumulated in merge_fluxes. However, there is a timestepping bug here such that if you have a point that goes from ice free to ice covered in a single timestep, then flwout will not be computed in merge_fluxes (because aicen_init is all zero) and stays zero. However, the coupler fluxes are passed based on aice, so for a single timestep flwout is passed to the coupler with a zero value. This causes a crash in CAM and likely is a problem in other atmospheric models. I'm not sure why this was never a problem before.
The solution is to remove the line:
flwout = c0
in ice_flux.F90 and icedrv_flux.F90 and only do this just before the call to merge_fluxes based on aice_init. Working on it now.
The text was updated successfully, but these errors were encountered: