Skip to content
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

Ice fraction in tracer flux calculations #97

Open
dougiesquire opened this issue Dec 13, 2023 · 5 comments
Open

Ice fraction in tracer flux calculations #97

dougiesquire opened this issue Dec 13, 2023 · 5 comments

Comments

@dougiesquire
Copy link

I'm very likely to be misunderstanding/missing something, but the calculation of gas and tracer fluxes in atmos_ocean_fluxes_calc_mod and atmos_ocean_dep_fluxes_calc_mod does not appear to account for fractional ice coverage. Unweighted fluxes (and related fields) are calculated for open water exchange cells, otherwise they are set to zero. E.g.

if (seawater(i) == 1.) then
gas_fluxes%bc(n)%field(fms_coupler_ind_kw)%values(i) =&
& gas_fluxes%bc(n)%param(1) * gas_fields_atm%bc(n)%field(fms_coupler_ind_u10)%values(i)**2
cair(i) = &
gas_fields_ice%bc(n)%field(fms_coupler_ind_alpha)%values(i) * &
gas_fields_atm%bc(n)%field(fms_coupler_ind_pCair)%values(i) * &
gas_fields_atm%bc(n)%field(fms_coupler_ind_psurf)%values(i) * gas_fluxes%bc(n)%param(2)
gas_fluxes%bc(n)%field(fms_coupler_ind_flux)%values(i) =&
& gas_fluxes%bc(n)%field(fms_coupler_ind_kw)%values(i) *&
& sqrt(660. / (gas_fields_ice%bc(n)%field(fms_coupler_ind_sc_no)%values(i) + epsln)) *&
& (gas_fields_ice%bc(n)%field(fms_coupler_ind_csurf)%values(i) - cair(i))
gas_fluxes%bc(n)%field(fms_coupler_ind_flux0)%values(i) =&
& gas_fluxes%bc(n)%field(fms_coupler_ind_kw)%values(i) *&
& sqrt(660. / (gas_fields_ice%bc(n)%field(fms_coupler_ind_sc_no)%values(i) + epsln)) *&
& gas_fields_ice%bc(n)%field(fms_coupler_ind_csurf)%values(i)
gas_fluxes%bc(n)%field(fms_coupler_ind_deltap)%values(i) =&
& (gas_fields_ice%bc(n)%field(fms_coupler_ind_csurf)%values(i) - cair(i)) / &
(gas_fields_ice%bc(n)%field(fms_coupler_ind_alpha)%values(i) * permeg + epsln)
else
gas_fluxes%bc(n)%field(fms_coupler_ind_kw)%values(i) = 0.0
gas_fluxes%bc(n)%field(fms_coupler_ind_flux)%values(i) = 0.0
gas_fluxes%bc(n)%field(fms_coupler_ind_flux0)%values(i) = 0.0
gas_fluxes%bc(n)%field(fms_coupler_ind_deltap)%values(i) = 0.0
cair(i) = 0.0
endif

Am I understanding correctly?

@thomas-robinson
Copy link
Member

@dougiesquire someone is looking into this more for you. We will get back to you soon.

@nikizadehgfdl
Copy link
Contributor

@dougiesquire I prepared a PR with the following comments that might explain what is happening with array "seawater". Note that "seawater" in the lines you quoted is the same as "ex_seawater" below which is passed as arg.
I brief, "seawater" is and stays 1: everywhere that there is open water and 0: everywhere that is totally ice covered.
Hence if(seawater(i) == 1.) ensures no flux exchange at the cells that are totally covered with seaice.

Hope that helps.

  !Generate a wet mask array on the xgrid which is:
  !       1: where there is any open water in the OCN grid cell
  !       0: where there is no  open water in the OCN grid cell, i.e., totally ice covered or land
  !This is a dynamic wet mask and particularly is not the same as a static land mask because seaice fractions change
  ! as the model runs.
  !One way to create such a mask is if 'OCN' puts an array on the xgrid which is
  ! 1 on every OCN grid cell with the 3rd index equal to 1 (ice category 1 corresponds to open water in the grid cell)
  ! 0 otherwise
  !This wet mask will be used to limit the air-sea flux exchange to areas that are not totally covered by seaice.
  sea = 0.0; sea(:,:,1) = 1.0;		   sea = 0.0; sea(:,:,1) = 1.0;
  ex_seawater = 0.0		   ex_seawater = 0.0
  call fms_xgrid_put_to_xgrid (sea,             'OCN', ex_seawater,    xmap_sfc)    call fms_xgrid_put_to_xgrid (sea, 'OCN', ex_seawater, xmap_sfc)

  !Question: Why is the above ex_seawater a dynamic mask array?
  !          From its construction it looks like a static array of 1s and 0s !
  !Answer: The xmap_sfc is dynamic and changes as the model steps because it contains updated information about
  !        seaice fractions. The updated array "ex_seawater" after the above "put" call will be 1 where there
  !        is open water even if those grid cells where previously closed by seaice.
  !        Particularly if we restrict xgrid calculations where  ex_seawater==1
  !        only cells with (partially or totally) open water contribute and totally covered cells won't contribute.

@dougiesquire
Copy link
Author

Thanks @nikizadehgfdl. My confusion is about cells where there is partial ice cover (i.e. both ice and open water). The flux at these cells should be weighted by (1 - ai), where ai is the fractional ice coverage of the grid cell, to account for the fact that some of the cell is covered with ice. Is this weighting done elsewhere, or not at all, or am I misunderstanding something?

@nikizadehgfdl
Copy link
Contributor

@dougiesquire yes that averaging of flux over open water fraction of grid cells happen when ATM gets the field from the exchange grid. This is how it happens:

  • The area of any xgrid cell at side1 (i.e.,ATM side) is scaled (at each timestep) by the open water fraction of the cell (see line 2954 of xgrid.F90) .

  • The area weighted averaging of the ATM fields happen at the get_from_xgrid calls (e.g., see line 3854 of xgrid.F90 .

For GFDL seaice (SIS2), the fraction of open water in OCN grid cell i,j is Ice%part_size(i,j,0) which is passed to xgrid module and sets f(i,j,1) in line 3129 of xgrid.F90 and then the xmap is updated with this info. So, I believe this f(i,j,1) is your 1-ai .

@dougiesquire
Copy link
Author

Thanks very much @nikizadehgfdl! This is what I was missing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants