Skip to content

Commit 780454e

Browse files
authored
Merge pull request #419 from mnlevy1981/MARBL_forcing_accum
Fix how fluxes sent to MARBL are treated when DT_THERMO is bigger than coupling interval
2 parents 9f622bf + da74cad commit 780454e

4 files changed

Lines changed: 164 additions & 67 deletions

File tree

config_src/drivers/nuopc_cap/mom_ocean_model_nuopc.F90

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,6 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, &
566566

567567
if (OS%fluxes%fluxes_used) then
568568

569-
! enable_averages() is necessary to post forcing fields to diagnostics
570-
call enable_averages(dt_coupling, OS%Time + Ocean_coupling_time_step, OS%diag)
571-
572569
if (do_thermo) &
573570
call convert_IOB_to_fluxes(Ice_ocean_boundary, OS%fluxes, index_bnds, OS%Time, dt_coupling, &
574571
OS%grid, OS%US, OS%forcing_CSp, OS%sfc_state, &

config_src/drivers/nuopc_cap/mom_surface_forcing_nuopc.F90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1470,7 +1470,8 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, restore_salt,
14701470

14711471
call register_forcing_type_diags(Time, diag, US, CS%use_temperature, CS%handles, &
14721472
use_berg_fluxes=iceberg_flux_diags, use_waves=use_waves, &
1473-
use_cfcs=CS%use_CFC, use_glc_runoff=glc_runoff_diags)
1473+
use_cfcs=CS%use_CFC, use_MARBL_tracers=CS%use_MARBL_tracers, &
1474+
use_glc_runoff=glc_runoff_diags)
14741475

