@@ -11,7 +11,7 @@ module MOM_state_initialization
1111use MOM_cpu_clock, only : CLOCK_ROUTINE, CLOCK_LOOP
1212use MOM_domains, only : pass_var, pass_vector, sum_across_PEs, broadcast
1313use 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
1515use MOM_error_handler, only : callTree_enter, callTree_leave, callTree_waypoint
1616use MOM_file_parser, only : get_param, read_param, log_param, param_file_type
1717use MOM_file_parser, only : log_version
@@ -94,6 +94,9 @@ module MOM_state_initialization
9494use MOM_remapping, only : remapping_CS, initialize_remapping
9595use MOM_remapping, only : remapping_core_h
9696use 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
98101implicit none ; private
99102
@@ -114,7 +117,7 @@ module MOM_state_initialization
114117! ! conditions or by reading them from a restart (or saves) file.
115118subroutine 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+
618639end 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
20232044end 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.
20272199subroutine set_velocity_depth_max (G )
0 commit comments