@@ -31,6 +31,7 @@ module MOM_generic_tracer
31
31
32
32
use MOM_ALE_sponge, only : set_up_ALE_sponge_field, ALE_sponge_CS
33
33
use MOM_coms, only : EFP_type, max_across_PEs, min_across_PEs, PE_here
34
+ use MOM_diagnose_mld, only : diagnoseMLDbyDensityDifference, diagnoseMLDbyEnergy
34
35
use MOM_diag_mediator, only : post_data, register_diag_field, safe_alloc_ptr
35
36
use MOM_diag_mediator, only : diag_ctrl, get_diag_time_end
36
37
use MOM_error_handler, only : MOM_error, FATAL, WARNING, NOTE, is_root_pe
@@ -83,6 +84,14 @@ module MOM_generic_tracer
83
84
logical :: tracers_may_reinit ! < If true, tracers may go through the
84
85
! ! initialization code if they are not found in the restart files.
85
86
87
+ logical :: mld_pha_calc = .False. ! < If true, use a fixed value for photoacclimation MLD
88
+ real :: mld_pha_val = 0.0 ! < The value of fixed photoacclimation MLD
89
+ logical :: mld_pha_use_delta_rho = .False. ! < If true, use a density diference to find the MLD
90
+ real :: mld_pha_href = 0.0 ! < The reference depth for density difference based MLD
91
+ real :: mld_pha_drho = 0.03 ! < The density thershold for a density difference based MLD
92
+ logical :: mld_pha_use_delta_eng = .False. ! < If true, use an energy diference to find the MLD
93
+ real :: mld_pha_deng = 25.0 ! < The energy threshold for an energy d ifference based MLD
94
+
86
95
type (diag_ctrl), pointer :: diag = > NULL () ! < A structure that is used to
87
96
! ! regulate the timing of diagnostic output.
88
97
type (MOM_restart_CS), pointer :: restart_CSp = > NULL () ! < Restart control structure
@@ -423,6 +432,42 @@ subroutine initialize_MOM_generic_tracer(restart, day, G, GV, US, h, tv, param_f
423
432
enddo
424
433
! ! end section to re-initialize generic tracers
425
434
435
+ call get_param(param_file, " MOM" , " PHA_MLD_CALC" , CS% mld_pha_calc, &
436
+ " If false, use a fixed value for the photoacclimation mixed layer depth within the " // &
437
+ " generic tracer update. This MLD is only used for photoacclimation. This variable should " // &
438
+ " be set to true if using COBALTv3 for the BGC." , default= .false. )
439
+ if (CS% mld_pha_calc) then
440
+ call get_param(param_file, " MOM" , " PHA_MLD_USE_DELTA_RHO" , CS% mld_pha_use_delta_rho, &
441
+ " If true, use a density difference to find the photoacclimation mixed layer depth " // &
442
+ " within the generic tracer update. This MLD is only used for photoacclimation." , default= .false. )
443
+ call get_param(param_file, " MOM" , " PHA_MLD_USE_DELTA_ENG" , CS% mld_pha_use_delta_eng, &
444
+ " If true, use an energy difference to find the photoacclimation mixed layer depth " // &
445
+ " with the generic tracer update. This MLD is only used for photoacclimation." , default= .false. )
446
+ if (CS% mld_pha_use_delta_rho .and. CS% mld_pha_use_delta_eng) then
447
+ call MOM_error(FATAL, " PHA_MLD_CALC is set to true and PHA_MLD_USE_DELTA_RHO and PHA_MLD_USE_DELTA_ENG " // &
448
+ " are both true. Choose only one option for the calculated photoacclimation MLD!" )
449
+ elseif ((.not. CS% mld_pha_use_delta_rho) .and. (.not. CS% mld_pha_use_delta_eng)) then
450
+ call MOM_error(FATAL, " PHA_MLD_CALC is set to true but PHA_MLD_USE_DELTA_RHO and PHA_MLD_USE_DELTA_ENG " // &
451
+ " are both false. Choose an option for the calculated photoacclimation MLD!" )
452
+ endif
453
+ if (CS% mld_pha_use_delta_rho) then
454
+ call get_param(param_file, " MOM" , " PHA_MLD_HREF" , CS% mld_pha_href, &
455
+ " The reference depth for a density difference based photoacclimation MLD [m]." , &
456
+ units= ' m' , default= 0.0 , scale= US% m_to_Z, do_not_log= .not. CS% mld_pha_use_delta_rho)
457
+ call get_param(param_file, " MOM" , " PHA_MLD_DRHO" , CS% mld_pha_drho, &
458
+ " The density difference for a density difference based photoacclimation MLD [kg m-3]." , &
459
+ units= ' kg/m3' , default= 0.03 , scale= US% kg_m3_to_R, do_not_log= .not. CS% mld_pha_use_delta_rho)
460
+ elseif (CS% mld_pha_use_delta_eng) then
461
+ call get_param(param_file, " MOM" , " PHA_MLD_DENG" , CS% mld_pha_deng, &
462
+ " The energy for an energy difference based photoacclimation MLD." , default= 25.0 , &
463
+ units= ' J/m2' ,scale= US% W_m2_to_RZ3_T3* US% s_to_T, do_not_log= .not. CS% mld_pha_use_delta_eng)
464
+ endif
465
+ else
466
+ call get_param(param_file, " MOM" , " PHA_MLD_VAL" , CS% mld_pha_val, &
467
+ " The depth of photoacclimation if fixed depth is used [m]." , &
468
+ units= ' m' , default= 0.0 , scale= US% m_to_Z)
469
+ endif
470
+
426
471
427
472
! Now we can reset the grid mask, axes and time to their true values
428
473
! Note that grid_tmask must be set correctly on the data domain boundary
@@ -507,6 +552,8 @@ subroutine MOM_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, Hml,
507
552
real , dimension (SZI_(G),SZJ_(G),SZK_(GV)) :: rho_dzt ! Layer mass per unit area [kg m-2]
508
553
real , dimension (SZI_(G),SZJ_(G),SZK_(GV)) :: dzt ! Layer vertical extents [m]
509
554
real , dimension (SZI_(G),SZJ_(G),SZK_(GV)) :: h_work ! A work array of thicknesses [H ~> m or kg m-2]
555
+ real , dimension (SZI_(G),SZJ_(G)) :: mld_pha ! The mixed layer depth calculated for photoacclimation
556
+ ! that is used in COBALTv3
510
557
integer :: i, j, k, isc, iec, jsc, jec, nk
511
558
512
559
isc = G% isc ; iec = G% iec ; jsc = G% jsc ; jec = G% jec ; nk = GV% ke
@@ -572,6 +619,17 @@ subroutine MOM_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, Hml,
572
619
enddo ; enddo
573
620
sosga = global_area_mean(surface_field, G, unscale= US% S_to_ppt)
574
621
622
+ mld_pha(:,:) = 0.0
623
+ if (.not. CS% mld_pha_calc) then
624
+ mld_pha(:,:) = CS% mld_pha_val
625
+ else
626
+ if (CS% mld_pha_use_delta_rho) then
627
+ call diagnoseMLDbyDensityDifference(- 1 , h_old, tv, CS% mld_pha_drho, G, GV, US, CS% diag, CS% mld_pha_href, id_ref_z=- 1 , id_ref_rho=- 1 , MLD_out= mld_pha)
628
+ elseif (CS% mld_pha_use_delta_eng) then
629
+ call diagnoseMLDbyEnergy((/- 1 , - 1 , - 1 / ), h_old, tv, G, GV, US, (/ CS% mld_pha_deng, CS% mld_pha_deng, CS% mld_pha_deng/ ), CS% diag, MLD_out= mld_pha)
630
+ endif
631
+ endif
632
+
575
633
!
576
634
! Calculate tendencies (i.e., field changes at dt) from the sources / sinks
577
635
!
@@ -582,7 +640,8 @@ subroutine MOM_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, Hml,
582
640
call generic_tracer_source(tv% T, tv% S, rho_dzt, dzt, dz_ml, G% isd, G% jsd, 1 , dt, &
583
641
G% areaT, get_diag_time_end(CS% diag), &
584
642
optics% nbands, optics% max_wavelength_band, optics% sw_pen_band, optics% opacity_band, &
585
- internal_heat= tv% internal_heat, frunoff= fluxes% frunoff, sosga= sosga, geolat= G% geolatT, eqn_of_state= tv% eqn_of_state)
643
+ internal_heat= tv% internal_heat, frunoff= fluxes% frunoff, sosga= sosga, geolat= G% geolatT, eqn_of_state= tv% eqn_of_state, &
644
+ photo_acc_dpth= mld_pha)
586
645
else
587
646
! tv%internal_heat is a null pointer unless DO_GEOTHERMAL = True,
588
647
! so we have to check and only do the scaling if it is associated.
@@ -593,14 +652,16 @@ subroutine MOM_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, Hml,
593
652
sw_pen_band= G% US% QRZ_T_to_W_m2* optics% sw_pen_band(:,:,:), &
594
653
opacity_band= G% US% m_to_Z* optics% opacity_band(:,:,:,:), &
595
654
internal_heat= G% US% RZ_to_kg_m2* US% C_to_degC* tv% internal_heat(:,:), &
596
- frunoff= G% US% RZ_T_to_kg_m2s* fluxes% frunoff(:,:), sosga= sosga, geolat= G% geolatT, eqn_of_state= tv% eqn_of_state)
655
+ frunoff= G% US% RZ_T_to_kg_m2s* fluxes% frunoff(:,:), sosga= sosga, geolat= G% geolatT, eqn_of_state= tv% eqn_of_state, &
656
+ photo_acc_dpth= mld_pha* US% Z_to_m)
597
657
else
598
658
call generic_tracer_source(US% C_to_degC* tv% T, US% S_to_ppt* tv% S, rho_dzt, dzt, dz_ml, G% isd, G% jsd, 1 , dt, &
599
659
G% US% L_to_m** 2 * G% areaT(:,:), get_diag_time_end(CS% diag), &
600
660
optics% nbands, optics% max_wavelength_band, &
601
661
sw_pen_band= G% US% QRZ_T_to_W_m2* optics% sw_pen_band(:,:,:), &
602
662
opacity_band= G% US% m_to_Z* optics% opacity_band(:,:,:,:), &
603
- frunoff= G% US% RZ_T_to_kg_m2s* fluxes% frunoff(:,:), sosga= sosga, geolat= G% geolatT, eqn_of_state= tv% eqn_of_state)
663
+ frunoff= G% US% RZ_T_to_kg_m2s* fluxes% frunoff(:,:), sosga= sosga, geolat= G% geolatT, eqn_of_state= tv% eqn_of_state, &
664
+ photo_acc_dpth= mld_pha* US% Z_to_m)
604
665
endif
605
666
endif
606
667
0 commit comments