14 implicit none ;
private
16 #include <MOM_memory.h>
18 public basin_builder_topography
21 # include "version_variable.h"
22 character(len=40) :: mdl =
"basin_builder"
27 subroutine basin_builder_topography(D, G, param_file, max_depth)
29 real,
dimension(G%isd:G%ied,G%jsd:G%jed), &
32 real,
intent(in) :: max_depth
34 character(len=17) :: pname1, pname2
35 character(len=20) :: funcs
36 real,
dimension(20) :: pars
39 integer :: i, j, n, n_funcs
41 call mom_mesg(
" basin_builder.F90, basin_builder_topography: setting topography", 5)
44 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
48 call get_param(param_file, mdl,
"BBUILDER_N", n_funcs, &
49 "Number of pieces of topography to use.", fail_if_missing=.true.)
52 write( pname1,
"('BBUILDER_',i3.3,'_FUNC')" ) n
53 write( pname2,
"('BBUILDER_',i3.3,'_PARS')" ) n
54 call get_param(param_file, mdl, pname1, funcs, &
55 "The basin builder function to apply with parameters "//&
56 trim(pname2)//
". Choices are: NS_COAST, EW_COAST, "//&
57 "CIRC_CONIC_RIDGE, NS_CONIC_RIDGE, CIRC_SCURVE_RIDGE, "//&
59 fail_if_missing=.true.)
61 if (trim(lowercase(funcs)) ==
'ns_coast')
then
62 call get_param(param_file, mdl, pname2, pars(1:5), &
63 "NS_COAST parameters: longitude, starting latitude, "//&
64 "ending latitude, footprint radius, shelf depth.", &
65 units=
"degrees_E,degrees_N,degrees_N,degrees,m", &
66 fail_if_missing=.true.)
67 pars(5) = pars(5) / max_depth
68 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
71 d(i,j) = min( d(i,j), ns_coast(lon, lat, pars(1), pars(2), pars(3), pars(4), pars(5)) )
73 elseif (trim(lowercase(funcs)) ==
'ns_conic_ridge')
then
74 call get_param(param_file, mdl, pname2, pars(1:5), &
75 "NS_CONIC_RIDGE parameters: longitude, starting latitude, "//&
76 "ending latitude, footprint radius, ridge height.", &
77 units=
"degrees_E,degrees_N,degrees_N,degrees,m", &
78 fail_if_missing=.true.)
79 pars(5) = pars(5) / max_depth
80 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
83 d(i,j) = min( d(i,j), ns_conic_ridge(lon, lat, pars(1), pars(2), pars(3), pars(4), pars(5)) )
85 elseif (trim(lowercase(funcs)) ==
'ns_scurve_ridge')
then
86 call get_param(param_file, mdl, pname2, pars(1:5), &
87 "NS_SCURVE_RIDGE parameters: longitude, starting latitude, "//&
88 "ending latitude, footprint radius, ridge height.", &
89 units=
"degrees_E,degrees_N,degrees_N,degrees,m", &
90 fail_if_missing=.true.)
91 pars(5) = pars(5) / max_depth
92 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
95 d(i,j) = min( d(i,j), ns_scurve_ridge(lon, lat, pars(1), pars(2), pars(3), pars(4), pars(5)) )
97 elseif (trim(lowercase(funcs)) ==
'ew_coast')
then
98 call get_param(param_file, mdl, pname2, pars(1:5), &
99 "EW_COAST parameters: latitude, starting longitude, "//&
100 "ending longitude, footprint radius, shelf depth.", &
101 units=
"degrees_N,degrees_E,degrees_E,degrees,m", &
102 fail_if_missing=.true.)
103 pars(5) = pars(5) / max_depth
104 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
107 d(i,j) = min( d(i,j), ew_coast(lon, lat, pars(1), pars(2), pars(3), pars(4), pars(5)) )
109 elseif (trim(lowercase(funcs)) ==
'circ_conic_ridge')
then
110 call get_param(param_file, mdl, pname2, pars(1:5), &
111 "CIRC_CONIC_RIDGE parameters: center longitude, center latitude, "//&
112 "ring radius, footprint radius, ridge height.", &
113 units=
"degrees_E,degrees_N,degrees,degrees,m", &
114 fail_if_missing=.true.)
115 pars(5) = pars(5) / max_depth
116 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
119 d(i,j) = min( d(i,j), circ_conic_ridge(lon, lat, pars(1), pars(2), pars(3), pars(4), pars(5)) )
121 elseif (trim(lowercase(funcs)) ==
'circ_scurve_ridge')
then
122 call get_param(param_file, mdl, pname2, pars(1:5), &
123 "CIRC_SCURVe_RIDGE parameters: center longitude, center latitude, "//&
124 "ring radius, footprint radius, ridge height.", &
125 units=
"degrees_E,degrees_N,degrees,degrees,m", &
126 fail_if_missing=.true.)
127 pars(5) = pars(5) / max_depth
128 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
131 d(i,j) = min( d(i,j), circ_scurve_ridge(lon, lat, pars(1), pars(2), pars(3), pars(4), pars(5)) )
134 call mom_error(fatal,
"basin_builder.F90, basin_builer_topography:\n"//&
135 "Unrecognized function "//trim(funcs))
140 do j=g%jsc,g%jec ;
do i=g%isc,g%iec
142 d(i,j) = d(i,j) * max_depth
145 end subroutine basin_builder_topography
151 real function cone(x, x0, L, clip)
152 real,
intent(in) :: x
153 real,
intent(in) :: x0
154 real,
intent(in) :: l
155 real,
optional,
intent(in) :: clip
157 cone = max( 0., 1. - abs(x - x0) / l )
158 if (
present(clip)) cone = min(clip, cone)
162 real function scurve(x, x0, L)
163 real,
intent(in) :: x
164 real,
intent(in) :: x0
165 real,
intent(in) :: l
168 s = max( 0., min( 1.,( x - x0 ) / l ) )
169 scurve = ( 3. - 2.*s ) * ( s * s )
173 real function cstprof(x, x0, L, lf, bf, sf, sh)
174 real,
intent(in) :: x
175 real,
intent(in) :: x0
176 real,
intent(in) :: l
177 real,
intent(in) :: lf
178 real,
intent(in) :: bf
179 real,
intent(in) :: sf
180 real,
intent(in) :: sh
183 s = max( 0., min( 1.,( x - x0 ) / l ) )
184 cstprof = sh * scurve(s-lf,0.,bf) + (1.-sh) * scurve(s - (1.-sf),0.,sf)
188 real function dist_line_fixed_x(x, y, x0, y0, y1)
189 real,
intent(in) :: x
190 real,
intent(in) :: y
191 real,
intent(in) :: x0
192 real,
intent(in) :: y0
193 real,
intent(in) :: y1
197 yr = min( max(y0,y1), max( min(y0,y1), y ) )
199 dist_line_fixed_x = sqrt( dx*dx + dy*dy )
200 end function dist_line_fixed_x
203 real function dist_line_fixed_y(x, y, x0, x1, y0)
204 real,
intent(in) :: x
205 real,
intent(in) :: y
206 real,
intent(in) :: x0
207 real,
intent(in) :: x1
208 real,
intent(in) :: y0
211 dist_line_fixed_y = dist_line_fixed_x(y, x, y0, x0, x1)
212 end function dist_line_fixed_y
215 real function ns_coast(lon, lat, lonC, lat0, lat1, dlon, sh)
216 real,
intent(in) :: lon
217 real,
intent(in) :: lat
218 real,
intent(in) :: lonc
219 real,
intent(in) :: lat0
220 real,
intent(in) :: lat1
221 real,
intent(in) :: dlon
222 real,
intent(in) :: sh
225 r = dist_line_fixed_x( lon, lat, lonc, lat0, lat1 )
226 ns_coast = cstprof(r, 0., dlon, 0.125, 0.125, 0.5, sh)
227 end function ns_coast
230 real function ew_coast(lon, lat, latC, lon0, lon1, dlat, sh)
231 real,
intent(in) :: lon
232 real,
intent(in) :: lat
233 real,
intent(in) :: latc
234 real,
intent(in) :: lon0
235 real,
intent(in) :: lon1
236 real,
intent(in) :: dlat
237 real,
intent(in) :: sh
240 r = dist_line_fixed_y( lon, lat, lon0, lon1, latc )
241 ew_coast = cstprof(r, 0., dlat, 0.125, 0.125, 0.5, sh)
242 end function ew_coast
245 real function ns_conic_ridge(lon, lat, lonC, lat0, lat1, dlon, rh)
246 real,
intent(in) :: lon
247 real,
intent(in) :: lat
248 real,
intent(in) :: lonc
249 real,
intent(in) :: lat0
250 real,
intent(in) :: lat1
251 real,
intent(in) :: dlon
252 real,
intent(in) :: rh
255 r = dist_line_fixed_x( lon, lat, lonc, lat0, lat1 )
256 ns_conic_ridge = 1. - rh * cone(r, 0., dlon)
257 end function ns_conic_ridge
260 real function ns_scurve_ridge(lon, lat, lonC, lat0, lat1, dlon, rh)
261 real,
intent(in) :: lon
262 real,
intent(in) :: lat
263 real,
intent(in) :: lonc
264 real,
intent(in) :: lat0
265 real,
intent(in) :: lat1
266 real,
intent(in) :: dlon
267 real,
intent(in) :: rh
270 r = dist_line_fixed_x( lon, lat, lonc, lat0, lat1 )
271 ns_scurve_ridge = 1. - rh * (1. - scurve(r, 0., dlon) )
272 end function ns_scurve_ridge
275 real function circ_conic_ridge(lon, lat, lon0, lat0, ring_radius, ring_thickness, ridge_height)
276 real,
intent(in) :: lon
277 real,
intent(in) :: lat
278 real,
intent(in) :: lon0
279 real,
intent(in) :: lat0
280 real,
intent(in) :: ring_radius
281 real,
intent(in) :: ring_thickness
282 real,
intent(in) :: ridge_height
285 r = sqrt( (lon - lon0)**2 + (lat - lat0)**2 )
286 r = abs( r - ring_radius)
287 r = cone(r, 0., ring_thickness, ridge_height)
288 circ_conic_ridge = 1. - r
289 end function circ_conic_ridge
292 real function circ_scurve_ridge(lon, lat, lon0, lat0, ring_radius, ring_thickness, ridge_height)
293 real,
intent(in) :: lon
294 real,
intent(in) :: lat
295 real,
intent(in) :: lon0
296 real,
intent(in) :: lat0
297 real,
intent(in) :: ring_radius
298 real,
intent(in) :: ring_thickness
299 real,
intent(in) :: ridge_height
302 r = sqrt( (lon - lon0)**2 + (lat - lat0)**2 )
303 r = abs( r - ring_radius)
304 r = 1. - scurve(r, 0., ring_thickness)
306 circ_scurve_ridge = 1. - r
307 end function circ_scurve_ridge