Skip to content

Commit a3fa3a1

Browse files
committed
Merge remote-tracking branch 'upstream/dev/emc' into ocn_stoch_july2021
2 parents e4bc007 + 67c1fd9 commit a3fa3a1

4 files changed

Lines changed: 1116 additions & 10 deletions

File tree

src/core/MOM.F90

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ module MOM
133133
! ODA modules
134134
use MOM_oda_driver_mod, only : ODA_CS, oda, init_oda, oda_end
135135
use MOM_oda_driver_mod, only : set_prior_tracer, set_analysis_time, apply_oda_tracer_increments
136+
use MOM_oda_incupd, only : oda_incupd_CS, init_oda_incupd_diags
137+
136138
! Offline modules
137139
use MOM_offline_main, only : offline_transport_CS, offline_transport_init, update_offline_fields
138140
use MOM_offline_main, only : insert_offline_main, extract_offline_main, post_offline_convergence_diags
@@ -363,6 +365,8 @@ module MOM
363365
type(sponge_CS), pointer :: sponge_CSp => NULL()
364366
!< Pointer to the layered-mode sponge control structure
365367
type(ALE_sponge_CS), pointer :: ALE_sponge_CSp => NULL()
368+
!< Pointer to the oda incremental update control structure
369+
type(oda_incupd_CS), pointer :: oda_incupd_CSp => NULL()
366370
!< Pointer to the ALE-mode sponge control structure
367371
type(ALE_CS), pointer :: ALE_CSp => NULL()
368372
!< Pointer to the Arbitrary Lagrangian Eulerian (ALE) vertical coordinate control structure
@@ -1665,6 +1669,7 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, &
16651669
type(ocean_OBC_type), pointer :: OBC_in => NULL()
16661670
type(sponge_CS), pointer :: sponge_in_CSp => NULL()
16671671
type(ALE_sponge_CS), pointer :: ALE_sponge_in_CSp => NULL()
1672+
type(oda_incupd_CS),pointer :: oda_incupd_in_CSp => NULL()
16681673

16691674
! This include declares and sets the variable "version".
16701675
# include "version_variable.h"
@@ -2421,12 +2426,12 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, &
24212426
call rotate_array(CS%frac_shelf_h, -turns, frac_shelf_in)
24222427
call MOM_initialize_state(u_in, v_in, h_in, CS%tv, Time, G_in, GV, US, &
24232428
param_file, dirs, restart_CSp, CS%ALE_CSp, CS%tracer_Reg, &
2424-
sponge_in_CSp, ALE_sponge_in_CSp, OBC_in, Time_in, &
2429+
sponge_in_CSp, ALE_sponge_in_CSp, oda_incupd_in_CSp, OBC_in, Time_in, &
24252430
frac_shelf_h=frac_shelf_in)
24262431
else
24272432
call MOM_initialize_state(u_in, v_in, h_in, CS%tv, Time, G_in, GV, US, &
24282433
param_file, dirs, restart_CSp, CS%ALE_CSp, CS%tracer_Reg, &
2429-
sponge_in_CSp, ALE_sponge_in_CSp, OBC_in, Time_in)
2434+
sponge_in_CSp, ALE_sponge_in_CSp, oda_incupd_in_CSp, OBC_in, Time_in)
24302435
endif
24312436

24322437
if (use_temperature) then
@@ -2468,12 +2473,12 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, &
24682473
call ice_shelf_query(ice_shelf_CSp,G,CS%frac_shelf_h)
24692474
call MOM_initialize_state(CS%u, CS%v, CS%h, CS%tv, Time, G, GV, US, &
24702475
param_file, dirs, restart_CSp, CS%ALE_CSp, CS%tracer_Reg, &
2471-
CS%sponge_CSp, CS%ALE_sponge_CSp, CS%OBC, Time_in, &
2476+
CS%sponge_CSp, CS%ALE_sponge_CSp,CS%oda_incupd_CSp, CS%OBC, Time_in, &
24722477
frac_shelf_h=CS%frac_shelf_h)
24732478
else
24742479
call MOM_initialize_state(CS%u, CS%v, CS%h, CS%tv, Time, G, GV, US, &
24752480
param_file, dirs, restart_CSp, CS%ALE_CSp, CS%tracer_Reg, &
2476-
CS%sponge_CSp, CS%ALE_sponge_CSp, CS%OBC, Time_in)
2481+
CS%sponge_CSp, CS%ALE_sponge_CSp, CS%oda_incupd_CSp, CS%OBC, Time_in)
24772482
endif
24782483
endif
24792484

