Export values from OCN to ATM - nikizadehgfdl/FMScoupler GitHub Wiki

Plain Code Summary

Ice%ocean_fields%bc(ind_export2atm_obgc_chl)%field(ind_export_value_ice)%values --> Atm%fields%bc(ind_export2atm_obgc_chl)%field(ind_export_value_atm)%values

What is this about?

This is a scheme to make (array) values of some fields on OCN grid available (exported) to ATM grid. Particularly the goal is to make the concentration of Chlorophyll calculated by the Ocean component (ocean_BGC COBALT , on OCN grid) available inside the Atmosphere component (atmos_shared/tracer_driver, on ATM grid) for subsequent Chemistry calculations.

The scheme makes use of the existing coupler-tracer mechanism of FMS and FMScoupler. This mechanism is already in heavy use in the ESM models for exchanging air-sea fluxes between OCN and ATM for some tracers, particularly gas fluxes like CO2 and deposition fluxes such as iron-dust. However, these are in the form of fluxes , with particular flux treatment applied in surface boundary layer. It is the goal of this new scheme to make values (as opposed to fluxes) calculated on the OCN grid directly available on the ATM grid, after going through the exchange grid interpolations of course.

Implementation

Changes to the coupler

https://github.com/NOAA-GFDL/FMScoupler/compare/xanadu_esm4_20190304...nikizadehgfdl:export_value_ocn2atm?expand=1

  • Call a subroutine for flux_ocean_to_atmos just before atmos loop.
         git diff full/coupler_main.F90
     +  use flux_exchange_mod,       only: flux_ocean_to_atmos
         +      call flux_ocean_to_atmos(Time_atmos, Atm, Atmos_ice_boundary, Ice)
         do na = 1, num_atmos_calls
         ```
    
    
  • Add a new flux_type 'export_value' to the existing list (‘air_sea_deposition’,’land_sea_runoff', …)
git diff full/atmos_ocean_fluxes_calc.F90
        elseif (gas_fluxes%bc(n)%flux_type .eq. 'air_sea_deposition') then
           cycle !air_sea_deposition is done in another subroutine
+        elseif (gas_fluxes%bc(n)%flux_type .eq. 'export_value') then
+          cycle !export_value/direct method/implementation currently does not need any flux treatment
  • Add a subroutine for flux_ocean_to_atmos in coupler. This subroutine loops over Ice%ocean_fields%bc(n) (these are all the obgc tracers that have registered a flux_type), checks if the flux_type is of the new type 'export_value', in that case it put_to_xgrid the OCN value to be exported to atm (the value is set in ocean_BGC package). Then it get_from_xgrid the value on ATM grid. So basically it does
Atm%fields%bc(n)%field(ind_export_value_atm)%values = Ice%ocean_fields%bc(n)%field(ind_export_value_ice)%values

Changes to the ocean_BGC component (sender)

https://github.com/NOAA-GFDL/ocean_BGC/pull/9/files

  • Indicate that a generic tracer has a flux_type of the new kind 'export_value', by adding the extra arguments to the tracer call g_tracer_add. E.g.,
call g_tracer_add(tracer_list,package_name,&
          name       = 'chl',         &
          longname   = 'Chlorophyll', &
          units      = 'ug kg-1',     &
          prog       = .false.,       &
+         export2atm = .true.,        &
+         export2atm_name = 'export2atm_chl',   &
+         flux_param = (/ 1.0 /),     &
          init_value = 0.08           )

  • Initialize the value to be exported in the generic_*_set_boundary_values of the generic tracer package (e.g., COBALT)
+    !Loop over tracers and for the ones that are registered as "export2atm" set values to be exported to ATM 
+    g_tracer => tracer_list !Local pointer. Do not change the input pointer!
+    do
+       if(g_tracer%export2atm) then
+          call g_tracer_get_pointer(tracer_list,g_tracer%name, 'field', tr_field)     
+          allocate(g_exported2atm(isd:ied, jsd:jed)); g_exported2atm(:,:)=tr_field(:,:,1,tau)* cobalt%Rho_0 / 1e9
+          call g_tracer_set_values(tracer_list,g_tracer%name,  'exported2atm',g_exported2atm,isd,jsd)
+          deallocate(g_exported2atm)
+       endif
+       !traverse the linked list till hit NULL
+       if(.NOT. associated(g_tracer%next)) exit
+       g_tracer => g_tracer%next
+    enddo


   end subroutine generic_COBALT_set_boundary_values
  • Arrange for the coupler exchange of the exported value by adding a aof_set_coupler call in generic_tracer_utils subroutine g_tracer_flux_init
+    !The following aof call must match a corresponding call in ATM
+    !(e.g., atmos_tracer_driver module)
+    !for the flux name,type,implementation
+    if(g_tracer%export2atm) then
+       g_tracer%export2atm_ind  = aof_set_coupler_flux(g_tracer%export2atm_name,&
+            flux_type           = 'export_value',                                 &
+            implementation      = 'direct',                                     &
+            param               = g_tracer%flux_param,                          &
+            verbosity           = verbosity                                     &
+            )
+    endif
  end subroutine g_tracer_flux_init
  • Adding a set_coupler_values call in generic_tracer_utils subroutine
+       if(_ALLOCATED(g_tracer%exported2atm)) then
+          !This is to expose a field directly to ATM component
+          call set_coupler_values(g_tracer%exported2atm,   &
+               BC_struc   = IOB_struc,              &
+               BC_index   = g_tracer%export2atm_ind,  &
+               BC_element = ind_export_value_ice,         &
+               ilb=g_tracer_com%isd, jlb=g_tracer_com%jsd ,&
+               is=g_tracer_com%isc, ie=g_tracer_com%iec,&
+               js=g_tracer_com%jsc, je=g_tracer_com%jec &
+               )
+       endif

Changes to atmos_tracer_driver component (receiver)

https://gitlab.gfdl.noaa.gov/fms/atmos_phys/-/merge_requests/20/diffs

  • Add a subroutine atmos_obgc_flux_init with a aof_set_coupler_flux call to match the corresponding call in OBGC module for the flux name,type,implementation
ind_export2atm_obgc_chl = aof_set_coupler_flux(name='export2atm_chl',   &
 flux_type = 'export_value', implementation = 'direct',       &
caller = trim(mod_name) // '(' // trim(sub_name) // ')')
  • The exported value is ready for use in subroutine atmos_tracer_driver_gather_data as
gas_fields%bc(ind_export2atm_obgc_chl)%field(ind_export_value_atm)%values(:,:)
Where ind_export2atm_obgc_chl corresponds to the return value of aof_set call above and ind_export_value_atm is the same value used in OBGC get_from_xgrid call

Changes to FMS component

https://github.com/NOAA-GFDL/FMS/compare/xanadu_esm4_20190304...nikizadehgfdl:export_value_ocn2atm?expand=1

  • Add the new fux_type in coupler/atmos_ocean_fluxes.F90
  • Add the new indices to coupler_types.F90
integer, public :: ind_export_value_ice = 1 !< The field_index for
                       flux_type 'export_value' in Ice%ocean_fields%bc(n)%field(field_index)
 integer, public :: ind_export_value_atm = 1 !< The field_index for flux_type 'export_value' in Atm%fields%bc(n)%field(field_index)