14751476
call get_param(param_file, mdl, "ALLOW_FLUX_ADJUSTMENTS", CS%allow_flux_adjustments, &
14761477
"If true, allows flux adjustments to specified via the "//&

src/core/MOM_forcing_type.F90

Lines changed: 151 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,12 @@ module MOM_forcing_type
236236
atm_co2 => NULL(), & !< Atmospheric CO2 Concentration [ppm]
237237
atm_alt_co2 => NULL(), & !< Alternate atmospheric CO2 Concentration [ppm]
238238
dust_flux => NULL(), & !< Flux of dust into the ocean [R Z T-1 ~> kgN m-2 s-1]
239-
iron_flux => NULL() !< Flux of dust into the ocean [conc Z T-1 ~> conc m s-1]
239+
iron_flux => NULL(), & !< Flux of dust into the ocean [conc Z T-1 ~> conc m s-1]
240+
atm_fine_dust_flux => NULL(), & !< Fine dust flux from atmosphere [R Z T-1 ~> kg m-2 s-1]
241+
atm_coarse_dust_flux => NULL(), & !< Coarse dust flux from atmosphere [R Z T-1 ~> kg m-2 s-1]
242+
seaice_dust_flux => NULL(), & !< Dust flux from seaice [R Z T-1 ~> kg m-2 s-1]
243+
atm_bc_flux => NULL(), & !< Black carbon flux from atmosphere [R Z T-1 ~> kg m-2 s-1]
244+
seaice_bc_flux => NULL() !< Black carbon flux from seaice [R Z T-1 ~> kg m-2 s-1]
240245

241246
real, pointer, dimension(:,:,:) :: &
242247
fracr_cat => NULL(), & !< per-category ice fraction [nondim]
@@ -423,6 +428,11 @@ module MOM_forcing_type
423428
! tracer surface flux related diagnostics handles
424429
integer :: id_ice_fraction = -1
425430
integer :: id_u10_sqr = -1
431+
integer :: id_atm_fine_dust_flux = -1
432+
integer :: id_atm_coarse_dust_flux = -1
433+
integer :: id_atm_bc_flux = -1
434+
integer :: id_seaice_dust_flux = -1
435+
integer :: id_seaice_bc_flux = -1
426436

427437
! iceberg diagnostic handles
428438
integer :: id_ustar_berg = -1
@@ -1542,7 +1552,7 @@ end subroutine forcing_SinglePointPrint
15421552

15431553
!> Register members of the forcing type for diagnostics
15441554
subroutine register_forcing_type_diags(Time, diag, US, use_temperature, handles, use_berg_fluxes, use_waves, &
1545-
use_cfcs, use_glc_runoff)
1555+
use_cfcs, use_MARBL_tracers, use_glc_runoff)
15461556
type(time_type), intent(in) :: Time !< time type
15471557
type(diag_ctrl), intent(inout) :: diag !< diagnostic control type
15481558
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
@@ -1551,8 +1561,18 @@ subroutine register_forcing_type_diags(Time, diag, US, use_temperature, handles,
15511561
logical, optional, intent(in) :: use_berg_fluxes !< If true, allow iceberg flux diagnostics
15521562
logical, optional, intent(in) :: use_waves !< If true, allow wave forcing diagnostics
15531563
logical, optional, intent(in) :: use_cfcs !< If true, allow cfc related diagnostics
1564+
logical, optional, intent(in) :: use_MARBL_tracers !< If true, allow MARBL related diagnostics
15541565
logical, optional, intent(in) :: use_glc_runoff !< If true, allow separate glacial runoff diagnostics
15551566

1567+
logical :: use_cfcs_or_MARBL_tracers
1568+
1569+
! some diagnostics should be registered if either cfc or MARBL tracers are enabled
1570+
use_cfcs_or_MARBL_tracers = .false.
1571+
if (present(use_cfcs)) &
1572+
use_cfcs_or_MARBL_tracers = use_cfcs_or_MARBL_tracers .or. use_cfcs
1573+
if (present(use_MARBL_tracers)) &
1574+
use_cfcs_or_MARBL_tracers = use_cfcs_or_MARBL_tracers .or. use_MARBL_tracers
1575+
15561576
! Clock for forcing diagnostics
15571577
handles%id_clock_forcing=cpu_clock_id('(Ocean forcing diagnostics)', grain=CLOCK_ROUTINE)
15581578

@@ -1601,17 +1621,34 @@ subroutine register_forcing_type_diags(Time, diag, US, use_temperature, handles,
16011621
endif
16021622
endif
16031623

1604-
! See:
1605-
if (present(use_cfcs)) then
1606-
if (use_cfcs) then
1607-
handles%id_ice_fraction = register_diag_field('ocean_model', 'ice_fraction', diag%axesT1, Time, &
1608-
'Fraction of cell area covered by sea ice', 'm2 m-2', conversion=1.0)
1624+
if (use_cfcs_or_MARBL_tracers) then
1625+
handles%id_ice_fraction = register_diag_field('ocean_model', 'ice_fraction', diag%axesT1, Time, &
1626+
'Fraction of cell area covered by sea ice', 'm2 m-2', conversion=1.0)
16091627

1610-
handles%id_u10_sqr = register_diag_field('ocean_model', 'u10_sqr', diag%axesT1, Time, &
1611-
'Wind magnitude at 10m, squared', 'm2 s-2', conversion=US%L_to_m**2*US%s_to_T**2)
1612-
endif
1628+
handles%id_u10_sqr = register_diag_field('ocean_model', 'u10_sqr', diag%axesT1, Time, &
1629+
'Wind magnitude at 10m, squared', 'm2 s-2', conversion=US%L_to_m**2*US%s_to_T**2)
16131630
endif
16141631

1632+
if (present(use_MARBL_tracers)) then
1633+
if (use_MARBL_tracers) then
1634+
handles%id_atm_fine_dust_flux = register_diag_field('ocean_model', 'ATM_FINE_DUST_FLUX_CPL', &
1635+
diag%axesT1, Time, 'ATM_FINE_DUST_FLUX from cpl', 'kg m-2 s', &
1636+
conversion=US%RZ_T_to_kg_m2s)
1637+
handles%id_atm_coarse_dust_flux = register_diag_field('ocean_model', 'ATM_COARSE_DUST_FLUX_CPL', &
1638+
diag%axesT1, Time, 'ATM_COARSE_DUST_FLUX from cpl', 'kg m-2 s', &
1639+
conversion=US%RZ_T_to_kg_m2s)
1640+
handles%id_atm_bc_flux = register_diag_field('ocean_model', 'ATM_BLACK_CARBON_FLUX_CPL', &
1641+
diag%axesT1, Time, 'ATM_BLACK_CARBON_FLUX from cpl', 'kg m-2 s', &
1642+
conversion=US%RZ_T_to_kg_m2s)
1643+
1644+
handles%id_seaice_dust_flux = register_diag_field('ocean_model', 'SEAICE_DUST_FLUX_CPL', &
1645+
diag%axesT1, Time, 'SEAICE_DUST_FLUX from cpl', 'kg m-2 s', &
1646+
conversion=US%RZ_T_to_kg_m2s)
1647+
handles%id_seaice_bc_flux = register_diag_field('ocean_model', 'SEAICE_BLACK_CARBON_FLUX_CPL', &
1648+
diag%axesT1, Time, 'SEAICE_BLACK_CARBON_FLUX from cpl', 'kg m-2 s', &
1649+
conversion=US%RZ_T_to_kg_m2s)
1650+
end if
1651+
end if
16151652
handles%id_psurf = register_diag_field('ocean_model', 'p_surf', diag%axesT1, Time, &
16161653
'Pressure at ice-ocean or atmosphere-ocean interface', &
16171654
'Pa', conversion=US%RL2_T2_to_Pa, cmor_field_name='pso', &
@@ -2340,7 +2377,7 @@ subroutine fluxes_accumulate(flux_tmp, fluxes, G, wt2, forces)
23402377
! applied based on the time interval stored in flux_tmp.
23412378

23422379
real :: wt1 ! The relative weight of the previous fluxes [nondim]
2343-
integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
2380+
integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq, n
23442381
integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
23452382
is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec
23462383
Isq = G%IscB ; Ieq = G%IecB ; Jsq = G%JscB ; Jeq = G%JecB
@@ -2501,6 +2538,84 @@ subroutine fluxes_accumulate(flux_tmp, fluxes, G, wt2, forces)
25012538
enddo ; enddo
25022539
endif
25032540

2541+
! Forcings introduced for MARBL
2542+
! NOTE: fluxes%salt_flux, %sw, and %p_surf_full are handled above
2543+
if (associated(fluxes%nhx_dep) .and. associated(flux_tmp%nhx_dep)) then
2544+
do j=jsd,jed ; do i=isd,ied
2545+
fluxes%nhx_dep(i,j) = wt1*fluxes%nhx_dep(i,j) + wt2*flux_tmp%nhx_dep(i,j)
2546+
enddo ; enddo
2547+
endif
2548+
if (associated(fluxes%noy_dep) .and. associated(flux_tmp%noy_dep)) then
2549+
do j=jsd,jed ; do i=isd,ied
2550+
fluxes%noy_dep(i,j) = wt1*fluxes%noy_dep(i,j) + wt2*flux_tmp%noy_dep(i,j)
2551+
enddo ; enddo
2552+
endif
2553+
if (associated(fluxes%atm_co2) .and. associated(flux_tmp%atm_co2)) then
2554+
do j=jsd,jed ; do i=isd,ied
2555+
fluxes%atm_co2(i,j) = wt1*fluxes%atm_co2(i,j) + wt2*flux_tmp%atm_co2(i,j)
2556+
enddo ; enddo
2557+
endif
2558+
if (associated(fluxes%atm_alt_co2) .and. associated(flux_tmp%atm_alt_co2)) then
2559+
do j=jsd,jed ; do i=isd,ied
2560+
fluxes%atm_alt_co2(i,j) = wt1*fluxes%atm_alt_co2(i,j) + wt2*flux_tmp%atm_alt_co2(i,j)
2561+
enddo ; enddo
2562+
endif
2563+
if (associated(fluxes%dust_flux) .and. associated(flux_tmp%dust_flux)) then
2564+
do j=jsd,jed ; do i=isd,ied
2565+
fluxes%dust_flux(i,j) = wt1*fluxes%dust_flux(i,j) + wt2*flux_tmp%dust_flux(i,j)
2566+
enddo ; enddo
2567+
endif
2568+
if (associated(fluxes%iron_flux) .and. associated(flux_tmp%iron_flux)) then
2569+
do j=jsd,jed ; do i=isd,ied
2570+
fluxes%iron_flux(i,j) = wt1*fluxes%iron_flux(i,j) + wt2*flux_tmp%iron_flux(i,j)
2571+
enddo ; enddo
2572+
endif
2573+
if (associated(fluxes%atm_fine_dust_flux) .and. associated(flux_tmp%atm_fine_dust_flux)) then
2574+
do j=jsd,jed ; do i=isd,ied
2575+
fluxes%atm_fine_dust_flux(i,j) = wt1*fluxes%atm_fine_dust_flux(i,j) + wt2*flux_tmp%atm_fine_dust_flux(i,j)
2576+
enddo ; enddo
2577+
endif
2578+
if (associated(fluxes%atm_coarse_dust_flux) .and. associated(flux_tmp%atm_coarse_dust_flux)) then
2579+
do j=jsd,jed ; do i=isd,ied
2580+
fluxes%atm_coarse_dust_flux(i,j) = wt1*fluxes%atm_coarse_dust_flux(i,j) + wt2*flux_tmp%atm_coarse_dust_flux(i,j)
2581+
enddo ; enddo
2582+
endif
2583+
if (associated(fluxes%atm_bc_flux) .and. associated(flux_tmp%atm_bc_flux)) then
2584+
do j=jsd,jed ; do i=isd,ied
2585+
fluxes%atm_bc_flux(i,j) = wt1*fluxes%atm_bc_flux(i,j) + wt2*flux_tmp%atm_bc_flux(i,j)
2586+
enddo ; enddo
2587+
endif
2588+
if (associated(fluxes%seaice_dust_flux) .and. associated(flux_tmp%seaice_dust_flux)) then
2589+
do j=jsd,jed ; do i=isd,ied
2590+
fluxes%seaice_dust_flux(i,j) = wt1*fluxes%seaice_dust_flux(i,j) + wt2*flux_tmp%seaice_dust_flux(i,j)
2591+
enddo ; enddo
2592+
endif
2593+
if (associated(fluxes%seaice_bc_flux) .and. associated(flux_tmp%seaice_bc_flux)) then
2594+
do j=jsd,jed ; do i=isd,ied
2595+
fluxes%seaice_bc_flux(i,j) = wt1*fluxes%seaice_bc_flux(i,j) + wt2*flux_tmp%seaice_bc_flux(i,j)
2596+
enddo ; enddo
2597+
endif
2598+
if (associated(fluxes%fracr_cat) .and. associated(flux_tmp%fracr_cat)) then
2599+
do n=1,size(fluxes%fracr_cat,dim=3) ; do j=jsd,jed ; do i=isd,ied
2600+
fluxes%fracr_cat(i,j,n) = wt1*fluxes%fracr_cat(i,j,n) + wt2*flux_tmp%fracr_cat(i,j,n)
2601+
enddo ; enddo ; enddo
2602+
endif
2603+
if (associated(fluxes%qsw_cat) .and. associated(flux_tmp%qsw_cat)) then
2604+
do n=1,size(fluxes%qsw_cat,dim=3) ; do j=jsd,jed ; do i=isd,ied
2605+
fluxes%qsw_cat(i,j,n) = wt1*fluxes%qsw_cat(i,j,n) + wt2*flux_tmp%qsw_cat(i,j,n)
2606+
enddo ; enddo ; enddo
2607+
endif
2608+
if (associated(fluxes%ice_fraction) .and. associated(flux_tmp%ice_fraction)) then
2609+
do j=jsd,jed ; do i=isd,ied
2610+
fluxes%ice_fraction(i,j) = wt1*fluxes%ice_fraction(i,j) + wt2*flux_tmp%ice_fraction(i,j)
2611+
enddo ; enddo
2612+
endif
2613+
if (associated(fluxes%u10_sqr) .and. associated(flux_tmp%u10_sqr)) then
2614+
do j=jsd,jed ; do i=isd,ied
2615+
fluxes%u10_sqr(i,j) = wt1*fluxes%u10_sqr(i,j) + wt2*flux_tmp%u10_sqr(i,j)
2616+
enddo ; enddo
2617+
endif
2618+
25042619
if (coupler_type_initialized(fluxes%tr_fluxes) .and. &
25052620
coupler_type_initialized(flux_tmp%tr_fluxes)) &
25062621
call coupler_type_increment_data(flux_tmp%tr_fluxes, fluxes%tr_fluxes, &
@@ -3368,6 +3483,21 @@ subroutine forcing_diagnostics(fluxes_in, sfc_state, G_in, US, time_end, diag, h
33683483
if ((handles%id_u10_sqr > 0) .and. associated(fluxes%u10_sqr)) &
33693484
call post_data(handles%id_u10_sqr, fluxes%u10_sqr, diag)
33703485

3486+
if ((handles%id_atm_fine_dust_flux > 0) .and. associated(fluxes%atm_fine_dust_flux)) &
3487+
call post_data(handles%id_atm_fine_dust_flux, fluxes%atm_fine_dust_flux, diag)
3488+
3489+
if ((handles%id_atm_coarse_dust_flux > 0) .and. associated(fluxes%atm_coarse_dust_flux)) &
3490+
call post_data(handles%id_atm_coarse_dust_flux, fluxes%atm_coarse_dust_flux, diag)
3491+
3492+
if ((handles%id_atm_bc_flux > 0) .and. associated(fluxes%atm_bc_flux)) &
3493+
call post_data(handles%id_atm_bc_flux, fluxes%atm_bc_flux, diag)
3494+
3495+
if ((handles%id_seaice_dust_flux > 0) .and. associated(fluxes%seaice_dust_flux)) &
3496+
call post_data(handles%id_seaice_dust_flux, fluxes%seaice_dust_flux, diag)
3497+
3498+
if ((handles%id_seaice_bc_flux > 0) .and. associated(fluxes%seaice_bc_flux)) &
3499+
call post_data(handles%id_seaice_bc_flux, fluxes%seaice_bc_flux, diag)
3500+
33713501
! remaining boundary terms ==================================================
33723502

33733503
if ((handles%id_psurf > 0) .and. associated(fluxes%p_surf)) &
@@ -3537,6 +3667,11 @@ subroutine allocate_forcing_by_group(G, fluxes, water, heat, ustar, press, &
35373667
call myAlloc(fluxes%atm_alt_co2,isd,ied,jsd,jed, marbl)
35383668
call myAlloc(fluxes%dust_flux,isd,ied,jsd,jed, marbl)
35393669
call myAlloc(fluxes%iron_flux,isd,ied,jsd,jed, marbl)
3670+
call myAlloc(fluxes%atm_fine_dust_flux,isd,ied,jsd,jed, marbl)
3671+
call myAlloc(fluxes%atm_coarse_dust_flux,isd,ied,jsd,jed, marbl)
3672+
call myAlloc(fluxes%atm_bc_flux,isd,ied,jsd,jed, marbl)
3673+
call myAlloc(fluxes%seaice_dust_flux,isd,ied,jsd,jed, marbl)
3674+
call myAlloc(fluxes%seaice_bc_flux,isd,ied,jsd,jed, marbl)
35403675

35413676
! These fields should only be allocated when receiving multiple ice categories
35423677
if (present(ice_ncat)) then
@@ -3843,6 +3978,11 @@ subroutine deallocate_forcing_type(fluxes)
38433978
if (associated(fluxes%atm_alt_co2)) deallocate(fluxes%atm_alt_co2)
38443979
if (associated(fluxes%dust_flux)) deallocate(fluxes%dust_flux)
38453980
if (associated(fluxes%iron_flux)) deallocate(fluxes%iron_flux)
3981+
if (associated(fluxes%atm_fine_dust_flux)) deallocate(fluxes%atm_fine_dust_flux)
3982+
if (associated(fluxes%atm_coarse_dust_flux)) deallocate(fluxes%atm_coarse_dust_flux)
3983+
if (associated(fluxes%atm_bc_flux)) deallocate(fluxes%atm_bc_flux)
3984+
if (associated(fluxes%seaice_dust_flux)) deallocate(fluxes%seaice_dust_flux)
3985+
if (associated(fluxes%seaice_bc_flux)) deallocate(fluxes%seaice_bc_flux)
38463986
if (associated(fluxes%fracr_cat)) deallocate(fluxes%fracr_cat)
38473987
if (associated(fluxes%qsw_cat)) deallocate(fluxes%qsw_cat)
38483988

0 commit comments

Comments
 (0)