@@ -2665,7 +2670,7 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, &
26652670
else
26662671
call diabatic_driver_init(Time, G, GV, US, param_file, CS%use_ALE_algorithm, diag, &
26672672
CS%ADp, CS%CDp, CS%diabatic_CSp, CS%tracer_flow_CSp, &
2668-
CS%sponge_CSp, CS%ALE_sponge_CSp)
2673+
CS%sponge_CSp, CS%ALE_sponge_CSp, CS%oda_incupd_CSp)
26692674
endif
26702675

26712676
if (associated(CS%sponge_CSp)) &
@@ -2674,6 +2679,10 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, &
26742679
if (associated(CS%ALE_sponge_CSp)) &
26752680
call init_ALE_sponge_diags(Time, G, diag, CS%ALE_sponge_CSp, US)
26762681

2682+
if (associated(CS%oda_incupd_CSp)) &
2683+
call init_oda_incupd_diags(Time, G, GV, diag, CS%oda_incupd_CSp, US)
2684+
2685+
26772686
call tracer_advect_init(Time, G, US, param_file, diag, CS%tracer_adv_CSp)
26782687
call tracer_hor_diff_init(Time, G, GV, US, param_file, diag, CS%tv%eqn_of_state, CS%diabatic_CSp, &
26792688
CS%tracer_diff_CSp)

src/initialization/MOM_state_initialization.F90

Lines changed: 175 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ module MOM_state_initialization
1111
use MOM_cpu_clock, only : CLOCK_ROUTINE, CLOCK_LOOP
1212
use MOM_domains, only : pass_var, pass_vector, sum_across_PEs, broadcast
1313
use MOM_domains, only : root_PE, To_All, SCALAR_PAIR, CGRID_NE, AGRID
14-
use MOM_error_handler, only : MOM_mesg, MOM_error, FATAL, WARNING, is_root_pe
14+
use MOM_error_handler, only : MOM_mesg, MOM_error, FATAL, NOTE, WARNING, is_root_pe
1515
use MOM_error_handler, only : callTree_enter, callTree_leave, callTree_waypoint
1616
use MOM_file_parser, only : get_param, read_param, log_param, param_file_type
1717
use MOM_file_parser, only : log_version
@@ -94,6 +94,9 @@ module MOM_state_initialization
9494
use MOM_remapping, only : remapping_CS, initialize_remapping
9595
use MOM_remapping, only : remapping_core_h
9696
use MOM_horizontal_regridding, only : horiz_interp_and_extrap_tracer
97+
use MOM_oda_incupd, only: oda_incupd_CS, initialize_oda_incupd_fixed, initialize_oda_incupd
98+
use MOM_oda_incupd, only: set_up_oda_incupd_field, set_up_oda_incupd_vel_field
99+
use MOM_oda_incupd, only: calc_oda_increments, output_oda_incupd_inc
97100

98101
implicit none ; private
99102

