!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! !!
!! GNU General Public License !!
!! !!
!! This file is part of the Flexible Modeling System (FMS). !!
!! !!
!! FMS is free software; you can redistribute it and/or modify !!
!! it and are expected to follow the terms of the GNU General Public !!
!! License as published by the Free Software Foundation. !!
!! !!
!! FMS is distributed in the hope that it will be useful, !!
!! but WITHOUT ANY WARRANTY; without even the implied warranty of !!
!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !!
!! GNU General Public License for more details. !!
!! !!
!! You should have received a copy of the GNU General Public License !!
!! along with FMS; if not, write to: !!
!! Free Software Foundation, Inc. !!
!! 59 Temple Place, Suite 330 !!
!! Boston, MA 02111-1307 USA !!
!! or see: !!
!! http://www.gnu.org/licenses/gpl.txt !!
!! !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!----------------------------------------------------------------
! Niki Zadeh
!
!
! William Cooke
!
!
! Ocean Carbon Model Intercomparison Study II: CFC module
! This module contains the generic version of CFC Tracers and their chemistry.
! It is designed so that both GFDL Ocean models, GOLD and MOM, can use it.
! The chemistry calculations in this module are ported from MOM ocmip2_cfc.F90
! released in omsk_2008_03
!
!
!
! Implementation of routines to solve the OCMIP-2 CFC
! simulations as outlined in the CFC-HOWTO documentation,
! revision 1.6, 1999/04/29.
!
!
!
!
! http://www.ipsl.jussieu.fr/OCMIP/phase2/simulations/CFC/HOWTO-CFC.html
!
!
! nnz:
! A. Reproducing GOLD results
! The tracers in this module reproduce the corresponding ones
! in non-generic module GOLD_OMIP2_CFC.F90 with branch tag perth_gas_fluxes_nnz.
! The reproducing of non-generic tracers in this case is sufficient evidence for the consistency of vertical diffusion
! (tracer_vertdiff) routine used in the two cases.
!
! B. Reproducing MOM results
!
!
!
!
!----------------------------------------------------------------
module generic_CFC
use coupler_types_mod, only: coupler_2d_bc_type
use field_manager_mod, only: fm_string_len
use mpp_mod, only : mpp_error, NOTE, WARNING, FATAL, stdout
use time_manager_mod, only : time_type
use fm_util_mod, only: fm_util_start_namelist, fm_util_end_namelist
use g_tracer_utils, only : g_tracer_type,g_tracer_start_param_list,g_tracer_end_param_list
use g_tracer_utils, only : g_tracer_add,g_tracer_add_param, g_tracer_set_files
use g_tracer_utils, only : g_tracer_set_values,g_tracer_get_pointer,g_tracer_get_common
use g_tracer_utils, only : g_tracer_coupler_set,g_tracer_coupler_get
use g_tracer_utils, only : g_tracer_send_diag, g_tracer_get_values
implicit none ; private
character(len=fm_string_len), parameter :: mod_name = 'generic_CFC'
character(len=fm_string_len), parameter :: package_name = 'generic_cfc'
public do_generic_CFC
public generic_CFC_register
public generic_CFC_init
public generic_CFC_update_from_coupler
public generic_CFC_update_from_source
public generic_CFC_set_boundary_values
public generic_CFC_end
!The following logical for using this module is overwritten
! by generic_tracer_nml namelist
logical, save :: do_generic_CFC = .false.
real, parameter :: epsln=1.0e-30
!
!This type contains all the parameters and arrays used in this module.
!
!Note that there is no programatic reason for treating
!the following as a type. These are the parameters used only in this module.
!It suffices for varables to be a declared at the top of the module.
!nnz: Find out about the timing overhead for using type%x rather than x
type generic_CFC_params
real :: a1_11, a2_11, a3_11, a4_11 ! Coefficients in the calculation of the
real :: a1_12, a2_12, a3_12, a4_12 ! CFC11 and CFC12 Schmidt numbers, in
! units of ND, degC-1, degC-2, degC-3.
real :: d1_11, d2_11, d3_11, d4_11 ! Coefficients in the calculation of the
real :: d1_12, d2_12, d3_12, d4_12 ! CFC11 and CFC12 solubilities, in units
! of ND, K-1, log(K)^-1, K-2.
real :: e1_11, e2_11, e3_11 ! More coefficients in the calculation of
real :: e1_12, e2_12, e3_12 ! the CFC11 and CFC12 solubilities, in
! units of PSU-1, PSU-1 K-1, PSU-1 K-2.
real :: Rho_0
character(len=fm_string_len) :: ice_restart_file
character(len=fm_string_len) :: ocean_restart_file,IC_file
end type generic_CFC_params
type(generic_CFC_params) :: param
contains
subroutine generic_CFC_register(tracer_list)
type(g_tracer_type), pointer :: tracer_list
character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_register'
!Specify all prognostic and diagnostic tracers of this modules.
call user_add_tracers(tracer_list)
end subroutine generic_CFC_register
!
!
! Initialize the generic CFC module
!
!
! This subroutine:
! Adds all the CFC Tracers to the list of generic Tracers passed to it via utility subroutine g_tracer_add().
! Adds all the parameters used by this module via utility subroutine g_tracer_add_param().
! Allocates all work arrays used in the module.
!
!
! call generic_CFC_init(tracer_list)
!
!
! Pointer to the head of generic tracer list.
!
!
subroutine generic_CFC_init(tracer_list)
type(g_tracer_type), pointer :: tracer_list
character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_init'
!Specify and initialize all parameters used by this package
call user_add_params
!Allocate and initiate all the private work arrays used by this module.
! call user_allocate_arrays !None for CFC module currently
end subroutine generic_CFC_init
subroutine user_allocate_arrays
!Allocate all the private arrays.
!None for CFC module currently
end subroutine user_allocate_arrays
!
! This is an internal sub, not a public interface.
! Add all the parameters to be used in this module.
!
subroutine user_add_params
!Specify all parameters used in this modules.
!==============================================================
!User adds one call for each parameter below!
!User also adds the definition of each parameter in generic_CFC_params type
!==============================================================
!=============
!Block Starts: g_tracer_add_param
!=============
!Add the known experimental parameters used for calculations
!in this module.
!All the g_tracer_add_param calls must happen between
!g_tracer_start_param_list and g_tracer_end_param_list calls.
!This implementation enables runtime overwrite via field_table.
call g_tracer_start_param_list(package_name)
!-----------------------------------------------------------------------
! Schmidt number coefficients
! Use coefficients given by Zheng et al (1998), JGR vol 103, C1
! for CFC11 and CFC12
!-----------------------------------------------------------------------
! g_tracer_add_param(name , variable , default_value)
call g_tracer_add_param('a1_11', param%a1_11, 3501.8)
call g_tracer_add_param('a2_11', param%a2_11, -210.31)
call g_tracer_add_param('a3_11', param%a3_11, 6.1851)
call g_tracer_add_param('a4_11', param%a4_11, -0.07513)
call g_tracer_add_param('a1_12', param%a1_12, 3845.4)
call g_tracer_add_param('a2_12', param%a2_12, -228.95)
call g_tracer_add_param('a3_12', param%a3_12, 6.1908)
call g_tracer_add_param('a4_12', param%a4_12, -0.067430)
!-----------------------------------------------------------------------
! Solubility coefficients for alpha in mol/l/atm
! (1) for CFC11, (2) for CFC12
! after Warner and Weiss (1985) DSR, vol 32 for CFC11 and CFC12
!-----------------------------------------------------------------------
call g_tracer_add_param('d1_11', param%d1_11, -229.9261)
call g_tracer_add_param('d2_11', param%d2_11, 319.6552)
call g_tracer_add_param('d3_11', param%d3_11, 119.4471)
call g_tracer_add_param('d4_11', param%d4_11, -1.39165)
call g_tracer_add_param('e1_11', param%e1_11, -0.142382)
call g_tracer_add_param('e2_11', param%e2_11, 0.091459)
call g_tracer_add_param('e3_11', param%e3_11, -0.0157274)
call g_tracer_add_param('d1_12', param%d1_12, -218.0971)
call g_tracer_add_param('d2_12', param%d2_12, 298.9702)
call g_tracer_add_param('d3_12', param%d3_12, 113.8049)
call g_tracer_add_param('d4_12', param%d4_12, -1.39165)
call g_tracer_add_param('e1_12', param%e1_12, -0.143566)
call g_tracer_add_param('e2_12', param%e2_12, 0.091015)
call g_tracer_add_param('e3_12', param%e3_12, -0.0153924)
! Rho_0 is used in the Boussinesq
! approximation to calculations of pressure and
! pressure gradients, in units of kg m-3.
call g_tracer_add_param('RHO_0', param%Rho_0, 1035.0)
call g_tracer_end_param_list(package_name)
!===========
!Block Ends: g_tracer_add_param
!===========
end subroutine user_add_params
!
! This is an internal sub, not a public interface.
! Add all the tracers to be used in this module.
!
subroutine user_add_tracers(tracer_list)
type(g_tracer_type), pointer :: tracer_list
character(len=fm_string_len), parameter :: sub_name = 'user_add_tracers'
call g_tracer_start_param_list(package_name)!nnz: Does this append?
call g_tracer_add_param('ice_restart_file' , param%ice_restart_file , 'ice_ocmip2_cfc.res.nc')
call g_tracer_add_param('ocean_restart_file' , param%ocean_restart_file , 'ocmip2_cfc.res.nc' )
call g_tracer_add_param('IC_file' , param%IC_file , '')
call g_tracer_end_param_list(package_name)
! Set Restart files
call g_tracer_set_files(ice_restart_file=param%ice_restart_file, ocean_restart_file=param%ocean_restart_file )
!=====================================================
!Specify all prognostic tracers of this modules.
!=====================================================
!User adds one call for each prognostic tracer below!
!User should specify if fluxes must be extracted from boundary
!by passing one or more of the following methods as .true.
!and provide the corresponding parameters array
!methods: flux_gas,flux_runoff,flux_wetdep,flux_drydep
!
!prog_tracers: cfc_11,cfc_12
!diag_tracers: none
!
!cfc_12
call g_tracer_add(tracer_list,package_name,&
name = 'cfc_12', &
longname = 'cfc_12 Concentration', &
units = 'mol/kg', &
prog = .true., &
flux_gas = .true., &
flux_gas_type = 'air_sea_gas_flux_generic', &
flux_gas_param = (/ 9.36e-07, 9.7561e-06 /), &
flux_gas_restart_file = 'ocmip2_cfc_airsea_flux.res.nc' )
!g_cfc_11
call g_tracer_add(tracer_list,package_name,&
name = 'cfc_11', &
longname = 'cfc_11 Concentration', &
units = 'mol/kg', &
prog = .true., &
flux_gas = .true., &
flux_gas_type = 'air_sea_gas_flux_generic', &
flux_gas_param = (/ 9.36e-07, 9.7561e-06 /), &
flux_gas_restart_file = 'ocmip2_cfc_airsea_flux.res.nc' )
end subroutine user_add_tracers
!
!
! Modify the values obtained from the coupler if necessary.
!
!
! Currently an empty stub for CFCs.
! Some tracer fields need to be modified after values are obtained from the coupler.
! This subroutine is the place for specific tracer manipulations.
!
!
! call generic_CFC_update_from_coupler(tracer_list)
!
!
! Pointer to the head of generic tracer list.
!
!
subroutine generic_CFC_update_from_coupler(tracer_list)
type(g_tracer_type), pointer :: tracer_list
character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_update_from_copler'
!
!Nothing specific to be done for CFC's
!
return
end subroutine generic_CFC_update_from_coupler
!
!
! Update tracer concentration fields due to the source/sink contributions.
!
!
! Currently an empty stub for CFCs.
!
!
subroutine generic_CFC_update_from_source(tracer_list)
type(g_tracer_type), pointer :: tracer_list
!
!No source update for CFC's currently exit in code.
!
return
end subroutine generic_CFC_update_from_source
!
!
! Calculate and set coupler values at the surface / bottom
!
!
!
!
!
! call generic_CFC_set_boundary_values(tracer_list,SST,SSS,rho,ilb,jlb,tau)
!
!
! Pointer to the head of generic tracer list.
!
!
! Lower bounds of x and y extents of input arrays on data domain
!
!
! Sea Surface Temperature
!
!
! Sea Surface Salinity
!
!
! Ocean density
!
!
! Time step index of %field
!
!
!User must provide the calculations for these boundary values.
subroutine generic_CFC_set_boundary_values(tracer_list,ST,SSS,rho,ilb,jlb,taum1)
type(g_tracer_type), pointer :: tracer_list
real, dimension(ilb:,jlb:), intent(in) :: ST, SSS
real, dimension(ilb:,jlb:,:,:), intent(in) :: rho
integer, intent(in) :: ilb,jlb,taum1
integer :: isc,iec, jsc,jec,isd,ied,jsd,jed,nk,ntau , i, j
real :: conv_fac,sal,ta,SST,alpha_11,alpha_12,sc_11,sc_12
real, dimension(:,:,:) ,pointer :: grid_tmask
real, dimension(:,:,:,:), pointer :: g_cfc_11_field,g_cfc_12_field
real, dimension(:,:), ALLOCATABLE :: g_cfc_11_alpha,g_cfc_11_csurf,g_cfc_12_alpha,g_cfc_12_csurf
real, dimension(:,:), ALLOCATABLE :: sc_no_11,sc_no_12
character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_set_boundary_values'
!nnz: Can we treat these as source and move block to user_update_from_source?
!
!=============
!Block Starts: Calculate the boundary values
!=============
!
!Get the necessary properties
!
call g_tracer_get_common(isc,iec,jsc,jec,isd,ied,jsd,jed,nk,ntau,grid_tmask=grid_tmask)
call g_tracer_get_pointer(tracer_list,'cfc_11','field',g_cfc_11_field)
call g_tracer_get_pointer(tracer_list,'cfc_12','field',g_cfc_12_field)
allocate(g_cfc_11_alpha(isd:ied, jsd:jed)); g_cfc_11_alpha=0.0
allocate(g_cfc_11_csurf(isd:ied, jsd:jed)); g_cfc_11_csurf=0.0
allocate(g_cfc_12_alpha(isd:ied, jsd:jed)); g_cfc_12_alpha=0.0
allocate(g_cfc_12_csurf(isd:ied, jsd:jed)); g_cfc_12_csurf=0.0
allocate(sc_no_11(isd:ied, jsd:jed))
allocate(sc_no_12(isd:ied, jsd:jed))
!The atmospheric code needs soluabilities in units of mol/m3/atm
!
!MOM
! The factor 1.0e+03 is for the conversion
! from mol/(l * atm) to mol/(m3 * atm)
conv_fac = 1.0e+03
!
!GOLD
! The factor 1.e-09 converts
! from mol/(l * atm) to mol/(m3 * pptv).
!conv_fac = 1.0e-09
do j=jsc,jec ; do i=isc,iec
!This calculation needs an input of SST and SSS
ta = (ST(i,j) + 273.15) * 0.01 ! Why is this in dekaKelvin?
sal = SSS(i,j) ; SST = ST(i,j)
!---------------------------------------------------------------------
! Calculate solubilities
! Use Warner and Weiss (1985) DSR, vol 32, final result
! in mol/l/atm (note, atmospheric data may be in 1 part per trillion 1e-12, pptv)
!
! Use Bullister and Wisegavger for CCl4
!---------------------------------------------------------------------
!nnz: MOM hmask=grid_tmask(i,j,1), GOLD hmask=G%hmask
alpha_11 = conv_fac * grid_tmask(i,j,1) * &
exp(param%d1_11 + param%d2_11/ta + param%d3_11*log(ta) + param%d4_11*ta*ta +&
sal * ((param%e3_11 * ta + param%e2_11) * ta + param%e1_11)&
)
alpha_12 = conv_fac * grid_tmask(i,j,1) * &
exp(param%d1_12 + param%d2_12/ta + param%d3_12*log(ta) + param%d4_12*ta*ta +&
sal * ((param%e3_12 * ta + param%e2_12) * ta + param%e1_12)&
)
!---------------------------------------------------------------------
! Calculate Schmidt numbers
! use coefficients given by Zheng et al (1998), JGR vol 103, C1
!---------------------------------------------------------------------
sc_no_11(i,j) = param%a1_11 + SST * (param%a2_11 + SST * (param%a3_11 + SST * param%a4_11)) * &
grid_tmask(i,j,1)
sc_no_12(i,j) = param%a1_12 + SST * (param%a2_12 + SST * (param%a3_12 + SST * param%a4_12)) * &
grid_tmask(i,j,1)
!sc_no_term = sqrt(660.0 / (sc_11 + epsln))
!
! In 'ocmip2_generic' atmos_ocean_fluxes.F90 coupler formulation,
! the schmidt number is carried in explicitly
!
g_cfc_11_alpha(i,j) = alpha_11
g_cfc_11_csurf(i,j) = g_cfc_11_field(i,j,1,taum1) * param%Rho_0
g_cfc_12_alpha(i,j) = alpha_12
g_cfc_12_csurf(i,j) = g_cfc_12_field(i,j,1,taum1) * param%Rho_0
enddo; enddo
!=============
!Block Ends: Calculate the boundary values
!=============
!
!Set %csurf and %alpha for these tracers. This will mark them for sending fluxes to coupler
!
call g_tracer_set_values(tracer_list,'cfc_11','alpha',g_cfc_11_alpha,isd,jsd)
call g_tracer_set_values(tracer_list,'cfc_11','csurf',g_cfc_11_csurf,isd,jsd)
call g_tracer_set_values(tracer_list,'cfc_11','sc_no',sc_no_11,isd,jsd)
call g_tracer_set_values(tracer_list,'cfc_12','alpha',g_cfc_12_alpha,isd,jsd)
call g_tracer_set_values(tracer_list,'cfc_12','csurf',g_cfc_12_csurf,isd,jsd)
call g_tracer_set_values(tracer_list,'cfc_12','sc_no',sc_no_12,isd,jsd)
deallocate(g_cfc_11_alpha,g_cfc_11_csurf,g_cfc_12_alpha,g_cfc_12_csurf,sc_no_11,sc_no_12)
end subroutine generic_CFC_set_boundary_values
!
!
! End the module.
!
!
! Deallocate all work arrays
!
!
! call generic_CFC_end
!
!
subroutine generic_CFC_end
character(len=fm_string_len), parameter :: sub_name = 'generic_CFC_end'
end subroutine generic_CFC_end
end module generic_CFC