/[MITgcm]/MITgcm/pkg/exf/exf_getffields.F
ViewVC logotype

Contents of /MITgcm/pkg/exf/exf_getffields.F

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download)
Fri Jan 11 19:24:24 2002 UTC (22 years, 5 months ago) by heimbach
Branch: MAIN
CVS Tags: checkpoint44e_post, checkpoint46l_post, checkpoint46g_pre, checkpoint46f_post, checkpoint44f_post, checkpoint46b_post, checkpoint46l_pre, chkpt44d_post, checkpoint44e_pre, checkpoint46d_pre, checkpoint45d_post, checkpoint46j_pre, chkpt44a_post, checkpoint44h_pre, checkpoint46a_post, checkpoint46j_post, checkpoint46k_post, chkpt44c_pre, checkpoint45a_post, checkpoint44g_post, checkpoint46e_pre, checkpoint45b_post, checkpoint46b_pre, release1_final_v1, checkpoint46c_pre, checkpoint46, checkpoint44b_post, checkpoint46h_pre, checkpoint46m_post, checkpoint46a_pre, checkpoint45c_post, checkpoint44h_post, checkpoint46g_post, chkpt44a_pre, checkpoint46i_post, checkpoint46c_post, checkpoint46e_post, checkpoint44b_pre, checkpoint44, checkpoint45, checkpoint46h_post, chkpt44c_post, checkpoint44f_pre, checkpoint46d_post
Branch point for: release1_final
Changes since 1.2: +141 -64 lines
Changes to enable field swapping for external forcing
consistent with adjoint flow.
This allows to avoid in both forward and adjoint mode
the reading of fields at every time step.

