diff --git a/components/mpas-ocean/bld/build-namelist b/components/mpas-ocean/bld/build-namelist index 457078f1314a..c6e5d47b8555 100755 --- a/components/mpas-ocean/bld/build-namelist +++ b/components/mpas-ocean/bld/build-namelist @@ -1200,6 +1200,8 @@ if ($ice_bgc eq 'ice_bgc' ) { add_default($nl, 'config_use_ecosysTracers_sea_ice_coupling', 'val'=>".false."); } add_default($nl, 'config_use_ecosysTracers_river_inputs_from_coupler'); +add_default($nl, 'config_use_ecosysTracers_atm_dust_from_coupler'); +add_default($nl, 'config_use_ecosysTracers_iron_solubility_file'); #################################################### # Namelist group: tracer_forcing_freshwaterTracers # diff --git a/components/mpas-ocean/bld/build-namelist-section b/components/mpas-ocean/bld/build-namelist-section index c1a2e634dcd6..3cdcbc840968 100644 --- a/components/mpas-ocean/bld/build-namelist-section +++ b/components/mpas-ocean/bld/build-namelist-section @@ -599,11 +599,13 @@ add_default($nl, 'config_use_ecosysTracers_ttd_forcing'); add_default($nl, 'config_use_ecosysTracers_surface_value'); add_default($nl, 'config_use_ecosysTracers_river_inputs_from_coupler'); add_default($nl, 'config_use_ecosysTracers_sea_ice_coupling'); +add_default($nl, 'config_use_ecosysTracers_atm_dust_from_coupler'); add_default($nl, 'config_ecosysTracers_diagnostic_fields_level1'); add_default($nl, 'config_ecosysTracers_diagnostic_fields_level2'); add_default($nl, 'config_ecosysTracers_diagnostic_fields_level3'); add_default($nl, 'config_ecosysTracers_diagnostic_fields_level4'); add_default($nl, 'config_ecosysTracers_diagnostic_fields_level5'); +add_default($nl, 'config_use_ecosysTracers_iron_solubility_file'); #################################################### # Namelist group: tracer_forcing_freshwaterTracers # diff --git a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml index fcb9bcb7f114..044f4ef3914a 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_defaults_mpaso.xml @@ -760,11 +760,13 @@ .false. .false. .false. +.false. .false. .false. .false. .false. .false. +.false. .false. diff --git a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml index a455ff88869a..96486209b48a 100644 --- a/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml +++ b/components/mpas-ocean/bld/namelist_files/namelist_definition_mpaso.xml @@ -3115,6 +3115,14 @@ Valid values: .true. or .false. Default: Defined in namelist_defaults.xml + +if true, get atmospheric dust inputs from the coupler, else from ecosys monthly forcing file + +Valid values: .true. or .false. +Default: Defined in namelist_defaults.xml + + if true, make variables in ecosysDiagFieldsLevel1 available for output @@ -3155,6 +3163,14 @@ Valid values: .true. or .false. Default: Defined in namelist_defaults.xml + +if true, read in Fe solubility from the ecosys forcing file + +Valid values: .true. or .false. +Default: Defined in namelist_defaults.xml + + diff --git a/components/mpas-ocean/cime_config/buildnml b/components/mpas-ocean/cime_config/buildnml index 30682163e965..803f2bae500e 100755 --- a/components/mpas-ocean/cime_config/buildnml +++ b/components/mpas-ocean/cime_config/buildnml @@ -1812,6 +1812,11 @@ def buildnml(case, caseroot, compname): lines.append(' ') lines.append(' ') lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') + lines.append(' ') lines.append(' ') lines.append(' ') lines.append(' ') diff --git a/components/mpas-ocean/driver/ocn_comp_mct.F b/components/mpas-ocean/driver/ocn_comp_mct.F index c9465ca51983..92d4192d2ca6 100644 --- a/components/mpas-ocean/driver/ocn_comp_mct.F +++ b/components/mpas-ocean/driver/ocn_comp_mct.F @@ -1981,6 +1981,8 @@ subroutine ocn_import_mct(x2o_o, errorCode)!{{{ atmosphericPressureField, iceFractionField, & seaIcePressureField, windSpeedSquared10mField, & atmosphericCO2Field, atmosphericCO2_ALT_CO2Field, & + dust_FLUX_WETField, & + dust_FLUX_DRYField, & iceFluxDICField, & iceFluxDONField, & iceFluxNO3Field, & @@ -2032,6 +2034,8 @@ subroutine ocn_import_mct(x2o_o, errorCode)!{{{ seaIcePressure, windSpeedSquared10m, & atmosphericCO2, atmosphericCO2_ALT_CO2, & windSpeedSquared10mCFC, & + dust_FLUX_WET, & + dust_FLUX_DRY, & iceFluxDIC, & iceFluxDON, & iceFluxNO3, & @@ -2251,6 +2255,11 @@ subroutine ocn_import_mct(x2o_o, errorCode)!{{{ call mpas_pool_get_field(ecosysSeaIceCoupling, 'iceFluxDOC', iceFluxDOCField) call mpas_pool_get_field(ecosysSeaIceCoupling, 'iceFluxDON', iceFluxDONField) + if (config_use_ecosysTracers_atm_dust_from_coupler) then + call mpas_pool_get_field(ecosysAuxiliary, 'dust_FLUX_WET' , dust_FLUX_WETField) + call mpas_pool_get_field(ecosysAuxiliary, 'dust_FLUX_DRY' , dust_FLUX_DRYField) + endif + iceFluxPhytoC => iceFluxPhytoCField % array iceFluxDIC => iceFluxDICField % array iceFluxNO3 => iceFluxNO3Field % array @@ -2262,6 +2271,12 @@ subroutine ocn_import_mct(x2o_o, errorCode)!{{{ iceFluxDust => iceFluxDustField % array iceFluxDOC => iceFluxDOCField % array iceFluxDON => iceFluxDONField % array + + if (config_use_ecosysTracers_atm_dust_from_coupler) then + dust_FLUX_WET => dust_FLUX_WETField % array + dust_FLUX_DRY => dust_FLUX_DRYField % array + endif + endif endif if (config_use_DMSTracers .and. config_use_DMSTracers_sea_ice_coupling) then @@ -2518,9 +2533,26 @@ subroutine ocn_import_mct(x2o_o, errorCode)!{{{ if ( iceFluxFeDissolvedField % isActive ) then iceFluxFeDissolved(i) = x2o_o % rAttr(index_x2o_Fioi_fed1, n) endif - if ( iceFluxDustField % isActive ) then + if ( config_use_ecosysTracers_iron_solubility_file .and. & + config_use_ecosystracers_sea_ice_coupling .and. & + iceFluxDustField % isActive ) then iceFluxDust(i) = x2o_o % rAttr(index_x2o_Fioi_dust1, n) endif +! do not want atmospheric deposition on 100% land ice to enter the ocean + if ( config_use_ecosysTracers_atm_dust_from_coupler .and. dust_FLUX_WETField % isActive ) then + dust_FLUX_WET(i) = ( x2o_o % rAttr(index_x2o_Faxa_dstwet1, n) & + + x2o_o % rAttr(index_x2o_Faxa_dstwet2, n) & + + x2o_o % rAttr(index_x2o_Faxa_dstwet3, n) & + + x2o_o % rAttr(index_x2o_Faxa_dstwet4, n) ) & + * (1.0_RKIND - landIceFraction(i)) + endif + if ( config_use_ecosysTracers_atm_dust_from_coupler .and. dust_FLUX_DRYField % isActive ) then + dust_FLUX_DRY(i) = ( x2o_o % rAttr(index_x2o_Faxa_dstdry1, n) & + + x2o_o % rAttr(index_x2o_Faxa_dstdry2, n) & + + x2o_o % rAttr(index_x2o_Faxa_dstdry3, n) & + + x2o_o % rAttr(index_x2o_Faxa_dstdry4, n) ) & + * (1.0_RKIND - landIceFraction(i)) + endif if ( iceFluxDOCField % isActive ) then iceFluxDOC(1,i) = x2o_o % rAttr(index_x2o_Fioi_doc1, n) iceFluxDOC(2,i) = x2o_o % rAttr(index_x2o_Fioi_doc2, n) @@ -2626,6 +2658,11 @@ subroutine ocn_import_mct(x2o_o, errorCode)!{{{ call mpas_pool_get_field(ecosysSeaIceCoupling, 'iceFluxDust', iceFluxDustField) call mpas_pool_get_field(ecosysSeaIceCoupling, 'iceFluxDOC', iceFluxDOCField) call mpas_pool_get_field(ecosysSeaIceCoupling, 'iceFluxDON', iceFluxDONField) + + if (config_use_ecosysTracers_atm_dust_from_coupler) then + call mpas_pool_get_field(ecosysAuxiliary, 'dust_FLUX_WET' , dust_FLUX_WETField) + call mpas_pool_get_field(ecosysAuxiliary, 'dust_FLUX_DRY' , dust_FLUX_DRYField) + endif endif endif if (config_use_DMSTracers .and. config_use_DMSTracers_sea_ice_coupling) then @@ -2808,6 +2845,12 @@ subroutine ocn_import_mct(x2o_o, errorCode)!{{{ if ( iceFluxDustField % isActive ) then call mpas_dmpar_exch_halo_field(iceFluxDustField) endif + if ( config_use_ecosysTracers_atm_dust_from_coupler .and. dust_FLUX_WETField % isActive ) then + call mpas_dmpar_exch_halo_field(dust_FLUX_WETField) + endif + if ( config_use_ecosysTracers_atm_dust_from_coupler .and. dust_FLUX_DRYField % isActive ) then + call mpas_dmpar_exch_halo_field(dust_FLUX_DRYField) + endif if ( iceFluxDOCField % isActive ) then call mpas_dmpar_exch_halo_field(iceFluxDOCField) endif diff --git a/components/mpas-ocean/src/shared/mpas_ocn_constants.F b/components/mpas-ocean/src/shared/mpas_ocn_constants.F index dd3214d8d4fc..69117d68d7b2 100644 --- a/components/mpas-ocean/src/shared/mpas_ocn_constants.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_constants.F @@ -59,7 +59,8 @@ module ocn_constants ocn_ref_salinity ,&! ocean reference salinity (psu) atm_ref_pressure ,&! standard sea level pressure (Pa) molecular_weight_C ,&! molecular weight carbon - molecular_weight_O2 ! molecular weight oxygen + molecular_weight_O2 ,&! molecular weight oxygen + molecular_weight_Fe ! molecular weight iron ! conversion factors @@ -137,6 +138,7 @@ subroutine ocn_constants_init(configPool, packagePool)!{{{ atm_ref_pressure = 101325.0_RKIND ! (Pa) molecular_weight_C = 12.0107_RKIND ! molecular weight carbon molecular_weight_O2 = 15.9994_RKIND ! molecular weight oxygen + molecular_weight_Fe = 55.845_RKIND ! molecular weight iron !----------------------------------------------------------------------- @@ -176,6 +178,7 @@ subroutine ocn_constants_init(configPool, packagePool)!{{{ sea_ice_salinity = SHR_CONST_ICE_REF_SAL ! psu molecular_weight_C = SHR_CONST_MWC ! molecular weight carbon molecular_weight_O2 = SHR_CONST_MWO ! molecular weight oxygen + molecular_weight_Fe = SHR_CONST_MWFE ! molecular weight iron #endif !#ifdef ZERO_SEA_ICE_REF_SAL diff --git a/components/mpas-ocean/src/shared/mpas_ocn_tracer_ecosys.F b/components/mpas-ocean/src/shared/mpas_ocn_tracer_ecosys.F index 0148c32947cd..351b2011e7ef 100755 --- a/components/mpas-ocean/src/shared/mpas_ocn_tracer_ecosys.F +++ b/components/mpas-ocean/src/shared/mpas_ocn_tracer_ecosys.F @@ -1696,13 +1696,19 @@ subroutine ocn_tracer_ecosys_surface_flux_compute(activeTracers, ecosysTracers, iceFraction, & landIceFraction + ! input flux components in ecosysAuxiliary real (kind=RKIND), dimension(:), pointer :: & windSpeedSquared10m, & depositionFluxNO3, & depositionFluxNH4, & IRON_FLUX_IN, & + IRON_Solubility_wet, & + IRON_Solubility_dry, & + IRON_in_dust_fraction,& dust_FLUX_IN, & + dust_FLUX_WET, & + dust_FLUX_DRY, & riverFluxNO3, & riverFluxPO4, & riverFluxDON, & @@ -1723,6 +1729,7 @@ subroutine ocn_tracer_ecosys_surface_flux_compute(activeTracers, ecosysTracers, iceFluxSiO3, & iceFluxNH4, & iceFluxDOCr, & + iceFluxDust, & iceFluxFeDissolved real (kind=RKIND), dimension(:,:), pointer :: iceFluxPhytoC, & @@ -1810,6 +1817,7 @@ subroutine ocn_tracer_ecosys_surface_flux_compute(activeTracers, ecosysTracers, call mpas_pool_get_array(ecosysSeaIceCoupling, 'iceFluxDOCr', iceFluxDOCr) call mpas_pool_get_array(ecosysSeaIceCoupling, 'iceFluxDOC', iceFluxDOC) call mpas_pool_get_array(ecosysSeaIceCoupling, 'iceFluxDON', iceFluxDON) + call mpas_pool_get_array(ecosysSeaIceCoupling, 'iceFluxDust', iceFluxDust) call mpas_pool_get_array(ecosysSeaIceCoupling, 'iceFluxFeDissolved', iceFluxFeDissolved) endif @@ -1864,14 +1872,20 @@ subroutine ocn_tracer_ecosys_surface_flux_compute(activeTracers, ecosysTracers, activeTracers(indexTemperature,iLevelSurface,iCell) marbl_instances(1)%surface_flux_forcings(sss_indexInMARBL)%field_0d(iCell) = & activeTracers(indexSalinity,iLevelSurface,iCell) -! NOTE pass in total Fe and mult by parm_Fe_bioavail inside the flux routine -! divide river Fe by bioavail since it is already the available to make it total - marbl_instances(1)%surface_flux_forcings(ironFlux_indexInMARBL)%field_0d(iCell) = & - IRON_FLUX_IN(iCell) marbl_instances(1)%surface_flux_forcings(noxFlux_indexInMARBL)%field_0d(iCell) = & depositionFluxNO3(iCell) marbl_instances(1)%surface_flux_forcings(nhyFlux_indexInMARBL)%field_0d(iCell) = & depositionFluxNH4(iCell) + + if(config_use_ecosystracers_sea_ice_coupling) then + IRON_FLUX_IN(iCell) = (1.0_RKIND - iceFraction(iCell))*IRON_FLUX_IN(iCell) & + + iceFluxFeDissolved(iCell) + dust_FLUX_IN(iCell) = (1.0_RKIND - iceFraction(iCell))*dust_FLUX_IN(iCell) & + + iceFluxDust(iCell) + endif +! NOTE pass in total Fe and mult by parm_Fe_bioavail inside the flux routine + marbl_instances(1)%surface_flux_forcings(ironFlux_indexInMARBL)%field_0d(iCell) = & + IRON_FLUX_IN(iCell) marbl_instances(1)%surface_flux_forcings(dustFluxSurface_indexInMARBL)%field_0d(iCell) = & dust_FLUX_IN(iCell) @@ -1947,6 +1961,7 @@ subroutine ocn_tracer_ecosys_surface_flux_compute(activeTracers, ecosysTracers, ecosysSurfaceFlux(sio3_ind_MPAS,iCell) = & ecosysSurfaceFlux(sio3_ind_MPAS,iCell) + riverFluxSiO3(iCell) ecosysSurfaceFlux(fe_ind_MPAS,iCell) = & +! divide river Fe by bioavail since it is already the available to make it total ecosysSurfaceFlux(fe_ind_MPAS,iCell) + riverFluxFe(iCell) / parm_Fe_bioavail ecosysSurfaceFlux(dic_ind_MPAS,iCell) = & ecosysSurfaceFlux(dic_ind_MPAS,iCell) + riverFluxDIC(iCell) @@ -2128,7 +2143,12 @@ subroutine ocn_tracer_ecosys_init(domain,err)!{{{ depositionFluxNO3, & depositionFluxNH4, & IRON_FLUX_IN, & + IRON_Solubility_wet, & + IRON_Solubility_dry, & + IRON_in_dust_fraction,& dust_FLUX_IN, & + dust_FLUX_WET, & + dust_FLUX_DRY, & riverFluxNO3, & riverFluxPO4, & riverFluxDON, & @@ -2144,7 +2164,12 @@ subroutine ocn_tracer_ecosys_init(domain,err)!{{{ depositionFluzNO3, & depositionFluzNH4, & IRON_FLUZ_IN, & + IRON_Zolubility_wet, & + IRON_Zolubility_dry, & + IRON_in_duzt_fraction,& dust_FLUZ_IN, & + dust_FLUZ_WET, & + dust_FLUZ_DRY, & riverFluzNO3, & riverFluzPO4, & riverFluzDON, & @@ -2418,10 +2443,27 @@ subroutine ocn_tracer_ecosys_init(domain,err)!{{{ call mpas_pool_get_subpool(domain % blocklist % structs, 'forcing', forcingPool) call mpas_pool_get_subpool(forcingPool, 'ecosysAuxiliary', ecosysAuxiliary) +! make sure that if config_use_ecosysTracers_atm_dust_from_coupler is true, then +! config_use_ecosysTracers_iron_solubility_file is also true + + if (config_use_ecosysTracers_atm_dust_from_coupler .and. & + .not. config_use_ecosysTracers_iron_solubility_file) then + call mpas_log_write('Abort: In ocn_tracer_ecosys_init' // & + ' must have config_use_ecosysTracers_iron_solubility_file true if ' // & + 'config_use_ecosysTracers_atm_dust_from_coupler is true', MPAS_LOG_CRIT) + endif + call mpas_pool_get_array(ecosysAuxiliary, 'depositionFluxNO3', depositionFluxNO3) call mpas_pool_get_array(ecosysAuxiliary, 'depositionFluxNH4', depositionFluxNH4) call mpas_pool_get_array(ecosysAuxiliary, 'IRON_FLUX_IN', IRON_FLUX_IN) call mpas_pool_get_array(ecosysAuxiliary, 'dust_FLUX_IN', dust_FLUX_IN) + if (config_use_ecosysTracers_iron_solubility_file) then + call mpas_pool_get_array(ecosysAuxiliary, 'IRON_Solubility_wet', IRON_Solubility_wet) + call mpas_pool_get_array(ecosysAuxiliary, 'IRON_Solubility_dry', IRON_Solubility_dry) + call mpas_pool_get_array(ecosysAuxiliary, 'IRON_in_dust_fraction', IRON_in_dust_fraction) + call mpas_pool_get_array(ecosysAuxiliary, 'dust_FLUX_WET', dust_FLUX_WET) + call mpas_pool_get_array(ecosysAuxiliary, 'dust_FLUX_DRY', dust_FLUX_DRY) + endif if (.not. config_use_ecosysTracers_river_inputs_from_coupler) then call mpas_pool_get_array(ecosysAuxiliary, 'riverFluxNO3', riverFluxNO3) call mpas_pool_get_array(ecosysAuxiliary, 'riverFluxPO4', riverFluxPO4) @@ -2440,6 +2482,13 @@ subroutine ocn_tracer_ecosys_init(domain,err)!{{{ call mpas_pool_get_array(ecosysMonthlyForcing, 'depositionFluzNH4', depositionFluzNH4) call mpas_pool_get_array(ecosysMonthlyForcing, 'IRON_FLUZ_IN', IRON_FLUZ_IN) call mpas_pool_get_array(ecosysMonthlyForcing, 'dust_FLUZ_IN', dust_FLUZ_IN) + if (config_use_ecosysTracers_iron_solubility_file) then + call mpas_pool_get_array(ecosysMonthlyForcing, 'IRON_Zolubility_wet', IRON_Zolubility_wet) + call mpas_pool_get_array(ecosysMonthlyForcing, 'IRON_Zolubility_dry', IRON_Zolubility_dry) + call mpas_pool_get_array(ecosysMonthlyForcing, 'IRON_in_duzt_fraction', IRON_in_duzt_fraction) + call mpas_pool_get_array(ecosysMonthlyForcing, 'dust_FLUZ_WET', dust_FLUZ_WET) + call mpas_pool_get_array(ecosysMonthlyForcing, 'dust_FLUZ_DRY', dust_FLUZ_DRY) + endif if (.not. config_use_ecosysTracers_river_inputs_from_coupler) then call mpas_pool_get_array(ecosysMonthlyForcing, 'riverFluzNO3', riverFluzNO3) call mpas_pool_get_array(ecosysMonthlyForcing, 'riverFluzPO4', riverFluzPO4) @@ -2474,27 +2523,62 @@ subroutine ocn_tracer_ecosys_init(domain,err)!{{{ forcingReferenceTimeMonthly, & forcingIntervalMonthly) - call MPAS_forcing_init_field( domain % streamManager, & - forcingGroupHead, & - 'ecosysMonthlyClimatology', & - 'IRON_FLUZ_IN', & - 'ecosys_monthly_flux', & - 'ecosysMonthlyForcing', & - 'IRON_FLUZ_IN', & - 'linear', & - forcingReferenceTimeMonthly, & - forcingIntervalMonthly) + if (.not. config_use_ecosysTracers_iron_solubility_file) then + call MPAS_forcing_init_field( domain % streamManager, & + forcingGroupHead, & + 'ecosysMonthlyClimatology', & + 'IRON_FLUZ_IN', & + 'ecosys_monthly_flux', & + 'ecosysMonthlyForcing', & + 'IRON_FLUZ_IN', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) - call MPAS_forcing_init_field( domain % streamManager, & - forcingGroupHead, & - 'ecosysMonthlyClimatology', & - 'dust_FLUZ_IN', & - 'ecosys_monthly_flux', & - 'ecosysMonthlyForcing', & - 'dust_FLUZ_IN', & - 'linear', & - forcingReferenceTimeMonthly, & - forcingIntervalMonthly) + call MPAS_forcing_init_field( domain % streamManager, & + forcingGroupHead, & + 'ecosysMonthlyClimatology', & + 'dust_FLUZ_IN', & + 'ecosys_monthly_flux', & + 'ecosysMonthlyForcing', & + 'dust_FLUZ_IN', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + else + call MPAS_forcing_init_field( domain % streamManager, & + forcingGroupHead, & + 'ecosysMonthlyClimatology', & + 'IRON_Zolubility_wet', & + 'ecosys_monthly_flux', & + 'ecosysMonthlyForcing', & + 'IRON_Zolubility_wet', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + call MPAS_forcing_init_field( domain % streamManager, & + forcingGroupHead, & + 'ecosysMonthlyClimatology', & + 'IRON_Zolubility_dry', & + 'ecosys_monthly_flux', & + 'ecosysMonthlyForcing', & + 'IRON_Zolubility_dry', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + + call MPAS_forcing_init_field( domain % streamManager, & + forcingGroupHead, & + 'ecosysMonthlyClimatology', & + 'IRON_in_duzt_fraction', & + 'ecosys_monthly_flux', & + 'ecosysMonthlyForcing', & + 'IRON_in_duzt_fraction', & + 'linear', & + forcingReferenceTimeMonthly, & + forcingIntervalMonthly) + endif ! only read in river fluxes if not getting them from coupler if (.not. config_use_ecosysTracers_river_inputs_from_coupler) then @@ -2651,6 +2735,11 @@ subroutine ocn_get_ecosysData( streamManager, & depositionFluxNH4, & IRON_FLUX_IN, & dust_FLUX_IN, & + dust_FLUX_WET, & + dust_FLUX_DRY, & + IRON_Solubility_wet, & + IRON_Solubility_dry, & + IRON_in_dust_fraction,& riverFluxNO3, & riverFluxPO4, & riverFluxDON, & @@ -2667,6 +2756,11 @@ subroutine ocn_get_ecosysData( streamManager, & depositionFluzNH4, & IRON_FLUZ_IN, & dust_FLUZ_IN, & + dust_FLUZ_WET, & + dust_FLUZ_DRY, & + IRON_Zolubility_wet, & + IRON_Zolubility_dry, & + IRON_in_duzt_fraction,& riverFluzNO3, & riverFluzPO4, & riverFluzDON, & @@ -2702,6 +2796,13 @@ subroutine ocn_get_ecosysData( streamManager, & call mpas_pool_get_array(ecosysAuxiliary, 'depositionFluxNH4', depositionFluxNH4) call mpas_pool_get_array(ecosysAuxiliary, 'IRON_FLUX_IN', IRON_FLUX_IN) call mpas_pool_get_array(ecosysAuxiliary, 'dust_FLUX_IN', dust_FLUX_IN) + if (config_use_ecosysTracers_iron_solubility_file) then + call mpas_pool_get_array(ecosysAuxiliary, 'IRON_Solubility_wet', IRON_Solubility_wet) + call mpas_pool_get_array(ecosysAuxiliary, 'IRON_Solubility_dry', IRON_Solubility_dry) + call mpas_pool_get_array(ecosysAuxiliary, 'IRON_in_dust_fraction', IRON_in_dust_fraction) + call mpas_pool_get_array(ecosysAuxiliary, 'dust_FLUX_WET', dust_FLUX_WET) + call mpas_pool_get_array(ecosysAuxiliary, 'dust_FLUX_DRY', dust_FLUX_DRY) + endif if (.not. config_use_ecosysTracers_river_inputs_from_coupler) then call mpas_pool_get_array(ecosysAuxiliary, 'riverFluxNO3', riverFluxNO3) call mpas_pool_get_array(ecosysAuxiliary, 'riverFluxPO4', riverFluxPO4) @@ -2718,6 +2819,13 @@ subroutine ocn_get_ecosysData( streamManager, & call mpas_pool_get_array(ecosysMonthlyForcing, 'depositionFluzNH4', depositionFluzNH4) call mpas_pool_get_array(ecosysMonthlyForcing, 'IRON_FLUZ_IN', IRON_FLUZ_IN) call mpas_pool_get_array(ecosysMonthlyForcing, 'dust_FLUZ_IN', dust_FLUZ_IN) + if (config_use_ecosysTracers_iron_solubility_file) then + call mpas_pool_get_array(ecosysMonthlyForcing, 'IRON_Zolubility_wet', IRON_Zolubility_wet) + call mpas_pool_get_array(ecosysMonthlyForcing, 'IRON_Zolubility_dry', IRON_Zolubility_dry) + call mpas_pool_get_array(ecosysMonthlyForcing, 'IRON_in_duzt_fraction', IRON_in_duzt_fraction) + call mpas_pool_get_array(ecosysMonthlyForcing, 'dust_FLUZ_WET', dust_FLUZ_WET) + call mpas_pool_get_array(ecosysMonthlyForcing, 'dust_FLUZ_DRY', dust_FLUZ_DRY) + endif if (.not. config_use_ecosysTracers_river_inputs_from_coupler) then call mpas_pool_get_array(ecosysMonthlyForcing, 'riverFluzNO3', riverFluzNO3) call mpas_pool_get_array(ecosysMonthlyForcing, 'riverFluzPO4', riverFluzPO4) @@ -2733,8 +2841,28 @@ subroutine ocn_get_ecosysData( streamManager, & do iCell = 1, nCells depositionFluxNO3(iCell) = depositionFluzNO3(iCell) depositionFluxNH4(iCell) = depositionFluzNH4(iCell) - IRON_FLUX_IN(iCell) = IRON_FLUZ_IN(iCell) - dust_FLUX_IN(iCell) = dust_FLUZ_IN(iCell) + if (config_use_ecosysTracers_iron_solubility_file) then +! calculate Fe flux from dust, solubility, fraction +! Fe flux units are mmol/m2/s, dust is kg/m2/s +! use same value for atomic weight of Fe as mpas-seaice and MarBL + IRON_Solubility_wet(iCell) = IRON_Zolubility_wet(iCell) + IRON_Solubility_dry(iCell) = IRON_Zolubility_dry(iCell) + IRON_in_dust_fraction(iCell) = IRON_in_duzt_fraction(iCell) + +! only use dust fluxes from file if not coming from the coupler + if (.not. config_use_ecosysTracers_atm_dust_from_coupler) then + dust_FLUX_WET(iCell) = dust_FLUZ_WET(iCell) + dust_FLUX_DRY(iCell) = dust_FLUZ_DRY(iCell) + endif + + IRON_FLUX_IN(iCell) = ( dust_FLUX_WET(iCell)*IRON_Solubility_wet(iCell) & + + dust_FLUX_DRY(iCell)*IRON_Solubility_dry(iCell) ) & + * IRON_in_dust_fraction(iCell)*1.e6_RKIND/molecular_weight_Fe + dust_FLUX_IN(iCell) = dust_FLUX_WET(iCell) + dust_FLUX_DRY(iCell) + else + IRON_FLUX_IN(iCell) = IRON_FLUZ_IN(iCell) + dust_FLUX_IN(iCell) = dust_FLUZ_IN(iCell) + endif enddo if (.not. config_use_ecosysTracers_river_inputs_from_coupler) then diff --git a/components/mpas-ocean/src/tracer_groups/Registry_ecosys.xml b/components/mpas-ocean/src/tracer_groups/Registry_ecosys.xml index ac0225d3d0a4..870e07fcd9ce 100644 --- a/components/mpas-ocean/src/tracer_groups/Registry_ecosys.xml +++ b/components/mpas-ocean/src/tracer_groups/Registry_ecosys.xml @@ -55,6 +55,10 @@ description="if true, couple ecosys fields with sea ice" possible_values=".true. or .false." /> + + @@ -708,9 +716,24 @@ + + + + + @@ -2046,7 +2069,22 @@ + + + + + diff --git a/components/mpas-seaice/src/shared/mpas_seaice_constants.F b/components/mpas-seaice/src/shared/mpas_seaice_constants.F index 6852084479b4..a1034cce3dee 100644 --- a/components/mpas-seaice/src/shared/mpas_seaice_constants.F +++ b/components/mpas-seaice/src/shared/mpas_seaice_constants.F @@ -50,8 +50,9 @@ module seaice_constants seaiceLatentHeatVaporization = SHR_CONST_LATVAP ,&! latent heat, vaporization freshwater (J/kg) seaiceLatentHeatMelting = SHR_CONST_LATICE ,&! latent heat of melting of fresh ice (J/kg) seaiceReferenceSalinity = SHR_CONST_ICE_REF_SAL,&! ice reference salinity (ppt) - seaiceSnowPatchiness = 0.005_RKIND ! parameter for fractional snow area (m) + seaiceSnowPatchiness = 0.005_RKIND ,&! parameter for fractional snow area (m) + gramsIronPerMolIron = SHR_CONST_MWFE ! molecular weight of Iron ! R_gC2molC = SHR_CONST_MWC ,&! molar mass of carbon #else @@ -87,8 +88,9 @@ module seaice_constants ! - seaiceLatentHeatVaporization, & seaiceLatentHeatMelting = 3.34e5_RKIND ,&! latent heat of melting of fresh ice (J/kg) seaiceReferenceSalinity = 4._RKIND ,&! ice reference salinity (ppt) - seaiceSnowPatchiness = 0.02_RKIND ! parameter for fractional snow area (m) + seaiceSnowPatchiness = 0.02_RKIND ,&! parameter for fractional snow area (m) + gramsIronPerMolIron = 55.845_RKIND ! molecular weight of Iron ! R_gC2molC = 12.0107_RKIND, & ! molar mass of carbon #endif @@ -184,8 +186,7 @@ module seaice_constants real(kind=RKIND), public :: & skeletalLayerThickness = 0.03_RKIND , & ! (m) skeletal layer thickness gramsCarbonPerMolCarbon = 12.0107_RKIND , & ! g carbon per mol carbon - microgramsPerKilograms = 1.0e9_RKIND , & ! kg to ug conversion - gramsIronPerMolIron = 55.845_RKIND ! g iron per mol iron + microgramsPerKilograms = 1.0e9_RKIND ! kg to ug conversion ! ocean biogeochemistry ISPOL values real(kind=RKIND), parameter, public :: & diff --git a/share/util/shr_const_mod.F90 b/share/util/shr_const_mod.F90 index fe8a4bb08286..a89b5b2b810a 100644 --- a/share/util/shr_const_mod.F90 +++ b/share/util/shr_const_mod.F90 @@ -29,6 +29,7 @@ MODULE shr_const_mod real(R8),parameter :: SHR_CONST_MWC = 12.0107_R8 ! molecular weight carbon real(R8),parameter :: SHR_CONST_MWO = 15.9994_R8 ! molecular weight oxygen real(R8),parameter :: SHR_CONST_MWCO2 = 44.0095_R8 ! molecular weight carbon dioxide + real(R8),parameter :: SHR_CONST_MWFE = 55.845_R8 ! molecular weight iron real(R8),parameter :: SHR_CONST_RDAIR = SHR_CONST_RGAS/SHR_CONST_MWDAIR ! Dry air gas constant ~ J/K/kg real(R8),parameter :: SHR_CONST_RWV = SHR_CONST_RGAS/SHR_CONST_MWWV ! Water vapor gas constant ~ J/K/kg real(R8),parameter :: SHR_CONST_ZVIR = (SHR_CONST_RWV/SHR_CONST_RDAIR)-1.0_R8 ! RWV/RDAIR - 1.0