@@ -114,7 +117,7 @@ module MOM_state_initialization
114117
!! conditions or by reading them from a restart (or saves) file.
115118
subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, &
116119
restart_CS, ALE_CSp, tracer_Reg, sponge_CSp, &
117-
ALE_sponge_CSp, OBC, Time_in, frac_shelf_h)
120+
ALE_sponge_CSp, oda_incupd_CSp, OBC, Time_in, frac_shelf_h)
118121
type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure.
119122
type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
120123
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
@@ -140,6 +143,7 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, &
140143
type(sponge_CS), pointer :: sponge_CSp !< The layerwise sponge control structure.
141144
type(ALE_sponge_CS), pointer :: ALE_sponge_CSp !< The ALE sponge control structure.
142145
type(ocean_OBC_type), pointer :: OBC !< The open boundary condition control structure.
146+
type(oda_incupd_CS), pointer :: oda_incupd_CSp !< The oda_incupd control structure.
143147
type(time_type), optional, intent(in) :: Time_in !< Time at the start of the run segment.
144148
real, dimension(SZI_(G),SZJ_(G)), &
145149
optional, intent(in) :: frac_shelf_h !< The fraction of the grid cell covered
@@ -157,7 +161,7 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, &
157161
logical :: from_Z_file, useALE
158162
logical :: new_sim
159163
integer :: write_geom
160-
logical :: use_temperature, use_sponge, use_OBC
164+
logical :: use_temperature, use_sponge, use_OBC, use_oda_incupd
161165
logical :: use_EOS ! If true, density is calculated from T & S using an equation of state.
162166
logical :: depress_sfc ! If true, remove the mass that would be displaced
163167
! by a large surface pressure by squeezing the column.
@@ -478,6 +482,16 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, &
478482
dt=dt, initial=.true.)
479483
endif
480484
endif
485+
486+
! Initialized assimilative incremental update (oda_incupd) structure and
487+
! register restart.
488+
call get_param(PF, mdl, "ODA_INCUPD", use_oda_incupd, &
489+
"If true, oda incremental updates will be applied "//&
490+
"everywhere in the domain.", default=.false.)
491+
if (use_oda_incupd) then
492+
call initialize_oda_incupd_fixed(G, GV, US, oda_incupd_CSp, restart_CS)
493+
endif
494+
481495
! This is the end of the block of code that might have initialized fields
482496
! internally at the start of a new run.
483497

@@ -615,6 +629,13 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, &
615629
if (debug_OBC) call open_boundary_test_extern_h(G, GV, OBC, h)
616630
call callTree_leave('MOM_initialize_state()')
617631

632+
! Set-up of data Assimilation with incremental update
633+
if (use_oda_incupd) then
634+
call initialize_oda_incupd_file(G, GV, US, use_temperature, tv, h, u, v, &
635+
PF, oda_incupd_CSp, restart_CS, Time)
636+
endif
637+
638+
618639
end subroutine MOM_initialize_state
619640

620641
!> Reads the layer thicknesses or interface heights from a file.
@@ -2022,6 +2043,157 @@ end function separate_idamp_for_uv
20222043

20232044
end subroutine initialize_sponges_file
20242045