1 c $Header: /u/gcmpack/development/heimbach/ecco_env/pkg/exf/exf_getffields.F,v 1.13 2002/01/11 17:34:46 heimbach Exp $
2
3 #include "EXF_CPPOPTIONS.h"
4
5 subroutine exf_GetFFields( mycurrenttime, mycurrentiter, mythid )
6
7 c ==================================================================
8 c SUBROUTINE exf_GetFFields
9 c ==================================================================
10 c
11 c o Get the surface fluxes either from file or as derived from bulk
12 c formulae that use the atmospheric state.
13 c
14 c The calculation of the bulk surface fluxes has been adapted from
15 c the NCOM model which uses the formulae given in Large and Pond
16 c (1981 & 1982 )
17 c
18 c
19 c Header taken from NCOM version: ncom1.4.1
20 c -----------------------------------------
21 c
22 c Following procedures and coefficients in Large and Pond
23 c (1981 ; 1982)
24 c
25 c Output: Bulk estimates of the turbulent surface fluxes.
26 c -------
27 c
28 c hs - sensible heat flux (W/m^2), into ocean
29 c hl - latent heat flux (W/m^2), into ocean
30 c
31 c Input:
32 c ------
33 c
34 c us - mean wind speed (m/s) at height hu (m)
35 c th - mean air temperature (K) at height ht (m)
36 c qh - mean air humidity (kg/kg) at height hq (m)
37 c sst - sea surface temperature (K)
38 c tk0 - Kelvin temperature at 0 Celsius (K)
39 c
40 c Assume 1) a neutral 10m drag coefficient =
41 c
42 c cdn = .0027/u10 + .000142 + .0000764 u10
43 c
44 c 2) a neutral 10m stanton number =
45 c
46 c ctn = .0327 sqrt(cdn), unstable
47 c ctn = .0180 sqrt(cdn), stable
48 c
49 c 3) a neutral 10m dalton number =
50 c
51 c cen = .0346 sqrt(cdn)
52 c
53 c 4) the saturation humidity of air at
54 c
55 c t(k) = exf_BulkqSat(t) (kg/m^3)
56 c
57 c Note: 1) here, tstar = <wt>/u*, and qstar = <wq>/u*.
58 c 2) wind speeds should all be above a minimum speed,
59 c say 0.5 m/s.
60 c 3) with optional iteration loop, niter=3, should suffice.
61 c 4) this version is for analyses inputs with hu = 10m and
62 c ht = hq.
63 c 5) sst enters in Celsius.
64 c
65 c ------------------------------------
66 c
67 c By setting CPP options in the header file *EXF_CPPOPTIONS.h* it
68 c is possible to combine data sets in four different ways:
69 c
70 c The following options are available:
71 c
72 c ALLOW_ATM_TEMP (UAT)
73 c ALLOW_ATM_WIND (UAW)
74 c
75 c
76 c UAT | UAW | action
77 c ----------------------------------------------------
78 c undefined | undefined | Use surface fluxes.
79 c undefined | defined | Assume cdn(u) given to
80 c | | infer the wind stress.
81 c defined | undefined | Compute wind field from
82 c | | given stress assuming a
83 c | | linear relation.
84 c defined | defined | Use the bulk formulae.
85 c ----------------------------------------------------
86 c
87 c Implementations of the bulk formulae exist for the follwing
88 c versions of the MITgcm:
89 c
90 c MITgcm : Patrick Heimbach
91 c MITgcmUV: Christian Eckert
92 c
93 c started: Christian Eckert eckert@mit.edu 27-Aug-1999
94 c
95 c changed: Christian Eckert eckert@mit.edu 14-Jan-2000
96 c
97 c - restructured the original version in order to have a
98 c better interface to the MITgcmUV.
99 c
100 c Christian Eckert eckert@mit.edu 12-Feb-2000
101 c
102 c - Changed Routine names (package prefix: exf_)
103 c
104 c Patrick Heimbach, heimbach@mit.edu 04-May-2000
105 c
106 c - changed the handling of precip and sflux with respect
107 c to CPP options ALLOW_BULKFORMULAE and ALLOW_ATM_TEMP
108 c
109 c - included some CPP flags ALLOW_BULKFORMULAE to make
110 c sure ALLOW_ATM_TEMP, ALLOW_ATM_WIND are used only in
111 c conjunction with defined ALLOW_BULKFORMULAE
112 c
113 c - statement functions discarded
114 c
115 c Ralf.Giering@FastOpt.de 25-Mai-2000
116 c
117 c - total rewrite using new subroutines
118 c
119 c ==================================================================
120 c SUBROUTINE exf_GetFFields
121 c ==================================================================
122
123 implicit none
124
125 c == global variables ==
126
127 #include "EEPARAMS.h"
128 #include "SIZE.h"
129 #include "PARAMS.h"
130 #include "DYNVARS.h"
131 #include "GRID.h"
132
133 #include "exf_fields.h"
134 #include "exf_constants.h"
135
136 #ifdef ALLOW_AUTODIFF_TAMC
137 #include "tamc.h"
138 #endif
139
140 c == routine arguments ==
141
142 integer mythid
143 integer mycurrentiter
144 _RL mycurrenttime
145
146 c == local variables ==
147
148 integer bi,bj
149 integer i,j,k
150
151 #ifdef ALLOW_BULKFORMULAE
152
153 #ifdef ALLOW_ATM_TEMP
154 integer iter
155 _RL aln
156 _RL delq
157 _RL deltap
158 _RL hqol
159 _RL htol
160 _RL huol
161 _RL psimh
162 _RL psixh
163 _RL qstar
164 _RL rd
165 _RL re
166 _RL rdn
167 _RL rh
168 _RL ssttmp
169 _RL ssq
170 _RL stable
171 _RL tstar
172 _RL t0
173 _RL ustar
174 _RL uzn
175 _RL shn
176 _RL xsq
177 _RL x
178 _RL tau
179 _RL evap(1-olx:snx+olx,1-oly:sny+oly,nsx,nsy)
180 #ifdef ALLOW_AUTODIFF_TAMC
181 integer ikey_1
182 integer ikey_2
183 #endif
184 #endif /* ALLOW_ATM_TEMP */
185
186 _RL ustmp
187 _RL us
188 _RL cw
189 _RL sw
190 _RL sh
191 _RL hs(1-olx:snx+olx,1-oly:sny+oly,nsx,nsy)
192 _RL hl(1-olx:snx+olx,1-oly:sny+oly,nsx,nsy)
193 _RL hfl
194
195 #endif /* ALLOW_BULKFORMULAE */
196
197 c == external functions ==
198
199 integer ilnblnk
200 external ilnblnk
201
202 #ifdef ALLOW_BULKFORMULAE
203 _RL exf_BulkqSat
204 external exf_BulkqSat
205 _RL exf_BulkCdn
206 external exf_BulkCdn
207 _RL exf_BulkRhn
208 external exf_BulkRhn
209 #endif /* ALLOW_BULKFORMULAE */
210
211 c == end of interface ==
212
213 c determine forcing field records
214
215 #ifdef ALLOW_BULKFORMULAE
216
217 #if (defined (ALLOW_ATM_TEMP) || defined (ALLOW_ATM_WIND))
218 aln = log(ht/zref)
219 #endif
220
221 c Determine where we are in time and set counters, flags and
222 c the linear interpolation factors accordingly.
223 #ifdef ALLOW_ATM_TEMP
224 c Atmospheric temperature.
225 call exf_set_atemp( mycurrenttime, mycurrentiter, mythid )
226
227 c Atmospheric humidity.
228 call exf_set_aqh( mycurrenttime, mycurrentiter, mythid )
229
230 c Net long wave radiative flux.
231 call exf_set_lwflux( mycurrenttime, mycurrentiter, mythid )
232
233 c Net short wave radiative flux.
234 call exf_set_swflux( mycurrenttime, mycurrentiter, mythid )
235
236 c Precipitation.
237 call exf_set_precip( mycurrenttime, mycurrentiter, mythid )
238
239 #ifdef ALLOW_ATEMP_CONTROL
240 call ctrl_getatemp ( mycurrenttime, mycurrentiter, mythid )
241 #endif
242
243 #ifdef ALLOW_AQH_CONTROL
244 call ctrl_getaqh ( mycurrenttime, mycurrentiter, mythid )
245 #endif
246
247 #else
248
249 c Atmospheric heat flux.
250 call exf_set_hflux( mycurrenttime, mycurrentiter, mythid )
251
252 c Salt flux.
253 call exf_set_sflux( mycurrenttime, mycurrentiter, mythid )
254
255 #ifdef ALLOW_KPP
256 c Net short wave radiative flux.
257 call exf_set_swflux( mycurrenttime, mycurrentiter, mythid )
258
259 #endif /* ALLOW_KPP */
260
261 #endif /* ALLOW_ATM_TEMP */
262
263 #ifdef ALLOW_ATM_WIND
264 c Zonal wind.
265 call exf_set_uwind( mycurrenttime, mycurrentiter, mythid )
266
267 c Meridional wind.
268 call exf_set_vwind( mycurrenttime, mycurrentiter, mythid )
269
270 #ifdef ALLOW_UWIND_CONTROL
271 call ctrl_getuwind ( mycurrenttime, mycurrentiter, mythid )
272 #endif
273
274 #ifdef ALLOW_VWIND_CONTROL
275 call ctrl_getvwind ( mycurrenttime, mycurrentiter, mythid )
276 #endif
277
278 #else
279 c Zonal wind stress.
280 call exf_set_ustress( mycurrenttime, mycurrentiter, mythid )
281
282 c Meridional wind stress.
283 call exf_set_vstress( mycurrenttime, mycurrentiter, mythid )
284
285 #endif /* ALLOW_ATM_WIND */
286
287 #else /* ALLOW_BULKFORMULAE undefined */
288 c Atmospheric heat flux.
289 call exf_set_hflux( mycurrenttime, mycurrentiter, mythid )
290
291 c Salt flux.
292 call exf_set_sflux( mycurrenttime, mycurrentiter, mythid )
293
294 c Zonal wind stress.
295 call exf_set_ustress( mycurrenttime, mycurrentiter, mythid )
296
297 c Meridional wind stress.
298 call exf_set_vstress( mycurrenttime, mycurrentiter, mythid )
299
300 #ifdef ALLOW_KPP
301 c Net short wave radiative flux.
302 call exf_set_swflux( mycurrenttime, mycurrentiter, mythid )
303 #endif
304
305 #endif /* ALLOW_BULKFORMULAE */
306
307 c Loop over tiles.
308 #ifdef ALLOW_AUTODIFF_TAMC
309 C-- HPF directive to help TAMC
310 CHPF$ INDEPENDENT
311 #endif /* ALLOW_AUTODIFF_TAMC */
312 do bj = mybylo(mythid),mybyhi(mythid)
313 #ifdef ALLOW_AUTODIFF_TAMC
314 C-- HPF directive to help TAMC
315 CHPF$ INDEPENDENT
316 #endif
317 do bi = mybxlo(mythid),mybxhi(mythid)
318
319 k = 1
320
321 do j = 1-oly,sny+oly
322 do i = 1-olx,snx+olx
323
324 #ifdef ALLOW_BULKFORMULAE
325
326 #ifdef ALLOW_AUTODIFF_TAMC
327 act1 = bi - myBxLo(myThid)
328 max1 = myBxHi(myThid) - myBxLo(myThid) + 1
329 act2 = bj - myByLo(myThid)
330 max2 = myByHi(myThid) - myByLo(myThid) + 1
331 act3 = myThid - 1
332 max3 = nTx*nTy
333 act4 = ikey_dynamics - 1
334
335 ikey_1 = i
336 & + sNx*(j-1)
337 & + sNx*sNy*act1
338 & + sNx*sNy*max1*act2
339 & + sNx*sNy*max1*max2*act3
340 & + sNx*sNy*max1*max2*max3*act4
341 #endif
342
343 c Compute the turbulent surface fluxes.
344 c (Bulk formulae estimates)
345
346 #ifdef ALLOW_ATM_WIND
347 c Wind speed and direction.
348 ustmp = uwind(i,j,bi,bj)*uwind(i,j,bi,bj) +
349 & vwind(i,j,bi,bj)*vwind(i,j,bi,bj)
350 if ( ustmp .ne. 0. _d 0 ) then
351 us = sqrt(ustmp)
352 cw = uwind(i,j,bi,bj)/us
353 sw = vwind(i,j,bi,bj)/us
354 else
355 us = 0. _d 0
356 cw = 0. _d 0
357 sw = 0. _d 0
358 endif
359 sh = max(us,umin)
360 #else
361 #ifdef ALLOW_ATM_TEMP
362
363 c The variables us, sh and rdn have to be computed from
364 c given wind stresses inverting relationship for neutral
365 c drag coeff. cdn.
366 c The inversion is based on linear and quadratic form of
367 c cdn(umps); ustar can be directly computed from stress;
368
369 ustmp = ustress(i,j,bi,bj)*ustress(i,j,bi,bj) +
370 & vstress(i,j,bi,bj)*vstress(i,j,bi,bj)
371 if ( ustmp .ne. 0. _d 0 ) then
372 ustar = sqrt(ustmp/atmrho)
373 cw = ustress(i,j,bi,bj)/sqrt(ustmp)
374 sw = vstress(i,j,bi,bj)/sqrt(ustmp)
375 else
376 ustar = 0. _d 0
377 cw = 0. _d 0
378 sw = 0. _d 0
379 endif
380
381 if ( ustar .eq. 0. _d 0 ) then
382 us = 0. _d 0
383 else if ( ustar .lt. ustofu11 ) then
384 tmp1 = -cquadrag_2/cquadrag_1/2
385 tmp2 = sqrt(tmp1*tmp1 + ustar*ustar/cquadrag_1)
386 us = sqrt(tmp1 + tmp2)
387 else
388 tmp3 = clindrag_2/clindrag_1/3
389 tmp4 = ustar*ustar/clindrag_1/2 - tmp3**3
390 tmp5 = sqrt(ustar*ustar/clindrag_1*
391 & (ustar*ustar/clindrag_1/4 - tmp3**3))
392 us = (tmp4 + tmp5)**(1/3) +
393 & tmp3**2 * (tmp4 + tmp5)**(-1/3) - tmp3
394 endif
395
396 if ( us .ne. 0 ) then
397 rdn = ustar/us
398 else
399 rdn = 0. _d 0
400 end if
401
402 sh = max(us,umin)
403 #endif /* ALLOW_ATM_TEMP */
404 #endif /* ALLOW_ATM_WIND */
405
406 #ifdef ALLOW_ATM_TEMP
407
408 c Initial guess: z/l=0.0; hu=ht=hq=z
409 c Iterations: converge on z/l and hence the fluxes.
410 c t0 : virtual temperature (K)
411 c ssq : sea surface humidity (kg/kg)
412 c deltap : potential temperature diff (K)
413
414 if ( atemp(i,j,bi,bj) .ne. 0. _d 0 ) then
415 t0 = atemp(i,j,bi,bj)*
416 & (exf_one + humid_fac*aqh(i,j,bi,bj))
417 ssttmp = theta(i,j,k,bi,bj)
418 ssq = saltsat*
419 & exf_BulkqSat(ssttmp + cen2kel)/
420 & atmrho
421 deltap = atemp(i,j,bi,bj) + gamma_blk*ht -
422 & ssttmp - cen2kel
423 delq = aqh(i,j,bi,bj) - ssq
424 stable = exf_half + sign(exf_half, deltap)
425 #ifdef ALLOW_AUTODIFF_TAMC
426 CADJ STORE sh = comlev1_exf_1, key = ikey_1
427 #endif
428 rdn = sqrt(exf_BulkCdn(sh))
429 ustar = rdn*sh
430 tstar = exf_BulkRhn(stable)*deltap
431 qstar = cdalton*delq
432
433 do iter = 1,niter_bulk
434
435 #ifdef ALLOW_AUTODIFF_TAMC
436 ikey_2 = iter
437 & + niter_bulk*(i-1)
438 & + sNx*niter_bulk*(j-1)
439 & + sNx*niter_bulk*sNy*act1
440 & + sNx*niter_bulk*sNy*max1*act2
441 & + sNx*niter_bulk*sNy*max1*max2*act3
442 & + sNx*niter_bulk*sNy*max1*max2*max3*act4
443 #endif
444
445 #ifdef ALLOW_AUTODIFF_TAMC
446 CADJ STORE rdn = comlev1_exf_2, key = ikey_2
447 CADJ STORE ustar = comlev1_exf_2, key = ikey_2
448 CADJ STORE qstar = comlev1_exf_2, key = ikey_2
449 CADJ STORE tstar = comlev1_exf_2, key = ikey_2
450 CADJ STORE sh = comlev1_exf_2, key = ikey_2
451 CADJ STORE us = comlev1_exf_2, key = ikey_2
452 #endif
453
454 huol = czol*(tstar/t0 +
455 & qstar/(exf_one/humid_fac+aqh(i,j,bi,bj)))/
456 & ustar**2
457 huol = max(huol,zolmin)
458 stable = exf_half + sign(exf_half, huol)
459 htol = huol*ht/hu
460 hqol = huol*hq/hu
461
462 c Evaluate all stability functions assuming hq = ht.
463 xsq = max(sqrt(abs(exf_one - 16.*huol)),exf_one)
464 x = sqrt(xsq)
465 psimh = -psim_fac*huol*stable +
466 & (exf_one - stable)*
467 & log((exf_one + x*(exf_two + x))*
468 & (exf_one + xsq)/8.) - exf_two*atan(x) +
469 & pi*exf_half
470 xsq = max(sqrt(abs(exf_one - 16.*htol)),exf_one)
471 psixh = -psim_fac*htol*stable + (exf_one - stable)*
472 & exf_two*log((exf_one + xsq)/exf_two)
473
474 c Shift wind speed using old coefficient
475 ccc rd = rdn/(exf_one + rdn/karman*
476 ccc & (log(hu/zref) - psimh) )
477 rd = rdn/(exf_one - rdn/karman*psimh )
478 shn = sh*rd/rdn
479 uzn = max(shn, umin)
480
481 c Update the transfer coefficients at 10 meters
482 c and neutral stability.
483
484 rdn = sqrt(exf_BulkCdn(uzn))
485
486 c Shift all coefficients to the measurement height
487 c and stability.
488 c rd = rdn/(exf_one + rdn/karman*(log(hu/zref) - psimh))
489 rd = rdn/(exf_one - rdn/karman*psimh)
490 rh = exf_BulkRhn(stable)/(exf_one +
491 & exf_BulkRhn(stable)/
492 & karman*(aln - psixh))
493 re = cdalton/(exf_one + cdalton/karman*(aln - psixh))
494
495 c Update ustar, tstar, qstar using updated, shifted
496 c coefficients.
497 ustar = rd*sh
498 qstar = re*delq
499 tstar = rh*deltap
500 tau = atmrho*ustar**2
501 tau = tau*us/sh
502
503 enddo
504
505 #ifdef ALLOW_AUTODIFF_TAMC
506 CADJ STORE ustar = comlev1_exf_1, key = ikey_1
507 CADJ STORE qstar = comlev1_exf_1, key = ikey_1
508 CADJ STORE tstar = comlev1_exf_1, key = ikey_1
509 CADJ STORE tau = comlev1_exf_1, key = ikey_1
510 CADJ STORE cw = comlev1_exf_1, key = ikey_1
511 CADJ STORE sw = comlev1_exf_1, key = ikey_1
512 #endif
513
514 hs(i,j,bi,bj) = atmcp*tau*tstar/ustar
515 hl(i,j,bi,bj) = flamb*tau*qstar/ustar
516
517 evap(i,j,bi,bj) = tau*qstar/ustar
518
519 ustress(i,j,bi,bj) = tau*cw
520 vstress(i,j,bi,bj) = tau*sw
521 ce hflux(i,j,bi,bj) = atmcp*tau*tstar/ustar +
522 ce & flamb*tau*qstar/ustar
523 else
524 ustress(i,j,bi,bj) = 0. _d 0
525 vstress(i,j,bi,bj) = 0. _d 0
526 hflux (i,j,bi,bj) = 0. _d 0
527 hs(i,j,bi,bj) = 0. _d 0
528 hl(i,j,bi,bj) = 0. _d 0
529 endif
530
531 #else
532 #ifdef ALLOW_ATM_WIND
533 ustress(i,j,bi,bj) = atmrho*exf_BulkCdn(sh)*us*
534 & uwind(i,j,bi,bj)
535 vstress(i,j,bi,bj) = atmrho*exf_BulkCdn(sh)*us*
536 & vwind(i,j,bi,bj)
537 #endif /* ALLOW_ATM_WIND */
538 #endif /* ALLOW_ATM_TEMP */
539 enddo
540 enddo
541 enddo
542 enddo
543
544 c Add all contributions.
545 do bj = mybylo(mythid),mybyhi(mythid)
546 do bi = mybxlo(mythid),mybxhi(mythid)
547 do j = 1,sny
548 do i = 1,snx
549 c Net surface heat flux.
550 #ifdef ALLOW_ATM_TEMP
551 hfl = 0. _d 0
552 hfl = hfl - hs(i,j,bi,bj)
553 hfl = hfl - hl(i,j,bi,bj)
554 hfl = hfl + lwflux(i,j,bi,bj)
555 #ifndef ALLOW_KPP
556 hfl = hfl + swflux(i,j,bi,bj)
557 #endif /* ALLOW_KPP undef */
558 c Heat flux:
559 hflux(i,j,bi,bj) = hfl*maskc(i,j,1,bi,bj)
560 c Salt flux from Precipitation and Evaporation.
561 sflux(i,j,bi,bj) = precip(i,j,bi,bj) - evap(i,j,bi,bj)
562 #endif /* ALLOW_ATM_TEMP */
563
564 #else
565 hflux(i,j,bi,bj) = hflux(i,j,bi,bj)*maskc(i,j,1,bi,bj)
566 sflux(i,j,bi,bj) = sflux(i,j,bi,bj)*maskc(i,j,1,bi,bj)
567 #endif /* ALLOW_BULKFORMULAE */
568 enddo
569 enddo
570 enddo
571 enddo
572
573 c Update the tile edges.
574 _EXCH_XY_R8(hflux, mythid)
575 _EXCH_XY_R8(sflux, mythid)
576 _EXCH_XY_R8(ustress, mythid)
577 _EXCH_XY_R8(vstress, mythid)
578
579 #ifdef ALLOW_KPP
580 _EXCH_XY_R8(swflux, mythid)
581 #endif /* ALLOW_KPP */
582
583 end

  ViewVC Help
Powered by ViewVC 1.1.22