user_initialization.F90
1! This file is part of MOM6, the Modular Ocean Model version 6.
2! See the LICENSE file for licensing information.
3! SPDX-License-Identifier: Apache-2.0
4
5!> A template of a user to code up customized initial conditions.
6module user_initialization
7
8use mom_error_handler, only : mom_mesg, mom_error, fatal, is_root_pe
9use mom_dyn_horgrid, only : dyn_horgrid_type
10use mom_file_parser, only : get_param, log_version, param_file_type
11use mom_get_input, only : directories
12use mom_grid, only : ocean_grid_type
13use mom_open_boundary, only : ocean_obc_type, obc_none
14use mom_open_boundary, only : obc_direction_e, obc_direction_w, obc_direction_n
15use mom_open_boundary, only : obc_direction_s
16use mom_sponge, only : set_up_sponge_field, initialize_sponge, sponge_cs
17use mom_tracer_registry, only : tracer_registry_type
18use mom_unit_scaling, only : unit_scale_type
19use mom_variables, only : thermo_var_ptrs
20use mom_verticalgrid, only : verticalgrid_type
21
22implicit none ; private
23
24#include <MOM_memory.h>
25
29
30! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional
31! consistency testing. These are noted in comments with units like Z, H, L, and T, along with
32! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units
33! vary with the Boussinesq approximation, the Boussinesq variant is given first.
34
35!> A module variable that should not be used.
36!! \todo Move this module variable into a control structure.
37logical :: first_call = .true.
38
39contains
40
41!> Set vertical coordinates.
42subroutine user_set_coord(Rlay, g_prime, GV, US, param_file)
43 type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure
44 real, dimension(GV%ke), intent(out) :: rlay !< Layer potential density [R ~> kg m-3].
45 real, dimension(GV%ke+1), intent(out) :: g_prime !< The reduced gravity at each
46 !! interface [L2 Z-1 T-2 ~> m s-2].
47 type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
48 type(param_file_type), intent(in) :: param_file !< A structure indicating the
49 !! open file to parse for model
50 !! parameter values.
51
52 call mom_error(fatal, &
53 "USER_initialization.F90, USER_set_coord: " // &
54 "Unmodified user routine called - you must edit the routine to use it")
55 rlay(:) = 0.0
56 g_prime(:) = 0.0
57
58 if (first_call) call write_user_log(param_file)
59
60end subroutine user_set_coord
61
62!> Initialize topography.
63subroutine user_initialize_topography(D, G, param_file, max_depth, US)
64 type(dyn_horgrid_type), intent(in) :: g !< The dynamic horizontal grid type
65 real, dimension(G%isd:G%ied,G%jsd:G%jed), &
66 intent(out) :: d !< Ocean bottom depth [Z ~> m]
67 type(param_file_type), intent(in) :: param_file !< Parameter file structure
68 real, intent(in) :: max_depth !< Maximum model depth [Z ~> m]
69 type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
70
71 call mom_error(fatal, &
72 "USER_initialization.F90, USER_initialize_topography: " // &
73 "Unmodified user routine called - you must edit the routine to use it")
74
75 d(:,:) = 0.0
76
77 if (first_call) call write_user_log(param_file)
78
79end subroutine user_initialize_topography
80
81!> Initialize thicknesses in depth units. These will be converted to thickness units later.
82subroutine user_initialize_thickness(h, G, GV, param_file, just_read)
83 type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
84 type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
85 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
86 intent(out) :: h !< The thicknesses being initialized [Z ~> m]
87 type(param_file_type), intent(in) :: param_file !< A structure indicating the open
88 !! file to parse for model parameter values.
89 logical, intent(in) :: just_read !< If true, this call will
90 !! only read parameters without changing h.
91
92 call mom_error(fatal, &
93 "USER_initialization.F90, USER_initialize_thickness: " // &
94 "Unmodified user routine called - you must edit the routine to use it")
95
96 if (just_read) return ! All run-time parameters have been read, so return.
97
98 h(:,:,1:gv%ke) = 0.0 ! h should be set in [Z ~> m]. It will be converted to thickness units
99 ! [H ~> m or kg m-2] once the temperatures and salinities are known.
100
101 if (first_call) call write_user_log(param_file)
102
103end subroutine user_initialize_thickness
104
105!> initialize velocities.
106subroutine user_initialize_velocity(u, v, G, GV, US, param_file, just_read)
107 type(ocean_grid_type), intent(in) :: g !< Ocean grid structure.
108 type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
109 real, dimension(SZIB_(G), SZJ_(G),SZK_(GV)), intent(out) :: u !< i-component of velocity [L T-1 ~> m s-1]
110 real, dimension(SZI_(G), SZJB_(G),SZK_(GV)), intent(out) :: v !< j-component of velocity [L T-1 ~> m s-1]
111 type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
112 type(param_file_type), intent(in) :: param_file !< A structure indicating the
113 !! open file to parse for model
114 !! parameter values.
115 logical, intent(in) :: just_read !< If true, this call will
116 !! only read parameters without changing u & v.
117
118 call mom_error(fatal, &
119 "USER_initialization.F90, USER_initialize_velocity: " // &
120 "Unmodified user routine called - you must edit the routine to use it")
121
122 if (just_read) return ! All run-time parameters have been read, so return.
123
124 u(:,:,1) = 0.0
125 v(:,:,1) = 0.0
126
127 if (first_call) call write_user_log(param_file)
128
129end subroutine user_initialize_velocity
130
131!> This function puts the initial layer temperatures and salinities
132!! into T(:,:,:) and S(:,:,:).
133subroutine user_init_temperature_salinity(T, S, G, GV, param_file, just_read)
134 type(ocean_grid_type), intent(in) :: g !< Ocean grid structure.
135 type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
136 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: t !< Potential temperature [C ~> degC].
137 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: s !< Salinity [S ~> ppt].
138 type(param_file_type), intent(in) :: param_file !< A structure indicating the
139 !! open file to parse for model
140 !! parameter values.
141 logical, intent(in) :: just_read !< If true, this call will only
142 !! read parameters without changing T & S.
143
144 call mom_error(fatal, &
145 "USER_initialization.F90, USER_init_temperature_salinity: " // &
146 "Unmodified user routine called - you must edit the routine to use it")
147
148 if (just_read) return ! All run-time parameters have been read, so return.
149
150 t(:,:,1) = 0.0
151 s(:,:,1) = 0.0
152
153 if (first_call) call write_user_log(param_file)
154
155end subroutine user_init_temperature_salinity
156
157!> Set up the sponges.
158subroutine user_initialize_sponges(G, GV, use_temp, tv, param_file, CSp, h)
159 type(ocean_grid_type), intent(in) :: g !< Ocean grid structure.
160 type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
161 logical, intent(in) :: use_temp !< If true, temperature and salinity are state variables.
162 type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers
163 !! to any available thermodynamic
164 !! fields, potential temperature and
165 !! salinity or mixed layer density.
166 !! Absent fields have NULL ptrs.
167 type(param_file_type), intent(in) :: param_file !< A structure indicating the
168 !! open file to parse for model
169 !! parameter values.
170 type(sponge_cs), pointer :: csp !< A pointer to the sponge control structure.
171 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
172 intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2].
173 call mom_error(fatal, &
174 "USER_initialization.F90, USER_initialize_sponges: " // &
175 "Unmodified user routine called - you must edit the routine to use it")
176
177 if (first_call) call write_user_log(param_file)
178
179end subroutine user_initialize_sponges
180
181!> This subroutine sets the properties of flow at open boundary conditions.
182subroutine user_set_obc_data(OBC, tv, G, GV, param_file, tr_Reg)
183 type(ocean_obc_type), pointer :: obc !< This open boundary condition type specifies
184 !! whether, where, and what open boundary
185 !! conditions are used.
186 type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any
187 !! available thermodynamic fields, including potential
188 !! temperature and salinity or mixed layer density. Absent
189 !! fields have NULL ptrs.
190 type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
191 type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
192 type(param_file_type), intent(in) :: param_file !< A structure indicating the
193 !! open file to parse for model
194 !! parameter values.
195 type(tracer_registry_type), pointer :: tr_reg !< Tracer registry.
196! call MOM_error(FATAL, &
197! "USER_initialization.F90, USER_set_OBC_data: " // &
198! "Unmodified user routine called - you must edit the routine to use it")
199
200 if (first_call) call write_user_log(param_file)
201
202end subroutine user_set_obc_data
203
204subroutine user_set_rotation(G, param_file)
205 type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure
206 type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters
207 call mom_error(fatal, &
208 "USER_initialization.F90, USER_set_rotation: " // &
209 "Unmodified user routine called - you must edit the routine to use it")
210
211 if (first_call) call write_user_log(param_file)
212
213end subroutine user_set_rotation
214
215!> Write output about the parameter values being used.
216subroutine write_user_log(param_file)
217 type(param_file_type), intent(in) :: param_file !< A structure indicating the
218 !! open file to parse for model
219 !! parameter values.
220
221 ! This include declares and sets the variable "version".
222# include "version_variable.h"
223 character(len=40) :: mdl = "user_initialization" ! This module's name.
224
225 call log_version(param_file, mdl, version)
226 first_call = .false.
227
228end subroutine write_user_log
229
230!> \namespace user_initialization
231!!
232!! This subroutine initializes the fields for the simulations.
233!! The one argument passed to initialize, Time, is set to the
234!! current time of the simulation. The fields which might be initialized
235!! here are:
236!! - u - Zonal velocity [Z T-1 ~> m s-1].
237!! - v - Meridional velocity [Z T-1 ~> m s-1].
238!! - h - Layer thickness [H ~> m or kg m-2]. (Must be positive.)
239!! - G%bathyT - Basin depth [Z ~> m].
240!! - G%CoriolisBu - The Coriolis parameter [T-1 ~> s-1].
241!! - GV%g_prime - The reduced gravity at each interface [L2 Z-1 T-2 ~> m s-2].
242!! - GV%Rlay - Layer potential density (coordinate variable) [R ~> kg m-3].
243!! If ENABLE_THERMODYNAMICS is defined:
244!! - T - Temperature [C ~> degC].
245!! - S - Salinity [S ~> ppt].
246!! If BULKMIXEDLAYER is defined:
247!! - Rml - Mixed layer and buffer layer potential densities [R ~> kg m-3].
248!! If SPONGE is defined:
249!! - A series of subroutine calls are made to set up the damping
250!! rates and reference profiles for all variables that are damped
251!! in the sponge.
252!!
253!! Any user provided tracer code is also first linked through this
254!! subroutine.
255!!
256!! These variables are all set in the set of subroutines (in this
257!! file) USER_initialize_bottom_depth, USER_initialize_thickness,
258!! USER_initialize_velocity, USER_initialize_temperature_salinity,
259!! USER_initialize_mixed_layer_density, USER_initialize_sponges,
260!! USER_set_coord, and USER_set_ref_profile.
261!!
262!! The names of these subroutines should be self-explanatory. They
263!! start with "USER_" to indicate that they will likely have to be
264!! modified for each simulation to set the initial conditions and
265!! boundary conditions. Most of these take two arguments: an integer
266!! argument specifying whether the fields are to be calculated
267!! internally or read from a NetCDF file; and a string giving the
268!! path to that file. If the field is initialized internally, the
269!! path is ignored.
270
271end module user_initialization