OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
FASCODE_routines.f90
Go to the documentation of this file.
2 
3  implicit none
4 
5 ! This is a rewrite / translation to Fortran 90 of a set of subroutines that do the forward
6 ! model calculations for CT and OD codes using UW-Madison coefficient files
7 ! -- Gala Wind 11.30.2011
8 
9 !c * PLOD/PFAAST subprograms for infrared transmittance
10 !C at 101-level AIRS/MODIS pressure coordinate
11 !c .... version of 18.03.03
12 
13 !contents:
14 
15 !c block data reference_atmosphere
16 !c subroutine calpir
17 !c subroutine conpir
18 !c subroutine gphite
19 !c subroutine taudoc
20 !c subroutine tauwtr
21 
22 !c *********************
23 #ifndef AIRBORNE
24 
25  integer, parameter :: nl = 101
26 
27  real, parameter :: pstd(nl) = (/0.0050, 0.0161, 0.0384, 0.0769, 0.1370, &
28  0.2244, 0.3454, 0.5064, 0.7140, 0.9753, 1.2972,&
29  1.6872, 2.1526, 2.7009, 3.3398, 4.0770, 4.9204,&
30  5.8776, 6.9567, 8.1655, 9.5119, 11.0038, 12.6492,&
31  14.4559, 16.4318, 18.5847, 20.9224, 23.4526, 26.1829,&
32  29.1210, 32.2744, 35.6505, 39.2566, 43.1001, 47.1882,&
33  51.5278, 56.1260, 60.9895, 66.1253, 71.5398, 77.2396,&
34  83.2310, 89.5204, 96.1138, 103.0172, 110.2366, 117.7775,&
35  125.6456, 133.8462, 142.3848, 151.2664, 160.4959, 170.0784,&
36  180.0183, 190.3203, 200.9887, 212.0277, 223.4415, 235.2338,&
37  247.4085, 259.9691, 272.9191, 286.2617, 300.0000, 314.1369,&
38  328.6753, 343.6176, 358.9665, 374.7241, 390.8926, 407.4738,&
39  424.4698, 441.8819, 459.7118, 477.9607, 496.6298, 515.7200,&
40  535.2322, 555.1669, 575.5248, 596.3062, 617.5112, 639.1398,&
41  661.1920, 683.6673, 706.5654, 729.8857, 753.6275, 777.7897,&
42  802.3714, 827.3713, 852.7880, 878.6201, 904.8659, 931.5236,&
43  958.5911, 986.0666, 1013.9476, 1042.2319, 1070.9170, 1100.0000/)
44 
45 
46  real, parameter :: tstd(nl) = (/190.19, 203.65, 215.30, 226.87, 237.83, &
47  247.50, 256.03, 263.48, 267.09, 270.37, 266.42, 261.56, 256.40, &
48  251.69, 247.32, 243.27, 239.56, 236.07, 232.76, 230.67, 228.71, &
49  227.35, 226.29, 225.28, 224.41, 223.61, 222.85, 222.12, 221.42, &
50  220.73, 220.07, 219.44, 218.82, 218.23, 217.65, 217.18, 216.91, &
51  216.70, 216.70, 216.70, 216.70, 216.70, 216.70, 216.70, 216.70, &
52  216.70, 216.70, 216.70, 216.70, 216.70, 216.70, 216.70, 216.71, &
53  216.71, 216.72, 216.81, 217.80, 218.77, 219.72, 220.66, 222.51, &
54  224.57, 226.59, 228.58, 230.61, 232.61, 234.57, 236.53, 238.48, &
55  240.40, 242.31, 244.21, 246.09, 247.94, 249.78, 251.62, 253.45, &
56  255.26, 257.04, 258.80, 260.55, 262.28, 264.02, 265.73, 267.42, &
57  269.09, 270.77, 272.43, 274.06, 275.70, 277.32, 278.92, 280.51, &
58  282.08, 283.64, 285.20, 286.74, 288.25, 289.75, 291.22, 292.68/)
59 
60  real, parameter :: wstd(nl) = (/ 0.001, 0.001, 0.002, 0.003, 0.003, &
61  0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, &
62  0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, &
63  0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, &
64  0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, &
65  0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, &
66  0.003, 0.003, 0.004, 0.004, 0.005, 0.005, 0.007, 0.009, &
67  0.011, 0.012, 0.014, 0.020, 0.025, 0.030, 0.035, 0.047, &
68  0.061, 0.075, 0.089, 0.126, 0.162, 0.197, 0.235, 0.273, &
69  0.310, 0.356, 0.410, 0.471, 0.535, 0.601, 0.684, 0.784, &
70  0.886, 0.987, 1.094, 1.225, 1.353, 1.519, 1.686, 1.852, &
71  2.036, 2.267, 2.496, 2.721, 2.947, 3.170, 3.391, 3.621, &
72  3.848, 4.084, 4.333, 4.579, 4.822, 5.061, 5.296, 5.528/)
73 
74  real, parameter :: ostd(nl) = (/0.47330,0.27695,0.28678,0.51816,0.83229, &
75  1.18466,1.69647,2.16633,3.00338,3.76287,4.75054,5.61330,6.33914, &
76  7.03675,7.50525,7.75612,7.81607,7.69626,7.56605,7.28440,7.01002, &
77  6.72722,6.44629,6.17714,5.92914,5.69481,5.47387,5.26813,5.01252, &
78  4.68941,4.35141,4.01425,3.68771,3.37116,3.06407,2.77294,2.50321, &
79  2.24098,1.98592,1.74840,1.54451,1.34582,1.17824,1.02513,0.89358, &
80  0.78844,0.69683,0.62654,0.55781,0.50380,0.45515,0.42037,0.38632, &
81  0.35297,0.32029,0.28832,0.25756,0.22739,0.19780,0.16877,0.14901, &
82  0.13190,0.11511,0.09861,0.08818,0.07793,0.06786,0.06146,0.05768, &
83  0.05396,0.05071,0.04803,0.04548,0.04301,0.04081,0.03983,0.03883, &
84  0.03783,0.03685,0.03588,0.03491,0.03395,0.03368,0.03349,0.03331, &
85  0.03313,0.03292,0.03271,0.03251,0.03190,0.03126,0.03062,0.02990, &
86  0.02918,0.02850,0.02785,0.02721,0.02658,0.02596,0.02579,0.02579/)
87 
88 
89  integer, parameter :: fnm = 101-1
90 
91 #else
92  integer, parameter :: fnm = 66-1
93 
94 #endif
95 
96  integer, parameter :: fncd = 8+1, fnco = 9+1, fncl = 2+1, fncs=11+1, fncc=4+1
97 
98 #ifdef AHI_INST
99  integer, parameter :: fnr = 10
100  real :: coefd(fncd,fnm,fnr),&
101  coefo(fnco,fnm,fnr), &
102  coefl(fncl,fnm,fnr),&
103  coefs(fncs,fnm,fnr), &
104  coefc(fncc,fnm,fnr)
105 
106 #endif
107 
108 #ifdef SEVIRI_INST
109  integer, parameter :: fnr = 8
110  real :: coefd(fncd,fnm,fnr),&
111  coefo(fnco,fnm,fnr), &
112  coefl(fncl,fnm,fnr),&
113  coefs(fncs,fnm,fnr), &
114  coefc(fncc,fnm,fnr)
115 
116 #endif
117 
118 #ifdef MAS_INST
119  integer, parameter :: fnr = 22
120  real :: coefd(fncd,fnm,fnr),&
121  coefo(fnco,fnm,fnr), &
122  coefl(fncl,fnm,fnr),&
123  coefs(fncs,fnm,fnr), &
124  coefc(fncc,fnm,fnr)
125 #endif
126 
127 #ifdef EMAS_INST
128  integer, parameter :: fnr = 13
129  real :: coefd(fncd,fnm,fnr),&
130  coefo(fnco,fnm,fnr), &
131  coefl(fncl,fnm,fnr),&
132  coefs(fncs,fnm,fnr), &
133  coefc(fncc,fnm,fnr)
134 #endif
135 
136  real :: pavg(fnm),tref(fnm),wref(fnm),oref(fnm)
138 
139 
140  integer, parameter :: fnxd = 8, fnxo=9, fnxw = 2 + 11, fnxc =4
141 
144 
145  character*6 cinit
146  integer :: init
147 
148 contains
149 
150  subroutine init_fascode
151 
152 #ifdef AIRBORNE
153  cinit = 'zz'
154 #else
155  cinit = 'zzzzzz'
156 #endif
157 
158  init = 0
159 
160  xdry = 0.
161  xozo = 0.
162  xwet = 0.
163  xcon = 0.
164 
165  xdry_2way = 0.
166  xozo_2way = 0.
167  xwet_2way = 0.
168  xcon_2way = 0.
169 
170 
171  end subroutine init_fascode
172 
173  real function secant (z)
174 
175  real, intent(in) :: z
176 
177  secant = 1./cos(0.01745329*z)
178 
179  end function secant
180 
181 
182  subroutine calpir(t_avg_ref, amt_wet_ref, amt_ozo_ref, &
183  t_avg, amt_wet, amt_ozo, &
184  p_avg, sec_theta, n_layers, &
185  n_dry_pred, n_wet_pred, n_ozo_pred, &
186  n_con_pred, &
187  pred_dry, pred_wet, pred_ozo, &
188  pred_con, do_init)
189 ! ... version of 18.03.03
190 
191 ! PURPOSE:
192 
193 ! Routine to calculate the predictors for the dry (temperature),
194 ! wet and ozone components of a fast transmittance model for a
195 ! scanning satellite based instrument.
196 
197 ! REFERENCES:
198 
199 ! AIRS FTC package science notes and software, S. Hannon and L. Strow,
200 ! Uni. of Maryland, Baltimore County (UMBC)
201 
202 ! CREATED:
203 
204 ! 19-Sep-1996 HMW
205 
206 ! ARGUMENTS:
207 
208 ! Input
209 ! -----------
210 ! t_avg_ref - REAL*4 reference layer average temperature array (K)
211 
212 ! amt_wet_ref - REAL*4 reference water vapour amount array (k.mol)/cm^2
213 
214 ! amt_ozo_ref - REAL*4 reference ozone amount array (k.mol)/cm^2
215 
216 ! t_avg - REAL*4 layer average temperature array (K)
217 
218 ! amt_wet - REAL*4 water vapour amount array (k.mol)/cm^2
219 
220 ! amt_ozo - REAL*4 ozone amount array (k.mol)/cm^2
221 
222 ! p_avg - REAL*4 layer average pressure array (mb)
223 
224 ! sec_theta - REAL*4 secant of the zenith angle array
225 
226 ! n_layers - INT*4 Number of atmospheric layers
227 
228 ! n_dry_pred - INT*4 number of dry (temperature) predictors
229 
230 ! n_wet_pred - INT*4 number of water vapour predictors
231 
232 ! n_ozo_pred - INT*4 number of ozone predictors
233 
234 ! n_con_pred - INT*4 number of water vapour continuum predictors
235 
236 ! Output
237 ! -----------
238 ! pred_dry - REAL*4 dry gas (temperature) predictor matrix
239 
240 ! pred_wet - REAL*4 water vapour predictor matrix
241 
242 ! pred_ozo - REAL*4 ozone predictor matrix
243 
244 ! pred_con - REAL*4 water vapour continuum predictor matrix
245 
246 ! COMMENTS:
247 
248 ! Levels or Layers?
249 ! -----------------
250 ! Profile data is input at a number of *LAYERS*.
251 
252 ! Layer Numbering pt. A
253 ! ---------------------
254 ! Layer 1 => Atmosphere between LEVELs 1 & 2
255 ! Layer 2 => Atmosphere between LEVELs 2 & 3
256 ! .
257 ! .
258 ! .
259 ! Layer L-1 => Atmosphere between LEVELs L-1 & L
260 
261 ! Layer Numbering pt. B
262 ! ---------------------
263 ! For the HIS instrument, Layer 1 is at the top of the atmosphere
264 ! and Layer L-1 is at the surface.
265 
266 ! Layer Numbering pt. C
267 ! ---------------------
268 ! In this routine the number of *LAYERS* is passed in the argument
269 ! list, _not_ the number of LEVELS. This was done to improve
270 ! the readability of this code, i.e. loop from 1->L(ayers)
271 ! rather than from 1->L(evels)-1.
272 
273 !=======================================================================
274 
275 !-----------------------------------------------------------------------
276 ! Turn off implicit type declaration
277 !-----------------------------------------------------------------------
278 
279  implicit none
280 
281 !------------------------------------------------------------------------
282 ! Arguments
283 !------------------------------------------------------------------------
284 
285 ! -- Input
286 
287  integer*4 :: n_layers, &
288  n_dry_pred, n_wet_pred, n_ozo_pred, n_con_pred
289 
290  real*4 :: t_avg_ref(*), amt_wet_ref(*), amt_ozo_ref(*),&
291  t_avg(*), amt_wet(*), amt_ozo(*), &
292  p_avg(*), sec_theta(*)
293 ! WDR in/output
294  integer :: do_init
295 
296 ! -- Output
297 
298  real*4 :: pred_dry(n_dry_pred, *), &
299  pred_wet(n_wet_pred, *),&
300  pred_ozo(n_ozo_pred, *),&
301  pred_con(n_con_pred, *)
302 
303 !------------------------------------------------------------------------
304 ! Local variables
305 !------------------------------------------------------------------------
306 
307 ! -- Parameters
308 #ifdef AIRBORNE
309  integer, parameter :: max_layers = 65
310 #else
311  integer, parameter :: max_layers = 100
312 #endif
313  integer, parameter :: max_dry_pred = 8, &
314  max_wet_pred = 13,&
315  max_ozo_pred = 9,&
316  max_con_pred = 4
317 
318 ! -- Scalars
319 
320  integer*4 :: l
321 
322 ! -- Arrays
323 
324 ! ....Pressure
325  real*4 :: p_dp(max_layers),&
326  p_norm(max_layers)
327 
328 ! ....Temperature
329  real*4 :: delta_t(max_layers), &
330  t_ratio(max_layers), &
331  pw_t_ratio(max_layers) ! Pressure weighted
332 
333 ! ....Water vapour
334  real*4 :: wet_ratio(max_layers),&
335  pw_wet(max_layers), & ! Pressure weighted
336  pw_wet_ref(max_layers), & ! Pressure weighted
337  pw_wet_ratio(max_layers) ! Pressure weighted
338 
339 ! ....Ozone
340  real*4 :: ozo_ratio(max_layers), &
341  pw_ozo_ratio(max_layers), & ! Pressure weighted
342  pow_t_ratio(max_layers) ! Pressure/ozone weighted
343 
344 !************************************************************************
345 ! ** Executable code **
346 !************************************************************************
347 
348 !------------------------------------------------------------------------
349 ! -- Check that n_layers is o.k. --
350 !------------------------------------------------------------------------
351 
352 ! WDR to avoid init parts that are the same
353  if( do_init == 1 ) then
354  if( n_layers > max_layers )then
355  write(*,'(/10x,''*** calpir : n_layers > max_layers'')')
356  stop
357  end if
358 
359 !------------------------------------------------------------------------
360 ! -- Check that numbers of predictors is consistent --
361 !------------------------------------------------------------------------
362 
363 ! ---------------------------------
364 ! # of dry (temperature) predictors
365 ! ---------------------------------
366 
367  if( n_dry_pred /= max_dry_pred )then
368  write(*,'(/10x,''*** calpir : invalid n_dry_pred'')')
369  stop
370  end if
371 
372 ! ----------------------------
373 ! # of water vapour predictors
374 ! ----------------------------
375 
376  if( n_wet_pred /= max_wet_pred )then
377  write(*,'(/10x,''*** calpir : invalid n_wet_pred'')')
378  stop
379  end if
380 
381 ! ---------------------
382 ! # of ozone predictors
383 ! ---------------------
384 
385  if( n_ozo_pred /= max_ozo_pred )then
386  write(*,'(/10x,''*** calpir : invalid n_ozo_pred'')')
387  stop
388  end if
389 
390 ! --------------------------------------
391 ! # of water vapour continuum predictors
392 ! --------------------------------------
393 
394  if( n_con_pred /= max_con_pred )then
395  write(*,'(/10x,''*** calpir : invalid n_con_pred'')')
396  stop
397  end if
398 
399 !------------------------------------------------------------------------
400 ! -- Calculate ratios, offsets, etc, for top layer --
401 !------------------------------------------------------------------------
402 
403 ! ------------------
404 ! Pressure variables
405 ! ------------------
406 
407  p_dp(1) = p_avg(1) * ( p_avg(2) - p_avg(1) )
408  p_norm(1) = 0.0
409 
410 ! ---------------------
411 ! Temperature variables
412 ! ---------------------
413 
414  delta_t(1) = t_avg(1) - t_avg_ref(1)
415  t_ratio(1) = t_avg(1) / t_avg_ref(1)
416  pw_t_ratio(1) = 0.0
417 
418 ! ----------------
419 ! Amount variables
420 ! ----------------
421 
422 ! ....Water vapour
423 
424  wet_ratio(1) = amt_wet(1) / amt_wet_ref(1)
425  pw_wet(1) = p_dp(1) * amt_wet(1)
426  pw_wet_ref(1) = p_dp(1) * amt_wet_ref(1)
427  pw_wet_ratio(1) = wet_ratio(1)
428 
429 ! ....Ozone
430 
431  ozo_ratio(1) = amt_ozo(1) / amt_ozo_ref(1)
432  pw_ozo_ratio(1) = 0.0
433  pow_t_ratio(1) = 0.0
434 
435 !------------------------------------------------------------------------
436 ! -- Calculate ratios, offsets, etc, for all layers --
437 !------------------------------------------------------------------------
438 
439  do l = 2, n_layers
440 
441 ! ------------------
442 ! Pressure variables
443 ! ------------------
444 
445  p_dp(l) = p_avg(l) * ( p_avg(l) - p_avg(l-1) )
446  p_norm(l) = p_norm(l-1) + p_dp(l)
447 
448 ! ---------------------
449 ! Temperature variables
450 ! ---------------------
451 
452  delta_t(l) = t_avg(l) - t_avg_ref(l)
453  t_ratio(l) = t_avg(l) / t_avg_ref(l)
454  pw_t_ratio(l) = pw_t_ratio(l-1) + ( p_dp(l) * t_ratio(l-1) )
455 
456 ! ----------------
457 ! Amount variables
458 ! ----------------
459 
460 ! ..Water vapour
461 
462  wet_ratio(l) = amt_wet(l) / amt_wet_ref(l)
463  pw_wet(l) = pw_wet(l-1) + ( p_dp(l) * amt_wet(l) )
464  pw_wet_ref(l) = pw_wet_ref(l-1) + ( p_dp(l) * amt_wet_ref(l) )
465 
466 ! ..Ozone
467 
468  ozo_ratio(l) = amt_ozo(l) / amt_ozo_ref(l)
469  pw_ozo_ratio(l) = pw_ozo_ratio(l-1) + &
470  ( p_dp(l) * ozo_ratio(l-1) )
471  pow_t_ratio(l) = pow_t_ratio(l-1) + &
472  ( p_dp(l) * ozo_ratio(l-1) * delta_t(l-1) )
473 
474  end do
475 
476 !------------------------------------------------------------------------
477 ! -- Scale the pressure dependent variables --
478 !------------------------------------------------------------------------
479 
480  do l = 2, n_layers
481 
482  pw_t_ratio(l) = pw_t_ratio(l) / p_norm(l)
483  pw_wet_ratio(l) = pw_wet(l) / pw_wet_ref(l)
484  pw_ozo_ratio(l) = pw_ozo_ratio(l) / p_norm(l)
485  pow_t_ratio(l) = pow_t_ratio(l) / p_norm(l)
486 
487  end do
488 
489  ! WDR end init portion
490  do_init = 0
491  end if
492 !------------------------------------------------------------------------
493 ! -- Load up predictor arrays --
494 !------------------------------------------------------------------------
495 
496  do l = 1, n_layers
497 
498 ! ----------------------
499 ! Temperature predictors
500 ! ----------------------
501 
502  pred_dry(1,l) = sec_theta(l)
503  pred_dry(2,l) = sec_theta(l) * sec_theta(l)
504  pred_dry(3,l) = sec_theta(l) * t_ratio(l)
505  pred_dry(4,l) = pred_dry(3,l) * t_ratio(l)
506  pred_dry(5,l) = t_ratio(l)
507  pred_dry(6,l) = t_ratio(l) * t_ratio(l)
508  pred_dry(7,l) = sec_theta(l) * pw_t_ratio(l)
509  pred_dry(8,l) = pred_dry(7,l) / t_ratio(l)
510 
511 ! -----------------------
512 ! Water vapour predictors
513 ! -----------------------
514 
515  pred_wet(1,l) = sec_theta(l) * wet_ratio(l)
516  pred_wet(2,l) = sqrt( pred_wet(1,l) )
517  pred_wet(3,l) = pred_wet(1,l) * delta_t(l)
518  pred_wet(4,l) = pred_wet(1,l) * pred_wet(1,l)
519  pred_wet(5,l) = abs( delta_t(l) ) * delta_t(l) * pred_wet(1,l)
520  pred_wet(6,l) = pred_wet(1,l) * pred_wet(4,l)
521  pred_wet(7,l) = sec_theta(l) * pw_wet_ratio(l)
522  pred_wet(8,l) = pred_wet(2,l) * delta_t(l)
523  pred_wet(9,l) = sqrt( pred_wet(2,l) )
524  pred_wet(10,l) = pred_wet(7,l) * pred_wet(7,l)
525  pred_wet(11,l) = sqrt( pred_wet(7,l) )
526  pred_wet(12,l) = pred_wet(1,l)
527 ! +++ old
528 ! pred_wet(13,l) = pred_wet(2,l)
529 ! +++ new
530  pred_wet(13,l) = pred_wet(1,l) / pred_wet(10,l)
531 
532 ! ----------------
533 ! Ozone predictors
534 ! ----------------
535 
536  pred_ozo(1,l) = sec_theta(l) * ozo_ratio(l)
537  pred_ozo(2,l) = sqrt( pred_ozo(1,l) )
538  pred_ozo(3,l) = pred_ozo(1,l) * delta_t(l)
539  pred_ozo(4,l) = pred_ozo(1,l) * pred_ozo(1,l)
540  pred_ozo(5,l) = pred_ozo(2,l) * delta_t(l)
541  pred_ozo(6,l) = sec_theta(l) * pw_ozo_ratio(l)
542  pred_ozo(7,l) = sqrt( pred_ozo(6,l) ) * pred_ozo(1,l)
543  pred_ozo(8,l) = pred_ozo(1,l) * pred_wet(1,l)
544  pred_ozo(9,l) = sec_theta(l) * pow_t_ratio(l) * pred_ozo(1,l)
545 
546 ! ---------------------------------
547 ! Water vapour continuum predictors
548 ! ---------------------------------
549 
550  pred_con(1,l) = sec_theta(l) * wet_ratio(l) / ( t_ratio(l) * t_ratio(l) )
551  pred_con(2,l) = pred_con(1,l) * pred_con(1,l) / sec_theta(l)
552  pred_con(3,l) = sec_theta(l) * wet_ratio(l) / t_ratio(l)
553  pred_con(4,l) = pred_con(3,l) * wet_ratio(l)
554 
555  end do
556 
557  end subroutine calpir
558 
559 
560  subroutine conpir( p, t, w, o, n_levels, i_dir, &
561  p_avg, t_avg, w_amt, o_amt)
562 ! ... version of 19.09.96
563 
564 ! PURPOSE:
565 
566 ! Function to convert atmospheric water vapour (g/kg) and ozone (ppmv)
567 ! profiles specified at n_levels layer BOUNDARIES to n_levels-1
568 ! integrated layer amounts of units (k.moles)/cm^2. The average
569 ! LAYER pressure and temperature are also returned.
570 
571 ! REFERENCES:
572 
573 ! AIRS LAYERS package science notes, S. Hannon and L. Strow, Uni. of
574 ! Maryland, Baltimore County (UMBC)
575 
576 ! CREATED:
577 
578 ! 19-Sep-1996 HMW
579 
580 ! ARGUMENTS:
581 
582 ! Input
583 ! --------
584 ! p - REAL*4 pressure array (mb)
585 
586 ! t - REAL*4 temperature profile array (K)
587 
588 ! w - REAL*4 water vapour profile array (g/kg)
589 
590 ! o - REAL*4 ozone profile array (ppmv)
591 
592 ! n_levels - INT*4 number of elements used in passed arrays
593 
594 ! i_dir - INT*4 direction of increasing layer number
595 
596 ! i_dir = +1, Level(1) == p(top) } satellite/AC
597 ! Level(n_levels) == p(sfc) } case
598 
599 ! i_dir = -1, Level(1) == p(sfc) } ground-based
600 ! Level(n_levels) == p(top) } case
601 
602 ! Output
603 ! --------
604 ! p_avg - REAL*4 average LAYER pressure array (mb)
605 
606 ! t_avg - REAL*4 average LAYER temperature (K)
607 
608 ! w_amt - REAL*4 integrated LAYER water vapour amount array (k.moles)/cm^2
609 
610 ! o_amt - REAL*4 integrated LAYER ozone amount array (k.moles)/cm^2
611 
612 ! ROUTINES:
613 
614 ! Subroutines:
615 ! ------------
616 ! gphite - calculates geopotential height given profile data.
617 
618 ! Functions:
619 ! ----------
620 ! NONE
621 
622 ! COMMENTS:
623 
624 ! Levels or Layers?
625 ! -----------------
626 ! Profile data is input at a number of *LEVELS*. Number densitites
627 ! are calculated for *LAYERS* that are bounded by these levels.
628 ! So, for L levels there are L-1 layers.
629 
630 ! Layer Numbering
631 ! ---------------
632 ! Layer 1 => Atmosphere between LEVELs 1 & 2
633 ! Layer 2 => Atmosphere between LEVELs 2 & 3
634 ! .
635 ! .
636 ! .
637 ! Layer L-1 => Atmosphere between LEVELs L-1 & L
638 
639 !=======================================================================
640 
641 !-----------------------------------------------------------------------
642 ! -- Prevent implicit typing of variables --
643 !-----------------------------------------------------------------------
644 
645  implicit none
646 
647 !-----------------------------------------------------------------------
648 ! -- Arguments --
649 !-----------------------------------------------------------------------
650 
651 ! -- Arrays
652 
653  real*4 :: p(*), t(*), w(*), o(*), &
654  p_avg(*), t_avg(*), w_amt(*), o_amt(*)
655 
656 ! -- Scalars
657 
658  integer*4 :: n_levels, i_dir
659 
660 !-----------------------------------------------------------------------
661 ! -- Local variables --
662 !-----------------------------------------------------------------------
663 
664 ! -- Parameters
665 
666 #ifdef AIRBORNE
667  integer*4, parameter :: max_levels = 66 ! Maximum number of layers
668 #else
669  integer*4, parameter :: max_levels = 101 ! Maximum number of layers
670 #endif
671  real, parameter :: r_equator = 6.378388e+06,& ! Earth radius at equator
672  r_polar = 6.356911e+06, & ! Earth radius at pole
673  r_avg = 0.5*(r_equator+r_polar)
674 
675  real, parameter :: g_sfc = 9.80665 ! Gravity at surface
676 !
677  real*4, parameter :: rho_ref = 1.2027e-12 ! Reference air "density"
678 
679  real, parameter :: mw_dryair = 28.97, & ! Molec. wgt. of dry air (g/mol)
680  mw_h2o = 18.0152, & ! Molec. wgt. of water
681  mw_o3 = 47.9982 ! Molec. wgt. of ozone
682 
683  real, parameter :: R_gas = 8.3143, & ! Ideal gas constant (J/mole/K)
684  r_air = 0.9975*r_gas ! Gas constant for air (worst case)
685 
686 ! -- Scalars
687 
688  integer*4 l, l_start, l_end, l_indx
689 
690  real*4 rho1, rho2, p1, p2, w1, w2, o1, o2, z1, z2, &
691  c_avg, g_avg, z_avg, w_avg, o_avg, &
692  dz, dp, r_hgt, a, b
693 
694 ! -- Arrays
695 
696  real*4 :: z(max_levels), & ! Pressure heights (m)
697  g(max_levels), & ! Acc. due to gravity (m/s/s)
698  mw_air(max_levels), & ! Molec. wgt. of air (g/mol)
699  rho_air(max_levels), & ! air mass density (kg.mol)/m^3
700  c(max_levels), & ! (kg.mol.K)/(N.m)
701  w_ppmv(max_levels) ! h2o LEVEL amount (ppmv)
702 
703 !***********************************************************************
704 ! ** Executable code **
705 !***********************************************************************
706 
707 !-----------------------------------------------------------------------
708 ! -- Calculate initial values of pressure heights --
709 !-----------------------------------------------------------------------
710 
711  call gphite( p, t, w, 0.0, n_levels, i_dir, z)
712 
713 !-----------------------------------------------------------------------
714 ! -- Set loop bounds for direction sensitive calculations --
715 ! -- so loop iterates from surface to the top --
716 !-----------------------------------------------------------------------
717 
718  if( i_dir > 0 )then
719 
720 ! --------------------
721 ! Data stored top down
722 ! --------------------
723 
724  l_start = n_levels
725  l_end = 1
726 
727  else
728 
729 ! ---------------------
730 ! Data stored bottom up
731 ! ---------------------
732 
733  l_start = 1
734  l_end = n_levels
735 
736  end if
737 
738 !-----------------------------------------------------------------------
739 ! -- Air molecular mass and density, and gravity --
740 ! -- as a function of LEVEL --
741 !-----------------------------------------------------------------------
742 
743 ! -----------------------
744 ! Loop from bottom to top
745 ! -----------------------
746 
747  do l = l_start, l_end, -1*i_dir
748 
749 ! ---------------------------------
750 ! Convert water vapour g/kg -> ppmv
751 ! ---------------------------------
752 
753  w_ppmv(l) = 1.0e+03 * w(l) * mw_dryair / mw_h2o
754 
755 ! -----------------------------------------
756 ! Calculate molecular weight of air (g/mol)
757 ! ----------------------------------------
758 
759  mw_air(l) = ( ( 1.0 - (w_ppmv(l)/1.0e+6) ) * mw_dryair ) + &
760  ( ( w_ppmv(l)/1.0e+06 ) * mw_h2o )
761 
762 ! ----------------
763 ! Air mass density
764 ! ----------------
765 
766  c(l) = 0.001 * mw_air(l) / r_air ! 0.001 factor for g -> kg
767  rho_air(l) = c(l) * p(l) / t(l)
768 
769 ! -------
770 ! Gravity
771 ! -------
772 
773  r_hgt = r_avg + z(l) ! m
774  g(l) = g_sfc - & ! m/s^2
775  g_sfc*( 1.0 - ( (r_avg*r_avg)/(r_hgt*r_hgt) ) )
776 
777  end do
778 
779 !-----------------------------------------------------------------------
780 ! -- LAYER quantities --
781 !-----------------------------------------------------------------------
782 
783 ! -----------------------
784 ! Loop from bottom to top
785 ! -----------------------
786 
787  do l = l_start, l_end+i_dir, -1*i_dir
788 
789 ! -------------------------------------------------------
790 ! Determine output array index. This is done so that the
791 ! output data is always ordered from 1 -> L-1 regardless
792 ! of the orientation of the input data. This is true by
793 ! default only for the bottom-up case. For the top down
794 ! case no correction would give output layers from 2 -> L
795 ! -------------------------------------------------------
796 
797  if( i_dir > 0 )then
798 
799  l_indx = l - 1
800 
801  else
802 
803  l_indx = l
804 
805  end if
806 
807 ! ---------------------------------------
808 ! Assign current layer boundary densities
809 ! ---------------------------------------
810 
811  rho1 = rho_air(l)
812  rho2 = rho_air(l-i_dir)
813 
814 ! ---------
815 ! Average c
816 ! ---------
817 
818  c_avg = ( (rho1*c(l)) + (rho2*c(l-i_dir)) ) / ( rho1 + rho2 )
819 
820 ! ---------
821 ! Average t
822 ! ---------
823 
824  t_avg(l_indx) = ( (rho1*t(l)) + (rho2*t(l-i_dir)) ) / ( rho1 + rho2 )
825 
826 ! ---------
827 ! Average p
828 ! ---------
829 
830  p1 = p(l)
831  p2 = p(l-i_dir)
832 
833  z1 = z(l)
834  z2 = z(l-i_dir)
835 
836  dp = p2 - p1
837 
838  a = log(p2/p1) / (z2-z1)
839  b = p1 / exp(a*z1)
840 
841  p_avg(l_indx) = dp / log(p2/p1)
842 
843 ! ------------------------------------------------
844 ! LAYER thickness (rather long-winded as it is not
845 ! assumed the layers are thin) in m. Includes
846 ! correction for altitude/gravity.
847 ! ------------------------------------------------
848 
849 ! ...Initial values
850  g_avg = g(l)
851  dz = -1.0 * dp * t_avg(l_indx) / ( g_avg*c_avg*p_avg(l_indx) )
852 
853 ! ...Calculate z_avg
854  z_avg = z(l) + ( 0.5*dz )
855 
856 ! ...Calculate new g_avg
857  r_hgt = r_avg + z_avg
858  g_avg = g_sfc - g_sfc*( 1.0 - ( (r_avg*r_avg)/(r_hgt*r_hgt) ) )
859 
860 ! ...Calculate new dz
861  dz = -1.0 * dp * t_avg(l_indx) / ( g_avg*c_avg*p_avg(l_indx) )
862 
863 ! ----------------------------------------
864 ! Calculate LAYER amounts for water vapour
865 ! ----------------------------------------
866 
867  w1 = w_ppmv(l)
868  w2 = w_ppmv(l-i_dir)
869 
870  w_avg = ( (rho1*w1) + (rho2*w2) ) / ( rho1+rho2 )
871 
872  w_amt(l_indx) = rho_ref * w_avg * dz * p_avg(l_indx) / t_avg(l_indx)
873 
874 ! ---------------------------------
875 ! Calculate LAYER amounts for ozone
876 ! ---------------------------------
877 
878  o1 = o(l)
879  o2 = o(l-i_dir)
880 
881  o_avg = ( (rho1*o1) + (rho2*o2) ) / ( rho1+rho2 )
882 
883  o_amt(l_indx) = rho_ref * o_avg * dz * p_avg(l_indx) / t_avg(l_indx)
884 
885  end do
886 
887  end subroutine conpir
888 
889 
890 
891  subroutine gphite( p, t, w, z_sfc, n_levels, i_dir, z)
892 ! .... version of 18.05.00
893 
894 ! PURPOSE:
895 
896 ! Routine to compute geopotential height given the atmospheric state.
897 ! Includes virtual temperature adjustment.
898 
899 ! CREATED:
900 
901 ! 19-Sep-1996 Received from Hal Woolf, recoded by Paul van Delst
902 ! 18-May-2000 Logic error related to z_sfc corrected by Hal Woolf
903 
904 ! ARGUMENTS:
905 
906 ! Input
907 ! --------
908 ! p - REAL*4 pressure array (mb)
909 
910 ! t - REAL*4 temperature profile array (K)
911 
912 ! w - REAL*4 water vapour profile array (g/kg)
913 
914 ! z_sfc - REAL*4 surface height (m). 0.0 if not known.
915 
916 ! n_levels - INT*4 number of elements used in passed arrays
917 
918 ! i_dir - INT*4 direction of increasing layer number
919 
920 ! i_dir = +1, Level(1) == p(top) } satellite/AC
921 ! Level(n_levels) == p(sfc) } case
922 
923 ! i_dir = -1, Level(1) == p(sfc) } ground-based
924 ! Level(n_levels) == p(top) } case
925 
926 ! Output
927 ! --------
928 ! z - REAL*4 pressure level height array (m)
929 
930 ! COMMENTS:
931 
932 ! Dimension of height array may not not be the same as that of the
933 ! input profile data.
934 
935 !=======================================================================
936 
937 !-----------------------------------------------------------------------
938 ! -- Prevent implicit typing of variables --
939 !-----------------------------------------------------------------------
940 
941  implicit none
942 
943 !-----------------------------------------------------------------------
944 ! -- Arguments --
945 !-----------------------------------------------------------------------
946 
947 ! -- Arrays
948 
949  real*4 :: p(*), t(*), w(*), z(*)
950 
951 ! -- Scalars
952 
953  integer*4 :: n_levels, i_dir
954 
955  real*4 :: z_sfc
956 
957 !-----------------------------------------------------------------------
958 ! -- Local variables --
959 !-----------------------------------------------------------------------
960 
961 ! -- Parameters
962 
963  real*4, parameter :: rog = 29.2898, &
964  fac = 0.5 * rog
965 
966 ! -- Scalars
967 
968  integer*4 :: i_start, i_end, l
969 
970  real*4 :: v_lower, v_upper, algp_lower, algp_upper, hgt
971 
972 !***********************************************************************
973 ! ** Executable code **
974 !***********************************************************************
975 
976 !-----------------------------------------------------------------------
977 ! -- Calculate virtual temperature adjustment and exponential --
978 ! -- pressure height for level above surface. Also set integration --
979 ! -- loop bounds --
980 !-----------------------------------------------------------------------
981 
982  if( i_dir > 0 )then
983 
984 ! --------------------
985 ! Data stored top down
986 ! --------------------
987 
988  v_lower = t(n_levels) * ( 1.0 + ( 0.00061 * w(n_levels) ) )
989 
990  algp_lower = alog( p(n_levels) )
991 
992  i_start = n_levels-1
993  i_end = 1
994 
995  else
996 
997 ! ---------------------
998 ! Data stored bottom up
999 ! ---------------------
1000 
1001  v_lower = t(1) * ( 1.0 + ( 0.00061 * w(1) ) )
1002 
1003  algp_lower = alog( p(1) )
1004 
1005  i_start = 2
1006  i_end = n_levels
1007 
1008  end if
1009 
1010 !-----------------------------------------------------------------------
1011 ! -- Assign surface height --
1012 !-----------------------------------------------------------------------
1013 
1014  hgt = z_sfc
1015 
1016 ! .. Following added 18 May 2000 ... previously, z(n_levels) for downward
1017 ! (usual) case was not defined!
1018 
1019  if(i_dir.gt.0) then
1020  z(n_levels) = z_sfc
1021  else
1022  z(1) = z_sfc
1023  endif
1024 
1025 ! .. End of addition
1026 
1027 !-----------------------------------------------------------------------
1028 ! -- Loop over layers always from sfc -> top --
1029 !-----------------------------------------------------------------------
1030 
1031  do l = i_start, i_end, -1*i_dir
1032 
1033 ! ----------------------------------------------------
1034 ! Apply virtual temperature adjustment for upper level
1035 ! ----------------------------------------------------
1036 
1037  v_upper = t(l)
1038  if( p(l) >= 300.0 ) v_upper = v_upper * ( 1.0 + ( 0.00061 * w(l) ) )
1039 
1040 ! -----------------------------------------------------
1041 ! Calculate exponential pressure height for upper layer
1042 ! -----------------------------------------------------
1043 
1044  algp_upper = alog( p(l) )
1045 
1046 ! ----------------
1047 ! Calculate height
1048 ! ----------------
1049 
1050  hgt = hgt + ( fac*(v_upper+v_lower)*(algp_lower-algp_upper) )
1051 
1052 ! -------------------------------
1053 ! Overwrite values for next layer
1054 ! -------------------------------
1055 
1056  v_lower = v_upper
1057  algp_lower = algp_upper
1058 
1059 ! ---------------------------------------------
1060 ! Store heights in same direction as other data
1061 ! ---------------------------------------------
1062 
1063  z(l) = hgt
1064 
1065  end do
1066 
1067 
1068  end subroutine gphite
1069 
1070 
1071  subroutine taudoc(nc,nx,ny,cc,xx,tau)
1072 ! * Strow-Woolf model ... for dry, ozo(ne), and wco (water-vapor continuum)
1073 ! .... version of 05.09.02
1074  integer, intent(in) :: nc, ny, nx
1075  real, intent(in) :: cc(:,:), xx(:,:)
1076  real, intent(inout) :: tau(*)
1077 
1078 ! cc(11,100)
1079 ! dimension cc(nc,ny),xx(nx,ny),tau(*)
1080 
1081  real, parameter :: trap = -999.99
1082 
1083  integer :: last, j, i
1084  real :: taulyr, taulev, yy
1085 
1086  last=ny
1087  taulyr=1.
1088  taulev=1.
1089 
1090  tau(1)=taulev
1091 
1092  do j=1,ny
1093 
1094  if (taulev == 0.) then
1095  tau(j+1) = taulev
1096  exit
1097  endif
1098 
1099  if(j > last) then
1100  taulev=taulev*taulyr
1101  tau(j+1)=taulev
1102  exit
1103  endif
1104 
1105  yy=cc(nc,j)
1106 
1107  if(yy == trap) then
1108 
1109  last=j
1110  taulev=taulev*taulyr
1111  tau(j+1)=taulev
1112  exit
1113 
1114  endif
1115 
1116  do i=1,nx
1117  yy=yy+cc(i,j)*xx(i,j)
1118  enddo
1119 
1120  yy=amax1(yy,0.)
1121  if(yy > 0.) taulyr=exp(-yy)
1122 
1123  taulev=taulev*taulyr
1124  tau(j+1)=taulev
1125 
1126  end do
1127 
1128  end subroutine taudoc
1129 
1130 
1131  subroutine taudry(nc,nx,ny,cc,xx,tau)
1132 ! * Strow-Woolf model ... for dry, ozo(ne), and wco (water-vapor continuum)
1133 ! .... version of 05.09.02
1134  integer, intent(in) :: nc, ny, nx
1135  real, intent(in) :: cc(:,:), xx(:,:)
1136  real, intent(inout) :: tau(:)
1137 
1138 ! cc(11,100)
1139 ! dimension cc(nc,ny),xx(nx,ny),tau(*)
1140 
1141  real, parameter :: trap = -999.99
1142 
1143  integer :: j, i
1144  real :: taulyr, taulev, yy
1145 
1146  taulyr=1.
1147  taulev=1.
1148  tau(1)=taulev
1149 
1150  do j=1,ny
1151 
1152  if (taulev == 0.) then
1153  tau(j+1) = taulev
1154  exit
1155  endif
1156 
1157  yy=cc(nc,j)
1158 
1159  if(yy == trap) then
1160 
1161  taulev=0.
1162  tau(j+1)=taulev
1163  exit
1164 
1165  endif
1166 
1167  do i=1,nx
1168  yy=yy+cc(i,j)*xx(i,j)
1169  enddo
1170 
1171  yy=amax1(yy,0.)
1172  if(yy > 0.) taulyr=exp(-yy)
1173 
1174  taulev=taulev*taulyr
1175  tau(j+1)=taulev
1176 
1177  end do
1178 
1179  end subroutine taudry
1180 
1181 
1182 
1183 
1184  subroutine tauwtr(ncs,ncl,nxs,nxl,nxw,ny,ccs,ccl,xx,tau)
1185 ! * Strow-Woolf model ... for 'wet' (water-vapor other than continuum)
1186 ! .... version of 05.09.02
1187 
1188  integer, intent(in) :: ncs, ncl, nxs, nxl, nxw, ny
1189  real, intent(in) :: ccs(:,:), ccl(:,:), xx(:,:)
1190  real, intent(inout) :: tau(:)
1191 
1192 ! dimension ccs(ncs,ny),ccl(ncl,ny),xx(nxw,ny),tau(*)
1193 
1194  real :: odsum, taulyr, taulev, yy
1195  integer :: j, i
1196 
1197  odsum=0.
1198  taulyr=1.
1199  taulev=1.
1200  tau(1)=taulev
1201 
1202  do j=1,ny
1203  if(odsum < 5.) then
1204  yy=ccs(ncs,j)
1205  do i=1,nxs
1206  yy=yy+ccs(i,j)*xx(i,j)
1207  enddo
1208  else
1209  yy=ccl(ncl,j)
1210  do i=1,nxl
1211  yy=yy+ccl(i,j)*xx(i+11,j)
1212  enddo
1213  endif
1214  yy=amax1(yy,0.)
1215  odsum=odsum+yy
1216  if(yy > 0.) taulyr=exp(-yy)
1217  taulev=taulev*taulyr
1218  tau(j+1)=taulev
1219 
1220  end do
1221 
1222  end subroutine tauwtr
1223 
1224 
1225 
1226 
1227 
1228 
1229 
1230 end module fascode_routines
1231 
integer, parameter fnxo
real, dimension(fnm) oamt
real, dimension(fnxw, fnm) xwet_2way
real, dimension(nl), parameter wstd
integer, parameter fnxw
integer, parameter fnr
real, dimension(fnm) tref
real, dimension(nl), parameter ostd
real, dimension(fnxd, fnm) xdry
real, dimension(fnm) wamt
real, dimension(fncd, fnm, fnr) coefd
real, dimension(nl), parameter pstd
integer, parameter fncd
subroutine tauwtr(ncs, ncl, nxs, nxl, nxw, ny, ccs, ccl, xx, tau)
integer, parameter fncs
subroutine conpir(p, t, w, o, n_levels, i_dir, p_avg, t_avg, w_amt, o_amt)
subroutine taudoc(nc, nx, ny, cc, xx, tau)
#define real
Definition: DbAlgOcean.cpp:26
real, dimension(fnxc, fnm) xcon
real, dimension(fncs, fnm, fnr) coefs
#define fac
real, dimension(fnm) secz_2way
integer, parameter fnxd
real, dimension(fnm) pavg
real, dimension(fnm) wref
real, dimension(fnxo, fnm) xozo_2way
integer, parameter fnco
subroutine gphite(p, t, w, z_sfc, n_levels, i_dir, z)
real, dimension(fnxw, fnm) xwet
subroutine calpir(t_avg_ref, amt_wet_ref, amt_ozo_ref, t_avg, amt_wet, amt_ozo, p_avg, sec_theta, n_layers, n_dry_pred, n_wet_pred, n_ozo_pred, n_con_pred, pred_dry, pred_wet, pred_ozo, pred_con, do_init)
real, dimension(fncc, fnm, fnr) coefc
real, dimension(fnm) secz
integer, parameter fncl
integer, parameter fnm
subroutine taudry(nc, nx, ny, cc, xx, tau)
real, dimension(fnco, fnm, fnr) coefo
real, dimension(fnxc, fnm) xcon_2way
integer, parameter fnxc
real, dimension(fnm) tavg
real, dimension(nl), parameter tstd
real function secant(z)
#define abs(a)
Definition: misc.h:90
real, dimension(fncl, fnm, fnr) coefl
real, dimension(fnxd, fnm) xdry_2way
real, dimension(fnm) oref
integer, parameter fncc
real, dimension(fnxo, fnm) xozo