2046+
subroutine initialize_oda_incupd_file(G, GV, US, use_temperature, tv, h, u, v, param_file, &
2047+
oda_incupd_CSp, restart_CS, Time)
2048+
type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure.
2049+
type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
2050+
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
2051+
logical, intent(in) :: use_temperature !< If true, T & S are state variables.
2052+
type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic
2053+
!! variables.
2054+
real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
2055+
intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] (in)
2056+
2057+
real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), &
2058+
intent(in) :: u !< The zonal velocity that is being
2059+
!! initialized [L T-1 ~> m s-1]
2060+
real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), &
2061+
intent(in) :: v !< The meridional velocity that is being
2062+
!! initialized [L T-1 ~> m s-1]
2063+
type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters.
2064+
type(oda_incupd_CS), pointer :: oda_incupd_CSp !< A pointer that is set to point to the control
2065+
!! structure for this module.
2066+
type(MOM_restart_CS), pointer :: restart_CS !< A pointer to the restart control
2067+
!! structure.
2068+
type(time_type), intent(in) :: Time !< Time at the start of the run segment. Time_in
2069+
!! overrides any value set for
2070+
!Time.
2071+
! Local variables
2072+
real, allocatable, dimension(:,:,:) :: hoda ! The layer thk inc. and oda layer thk [H ~> m or kg m-2].
2073+
real, allocatable, dimension(:,:,:) :: tmp_tr ! A temporary array for reading oda fields
2074+
real, allocatable, dimension(:,:,:) :: tmp_u,tmp_v ! A temporary array for reading oda fields
2075+
2076+
integer :: i, j, k, is, ie, js, je, nz
2077+
integer :: isd, ied, jsd, jed
2078+
2079+
integer, dimension(4) :: siz
2080+
integer :: nz_data ! The size of the sponge source grid
2081+
logical :: oda_inc ! input files are increments (true) or full fields (false)
2082+
logical :: save_inc ! save increments if using full fields
2083+
logical :: uv_inc ! use u and v increments
2084+
logical :: reset_ncount ! reset ncount to zero if true
2085+
2086+
character(len=40) :: tempinc_var, salinc_var, uinc_var, vinc_var, h_var
2087+
character(len=40) :: mdl = "initialize_oda_incupd_file"
2088+
character(len=200) :: inc_file, uv_inc_file ! Strings for filenames
2089+
character(len=200) :: filename, inputdir ! Strings for file/path and path.
2090+
2091+
! logical :: use_ALE ! True if ALE is being used, False if in layered mode
2092+
2093+
is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke
2094+
isd = G%isd ; ied = G%ied ; jsd = G%jsd ; jed = G%jed
2095+
2096+
call get_param(param_file, mdl, "INPUTDIR", inputdir, default=".")
2097+
inputdir = slasher(inputdir)
2098+
2099+
call get_param(param_file, mdl, "ODA_INCUPD_FILE", inc_file, &
2100+
"The name of the file with the T,S,h increments.", &
2101+
fail_if_missing=.true.)
2102+
call get_param(param_file, mdl, "ODA_INCUPD_INC", oda_inc, &
2103+
"INCUPD files are increments and not full fields.", &
2104+
default=.true.)
2105+
if (.not.oda_inc) then
2106+
call get_param(param_file, mdl, "ODA_INCUPD_SAVE", save_inc, &
2107+
"If true, save the increments when using full fields.", &
2108+
default=.false.)
2109+
endif
2110+
call get_param(param_file, mdl, "ODA_INCUPD_RESET_NCOUNT", reset_ncount, &
2111+
"If True, reinitialize number of updates already done, ncount.",&
2112+
default=.true.)
2113+
if (.not.oda_inc .and. .not.reset_ncount) &
2114+
call MOM_error(FATAL, " initialize_oda_incupd: restarting during update "// &
2115+
"necessitates increments input file")
2116+
2117+
call get_param(param_file, mdl, "ODA_TEMPINC_VAR", tempinc_var, &
2118+
"The name of the potential temperature inc. variable in "//&
2119+
"ODA_INCUPD_FILE.", default="ptemp_inc")
2120+
call get_param(param_file, mdl, "ODA_SALTINC_VAR", salinc_var, &
2121+
"The name of the salinity inc. variable in "//&
2122+
"ODA_INCUPD_FILE.", default="sal_inc")
2123+
call get_param(param_file, mdl, "ODA_THK_VAR", h_var, &
2124+
"The name of the layer thickness variable in "//&
2125+
"ODA_INCUPD_FILE.", default="h")
2126+
call get_param(param_file, mdl, "ODA_INCUPD_UV", uv_inc, &
2127+
"use U,V increments.", &
2128+
default=.true.)
2129+
call get_param(param_file, mdl, "ODA_INCUPD_UV_FILE", uv_inc_file, &
2130+
"The name of the file with the U,V increments.", &
2131+
default=inc_file)
2132+
call get_param(param_file, mdl, "ODA_UINC_VAR", uinc_var, &
2133+
"The name of the zonal vel. inc. variable in "//&
2134+
"ODA_INCUPD_FILE.", default="u_inc")
2135+
call get_param(param_file, mdl, "ODA_VINC_VAR", vinc_var, &
2136+
"The name of the meridional vel. inc. variable in "//&
2137+
"ODA_INCUPD_FILE.", default="v_inc")
2138+
2139+
! call get_param(param_file, mdl, "USE_REGRIDDING", use_ALE, do_not_log = .true.)
2140+
2141+
! Read in incremental update for tracers
2142+
filename = trim(inputdir)//trim(inc_file)
2143+
call log_param(param_file, mdl, "INPUTDIR/ODA_INCUPD_FILE", filename)
2144+
if (.not.file_exists(filename, G%Domain)) &
2145+
call MOM_error(FATAL, " initialize_oda_incupd: Unable to open "//trim(filename))
2146+
2147+
call field_size(filename,h_var,siz,no_domain=.true.)
2148+
if (siz(1) /= G%ieg-G%isg+1 .or. siz(2) /= G%jeg-G%jsg+1) &
2149+
call MOM_error(FATAL,"initialize_oda_incupd_file: Array size mismatch for oda data.")
2150+
nz_data = siz(3)
2151+
! get h increments
2152+
allocate(hoda(isd:ied,jsd:jed,nz_data))
2153+
call MOM_read_data(filename, h_var , hoda(:,:,:), G%Domain, scale=US%m_to_Z)
2154+
call initialize_oda_incupd( G, GV, US, param_file, oda_incupd_CSp, hoda, nz_data, restart_CS)
2155+
deallocate(hoda)
2156+
2157+
! set-up T and S increments arrays
2158+
if (use_temperature) then
2159+
allocate(tmp_tr(isd:ied,jsd:jed,nz_data))
2160+
! temperature inc. in array Inc(1)
2161+
call MOM_read_data(filename, tempinc_var, tmp_tr(:,:,:), G%Domain)
2162+
call set_up_oda_incupd_field(tmp_tr, G, GV, oda_incupd_CSp)
2163+
! salinity inc. in array Inc(2)
2164+
call MOM_read_data(filename, salinc_var, tmp_tr(:,:,:), G%Domain)
2165+
call set_up_oda_incupd_field(tmp_tr, G, GV, oda_incupd_CSp)
2166+
deallocate(tmp_tr)
2167+
endif
2168+
2169+
! set-up U and V increments arrays
2170+
if (uv_inc) then
2171+
filename = trim(inputdir)//trim(uv_inc_file)
2172+
call log_param(param_file, mdl, "INPUTDIR/ODA_INCUPD_UV_FILE", filename)
2173+
if (.not.file_exists(filename, G%Domain)) &
2174+
call MOM_error(FATAL, " initialize_oda_incupd_uv: Unable to open "//trim(filename))
2175+
allocate(tmp_u(G%IsdB:G%IedB,jsd:jed,nz_data))
2176+
allocate(tmp_v(isd:ied,G%JsdB:G%JedB,nz_data))
2177+
tmp_u(:,:,:) = 0.0 ; tmp_v(:,:,:) = 0.0
2178+
call MOM_read_vector(filename, uinc_var, vinc_var, tmp_u, tmp_v, G%Domain,scale=US%m_s_to_L_T)
2179+
call set_up_oda_incupd_vel_field(tmp_u, tmp_v, G, GV, oda_incupd_CSp)
2180+
deallocate(tmp_u,tmp_v)
2181+
endif
2182+
2183+
! calculate increments if input are full fields
2184+
if (oda_inc) then ! input are increments
2185+
if (is_root_pe()) call MOM_error(NOTE,"incupd using increments fields ")
2186+
else ! inputs are full fields
2187+
if (is_root_pe()) call MOM_error(NOTE,"incupd using full fields ")
2188+
call calc_oda_increments(h, tv, u, v, G, GV, US, oda_incupd_CSp)
2189+
if (save_inc) then
2190+
call output_oda_incupd_inc(Time, G, GV, param_file, oda_incupd_CSp, US)
2191+
endif
2192+
endif ! not oda_inc
2193+
2194+
end subroutine initialize_oda_incupd_file
2195+
2196+
20252197
!> This subroutine sets the 4 bottom depths at velocity points to be the
20262198
!! maximum of the adjacent depths.
20272199
subroutine set_velocity_depth_max(G)

0 commit comments

Comments
 (0)