Newer
Older
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
c
c subroutines and functions
c
c blas saxpy,sscal,isamax
c
c internal variables
c
real t
integer isamax,j,k,kp1,l,nm1
c
c
c gaussian elimination with partial pivoting
c
info = 0
nm1 = n - 1
if (nm1 .lt. 1) go to 70
do 60 k = 1, nm1
kp1 = k + 1
c
c find l = pivot index
c
l = isamax(n-k+1,a(k,k),1) + k - 1
ipvt(k) = l
c
c zero pivot implies this column already triangularized
c
if (a(l,k) .eq. 0.0e0) go to 40
c
c interchange if necessary
c
if (l .eq. k) go to 10
t = a(l,k)
a(l,k) = a(k,k)
a(k,k) = t
10 continue
c
c compute multipliers
c
t = -1.0e0/a(k,k)
call sscal(n-k,t,a(k+1,k),1)
c
c row elimination with column indexing
c
do 30 j = kp1, n
t = a(l,j)
if (l .eq. k) go to 20
a(l,j) = a(k,j)
a(k,j) = t
20 continue
call saxpy(n-k,t,a(k+1,k),1,a(k+1,j),1)
30 continue
go to 50
40 continue
info = k
50 continue
60 continue
70 continue
ipvt(n) = n
if (a(n,n) .eq. 0.0e0) info = n
return
end
subroutine sgbfa(abd,lda,n,ml,mu,ipvt,info)
integer lda,n,ml,mu,ipvt(1),info
real abd(lda,1)
c
c sgbfa factors a real band matrix by elimination.
c
c sgbfa is usually called by sgbco, but it can be called
c directly with a saving in time if rcond is not needed.
c
c on entry
c
c abd real(lda, n)
c contains the matrix in band storage. the columns
c of the matrix are stored in the columns of abd and
c the diagonals of the matrix are stored in rows
c ml+1 through 2*ml+mu+1 of abd .
c see the comments below for details.
c
c lda integer
c the leading dimension of the array abd .
c lda must be .ge. 2*ml + mu + 1 .
c
c n integer
c the order of the original matrix.
c
c ml integer
c number of diagonals below the main diagonal.
c 0 .le. ml .lt. n .
c
c mu integer
c number of diagonals above the main diagonal.
c 0 .le. mu .lt. n .
c more efficient if ml .le. mu .
c on return
c
c abd an upper triangular matrix in band storage and
c the multipliers which were used to obtain it.
c the factorization can be written a = l*u where
c l is a product of permutation and unit lower
c triangular matrices and u is upper triangular.
c
c ipvt integer(n)
c an integer vector of pivot indices.
c
c info integer
c = 0 normal value.
c = k if u(k,k) .eq. 0.0 . this is not an error
c condition for this subroutine, but it does
c indicate that sgbsl will divide by zero if
c called. use rcond in sgbco for a reliable
c indication of singularity.
c
c band storage
c
c if a is a band matrix, the following program segment
c will set up the input.
c
c ml = (band width below the diagonal)
c mu = (band width above the diagonal)
c m = ml + mu + 1
c do 20 j = 1, n
c i1 = max0(1, j-mu)
c i2 = min0(n, j+ml)
c do 10 i = i1, i2
c k = i - j + m
c abd(k,j) = a(i,j)
c 10 continue
c 20 continue
c
c this uses rows ml+1 through 2*ml+mu+1 of abd .
c in addition, the first ml rows in abd are used for
c elements generated during the triangularization.
c the total number of rows needed in abd is 2*ml+mu+1 .
c the ml+mu by ml+mu upper left triangle and the
c ml by ml lower right triangle are not referenced.
c
c linpack. this version dated 08/14/78 .
c cleve moler, university of new mexico, argonne national lab.
c
c subroutines and functions
c
c blas saxpy,sscal,isamax
c fortran max0,min0
c
c internal variables
c
real t
integer i,isamax,i0,j,ju,jz,j0,j1,k,kp1,l,lm,m,mm,nm1
c
c
m = ml + mu + 1
info = 0
c
c zero initial fill-in columns
c
j0 = mu + 2
j1 = min0(n,m) - 1
if (j1 .lt. j0) go to 30
do 20 jz = j0, j1
i0 = m + 1 - jz
do 10 i = i0, ml
abd(i,jz) = 0.0e0
10 continue
20 continue
30 continue
jz = j1
ju = 0
c
c gaussian elimination with partial pivoting
c
nm1 = n - 1
if (nm1 .lt. 1) go to 130
do 120 k = 1, nm1
kp1 = k + 1
c
c zero next fill-in column
c
jz = jz + 1
if (jz .gt. n) go to 50
if (ml .lt. 1) go to 50
do 40 i = 1, ml
abd(i,jz) = 0.0e0
40 continue
50 continue
c
c find l = pivot index
c
lm = min0(ml,n-k)
l = isamax(lm+1,abd(m,k),1) + m - 1
ipvt(k) = l + k - m
c
c zero pivot implies this column already triangularized
c
if (abd(l,k) .eq. 0.0e0) go to 100
c
c interchange if necessary
c
if (l .eq. m) go to 60
t = abd(l,k)
abd(l,k) = abd(m,k)
abd(m,k) = t
60 continue
c
c compute multipliers
c
t = -1.0e0/abd(m,k)
call sscal(lm,t,abd(m+1,k),1)
c
c row elimination with column indexing
c
ju = min0(max0(ju,mu+ipvt(k)),n)
mm = m
if (ju .lt. kp1) go to 90
do 80 j = kp1, ju
l = l - 1
mm = mm - 1
t = abd(l,j)
if (l .eq. mm) go to 70
abd(l,j) = abd(mm,j)
abd(mm,j) = t
70 continue
call saxpy(lm,t,abd(m+1,k),1,abd(mm+1,j),1)
80 continue
90 continue
go to 110
100 continue
info = k
110 continue
120 continue
130 continue
ipvt(n) = n
if (abd(m,n) .eq. 0.0e0) info = n
return
end
subroutine sgbsl(abd,lda,n,ml,mu,ipvt,b,job)
integer lda,n,ml,mu,ipvt(1),job
real abd(lda,1),b(1)
c
c sgbsl solves the real band system
c a * x = b or trans(a) * x = b
c using the factors computed by sgbco or sgbfa.
c
c on entry
c
c abd real(lda, n)
c the output from sgbco or sgbfa.
c
c lda integer
c the leading dimension of the array abd .
c
c n integer
c the order of the original matrix.
c
c ml integer
c number of diagonals below the main diagonal.
c
c mu integer
c number of diagonals above the main diagonal.
c
c ipvt integer(n)
c the pivot vector from sgbco or sgbfa.
c
c b real(n)
c the right hand side vector.
c
c job integer
c = 0 to solve a*x = b ,
c = nonzero to solve trans(a)*x = b , where
c trans(a) is the transpose.
c
c on return
c
c b the solution vector x .
c
c error condition
c
c a division by zero will occur if the input factor contains a
c zero on the diagonal. technically this indicates singularity
c but it is often caused by improper arguments or improper
c setting of lda . it will not occur if the subroutines are
c called correctly and if sgbco has set rcond .gt. 0.0
c or sgbfa has set info .eq. 0 .
c
c to compute inverse(a) * c where c is a matrix
c with p columns
c call sgbco(abd,lda,n,ml,mu,ipvt,rcond,z)
c if (rcond is too small) go to ...
c do 10 j = 1, p
c call sgbsl(abd,lda,n,ml,mu,ipvt,c(1,j),0)
c 10 continue
c
c linpack. this version dated 08/14/78 .
c cleve moler, university of new mexico, argonne national lab.
c
c subroutines and functions
c
c blas saxpy,sdot
c fortran min0
c
c internal variables
c
real sdot,t
integer k,kb,l,la,lb,lm,m,nm1
c
m = mu + ml + 1
nm1 = n - 1
if (job .ne. 0) go to 50
c
c job = 0 , solve a * x = b
c first solve l*y = b
c
if (ml .eq. 0) go to 30
if (nm1 .lt. 1) go to 30
do 20 k = 1, nm1
lm = min0(ml,n-k)
l = ipvt(k)
t = b(l)
if (l .eq. k) go to 10
b(l) = b(k)
b(k) = t
10 continue
call saxpy(lm,t,abd(m+1,k),1,b(k+1),1)
20 continue
30 continue
c
c now solve u*x = y
c
do 40 kb = 1, n
k = n + 1 - kb
b(k) = b(k)/abd(m,k)
lm = min0(k,m) - 1
la = m - lm
lb = k - lm
t = -b(k)
call saxpy(lm,t,abd(la,k),1,b(lb),1)
40 continue
go to 100
50 continue
c
c job = nonzero, solve trans(a) * x = b
c first solve trans(u)*y = b
c
do 60 k = 1, n
lm = min0(k,m) - 1
la = m - lm
lb = k - lm
t = sdot(lm,abd(la,k),1,b(lb),1)
b(k) = (b(k) - t)/abd(m,k)
60 continue
c
c now solve trans(l)*x = y
c
if (ml .eq. 0) go to 90
if (nm1 .lt. 1) go to 90
do 80 kb = 1, nm1
k = n - kb
lm = min0(ml,n-k)
b(k) = b(k) + sdot(lm,abd(m+1,k),1,b(k+1),1)
l = ipvt(k)
if (l .eq. k) go to 70
t = b(l)
b(l) = b(k)
b(k) = t
70 continue
80 continue
90 continue
100 continue
return
end
function sdot(n,sx,incx,sy,incy)
c
c forms the dot product of two vectors.
c uses unrolled loops for increments equal to one.
c jack dongarra, linpack, 3/11/78.
c modified 12/3/93, array(1) declarations changed to array(*)
c
real sdot
real sx(*),sy(*),stemp
integer i,incx,incy,ix,iy,m,mp1,n
c
stemp = 0.0e0
sdot = 0.0e0
if(n.le.0)return
if(incx.eq.1.and.incy.eq.1)go to 20
c
c code for unequal increments or equal increments
c not equal to 1
c
ix = 1
iy = 1
if(incx.lt.0)ix = (-n+1)*incx + 1
if(incy.lt.0)iy = (-n+1)*incy + 1
do 10 i = 1,n
stemp = stemp + sx(ix)*sy(iy)
ix = ix + incx
iy = iy + incy
10 continue
sdot = stemp
return
c
c code for both increments equal to 1
c
c
c clean-up loop
c
20 m = mod(n,5)
if( m .eq. 0 ) go to 40
do 30 i = 1,m
stemp = stemp + sx(i)*sy(i)
30 continue
if( n .lt. 5 ) go to 60
40 mp1 = m + 1
do 50 i = mp1,n,5
stemp = stemp + sx(i)*sy(i) + sx(i + 1)*sy(i + 1) +
* sx(i + 2)*sy(i + 2) + sx(i + 3)*sy(i + 3) + sx(i + 4)*sy(i + 4)
50 continue
60 sdot = stemp
return
end
function isamax(n,sx,incx)
c
c finds the index of element having max. absolute value.
c jack dongarra, linpack, 3/11/78.
c modified 3/93 to return if incx .le. 0.
c modified 12/3/93, array(1) declarations changed to array(*)
c
integer isamax
real sx(*),smax
integer i,incx,ix,n
c
isamax = 0
if( n.lt.1 .or. incx.le.0 ) return
isamax = 1
if(n.eq.1)return
if(incx.eq.1)go to 20
c
c code for increment not equal to 1
c
ix = 1
smax = abs(sx(1))
ix = ix + incx
do 10 i = 2,n
if(abs(sx(ix)).le.smax) go to 5
isamax = i
smax = abs(sx(ix))
5 ix = ix + incx
10 continue
return
c
c code for increment equal to 1
c
20 smax = abs(sx(1))
do 30 i = 2,n
if(abs(sx(i)).le.smax) go to 30
isamax = i
smax = abs(sx(i))
30 continue
return
end
*======= BEGIN of TUV 5.3.1 =======*
* M.LERICHE Update Feb. 2018
CCC FILE TUV.f
*----------------------------------------------------------------------------
subroutine tuvmain (asza, idate,
+ albnew, dobnew,
+ nlevel, zin, lwc,

ESCOBAR MUNOZ Juan
committed
+ njout, jout, jlabelout,
+ kout )
*-----------------------------------------------------------------------------*
*= Tropospheric Ultraviolet-Visible (TUV) radiation model =*
*= Version 5.3 =*
*= June 2016 =*
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
*-----------------------------------------------------------------------------*
*= Developed by Sasha Madronich with important contributions from: =*
*= Chris Fischer, Siri Flocke, Julia Lee-Taylor, Bernhard Meyer, =*
*= Irina Petropavlovskikh, Xuexi Tie, and Jun Zen. =*
*= Special thanks to Knut Stamnes and co-workers for the development of the =*
*= Discrete Ordinates code, and to Warren Wiscombe and co-workers for the =*
*= development of the solar zenith angle subroutine. Citations for the many =*
*= data bases (e.g. extraterrestrial irradiances, molecular spectra) may be =*
*= found in the data files headers and/or in the subroutines that read them. =*
*= To contact the author, write to: =*
*= Sasha Madronich, NCAR/ACD, P.O.Box 3000, Boulder, CO, 80307-3000, USA or =*
*= send email to: sasha@ucar.edu or tuv@acd.ucar.edu =*
*-----------------------------------------------------------------------------*
*= This program is free software; you can redistribute it and/or modify =*
*= it under the terms of the GNU General Public License as published by the =*
*= Free Software Foundation; either version 2 of the license, or (at your =*
*= option) any later version. =*
*= The TUV package is distributed in the hope that it will be useful, but =*
*= WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBI- =*
*= LITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public =*
*= License for more details. =*
*= To obtain a copy of the GNU General Public License, write to: =*
*= Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. =*
*-----------------------------------------------------------------------------*
*= Copyright (C) 1994-2016 by the University Corporation for Atmospheric =*
*= Research, extending to all called subroutines, functions, and data unless =*
*= another source is specified. =*
*-----------------------------------------------------------------------------*
*= Adapted to MesoNH : ONLY JVALUES are computed
IMPLICIT NONE
SAVE
* Include parameter file
c INCLUDE 'params'
*
* BROADLY USED PARAMETERS:
*_________________________________________________
* i/o file unit numbers

WAUTELET Philippe
committed
INTEGER :: ilu
INTEGER kout

ESCOBAR MUNOZ Juan
committed
* PARAMETER(kout=6)
*_________________________________________________
* altitude, wavelength, time (or solar zenith angle) grids
INTEGER kz, kw
* altitude
PARAMETER(kz=151)
* wavelength
PARAMETER(kw=157)
*_________________________________________________
* number of weighting functions
* wavelength and altitude dependent
PARAMETER(kj=90)
* delta for adding points at beginning or end of data grids
REAL deltax
PARAMETER (deltax = 1.E-5)
*_________________________________________________
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
* some constants...
* pi:
REAL pi
PARAMETER(pi=3.1415926535898)
* radius of the earth, km:
REAL radius
PARAMETER(radius=6.371E+3)
* Planck constant x speed of light, J m
REAL hc
PARAMETER(hc = 6.626068E-34 * 2.99792458E8)
* largest number of the machine:
REAL largest
PARAMETER(largest=1.E+36)
* small numbers (positive and negative)
REAL pzero, nzero
PARAMETER(pzero = +10./largest)
PARAMETER(nzero = -10./largest)
* machine precision
REAL precis
PARAMETER(precis = 1.e-7)
* More physical constants:
*_________________________________________________________________
* Na = 6.022142E23 mol-1 = Avogadro constant
* kb = 1.38065E-23 J K-1 = Boltzmann constant
* R = 8.31447 J mol-1 K-1 = molar gas constant
* h = 6.626068E-34 J s = Planck constant
* c = 2.99792458E8 m s-1 = speed of light in vacuum
* G = 6.673E-11 m3 kg-1 s-2 = Netwonian constant of gravitation
* sb = 5.67040E-8 W m-2 K-4 = Stefan-Boltzmann constant
*_________________________________________________________________
* (1) From NIST Reference on Constants, Units, and Uncertainty
* http://physics.nist.gov/cuu/index.html Oct. 2001.
* (2) These constants are not assigned to variable names; in other
* words this is not Fortran code, but only a text table for quick
* reference. To use, you must declare a variable name/type and
* assign the value to that variable. Or assign as parameter (see
* example for pi above).
* Wavelength grid:
INTEGER nw, iw, nwint
REAL wl(kw), wc(kw), wu(kw)
REAL wstart, wstop
* Altitude grid
INTEGER nz, nzm1, iz, izout
REAL z(kz), zstart, zstop, zout
* Solar zenith angle and azimuth
* slant pathlengths in spherical geometry
REAL sza, zen
INTEGER nid(0:kz)
REAL dsdh(0:kz,kz)
* Extra terrestrial solar flux and earth-Sun distance ^-2
REAL f(kw), etf(kw)
REAL esfact
* Ozone absorption cross section
INTEGER mabs
REAL o3xs(kz,kw)
* O2 absorption cross section
REAL o2xs(kz,kw), o2xs1(kw)
* SO2 absorption cross section
REAL so2xs(kw)
* NO2 absorption cross section
REAL no2xs(kz,kw)
* Atmospheric optical parameters
REAL tlev(kz), tlay(kz)
REAL aircon(kz), aircol(kz), vcol(kz), scol(kz)
REAL dtrl(kz,kw)
REAL co3(kz)
REAL dto3(kz,kw), dto2(kz,kw), dtso2(kz,kw), dtno2(kz,kw)
REAL dtcld(kz,kw), omcld(kz,kw), gcld(kz,kw)
REAL dtaer(kz,kw), omaer(kz,kw), gaer(kz,kw)
REAL dtsnw(kz,kw), omsnw(kz,kw), gsnw(kz,kw)
REAL albedo(kw)
* Spectral irradiance and actinic flux (scalar irradiance)
REAL edir(kz), edn(kz), eup(kz)
REAL sirrad(kz,kw)
REAL fdir(kz), fdn(kz), fup(kz)
REAL saflux(kz,kw)
* Photolysis coefficients (j-values)
INTEGER nj, ij
REAL sj(kj,kz,kw), valj(kj,kz)
REAL djdw
CHARACTER*50 jlabel(kj)
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
**** Re-scaling factors (can be read from input file)
* New surface albedo and surface pressure (milli bar)
* Total columns of O3, SO2, NO2 (Dobson Units)
* Cloud optical depth, altitude of base and top
* Aerosol optical depth at 550 nm, single scattering albedo, Angstrom alpha
REAL alsurf, psurf
REAL o3_tc, so2_tc, no2_tc
REAL taucld, zbase, ztop
REAL tauaer, ssaaer, alpha
* Location: Lat and Lon (deg.), surface elev (km)
* Altitude, temperature and pressure for specific outputs
REAL lat, lon
REAL zaird, ztemp
* Time and/or solar zenith angle
INTEGER iyear, imonth, iday
INTEGER it, nt
REAL t, tstart, tstop
LOGICAL lzenit
* number of radiation streams
INTEGER nstr
* input/output control
LOGICAL intrct
CHARACTER*6 inpfil, outfil
INTEGER iout
REAL dirsun, difdn, difup
CHARACTER*1 again
* Save arrays for output:
INTEGER isfix, ijfix, itfix, izfix, iwfix, i
* Planetary boundary layer height and pollutant concentrations
INTEGER ipbl
REAL zpbl
REAL o3pbl, so2pbl, no2pbl, aod330
* Other user-defined variables here:
C method:
C
C on first call, all necessary data will be read from the files
C in directories DATAE1, DATAJ1;
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
C all variables are saved for future calls to TUV
C
REAL, INTENT(IN) :: asza
INTEGER, INTENT(IN) :: idate
INTEGER, INTENT(IN) :: nlevel
REAL, INTENT(IN) :: dobnew, albnew
REAL, INTENT(IN) :: zin(nlevel)
REAL, INTENT(IN) :: lwc(nlevel)
INTEGER, INTENT(IN) :: njout
REAL, INTENT(OUT) :: jout(nlevel,njout)
CHARACTER*40, INTENT(OUT) :: jlabelout(njout)
C
LOGICAL LFIRSTCALL
DATA LFIRSTCALL /.TRUE./
C
* --- END OF DECLARATIONS ---------------------------------------------
* re-entry point
1000 CONTINUE
* ___ SECTION 1: SIMPLE INPUT VARIABLES --------------------------------
* Input and output files:
* inpfil = input file name
* outfil = output file name
* Radiative transfer scheme:
* nstr = number of streams
* If nstr < 2, will use 2-stream Delta Eddington
* If nstr > 1, will use nstr-stream discrete ordinates
nstr = 1
* Location (geographic):
* lat = LATITUDE (degrees, North = positive)
* lon = LONGITUDE (degrees, East = positive)
* tmzone = Local time zone difference (hrs) from Universal Time (ut):
* ut = timloc - tmzone
* Date:
* iyear = year (1950 to 2050)
* imonth = month (1 to 12)
* iday = day of month
* Time of day grid:
* tstart = starting time, local hours
* tstop = stopping time, local hours
* nt = number of time steps
* lzenit = switch for solar zenith angle (sza) grid rather than time
* grid. If lzenit = .TRUE. then
* tstart = first sza in deg.,
* tstop = last sza in deg.,
* nt = number of sza steps.
* esfact = 1. (Earth-sun distance = 1.000 AU)
lzenit=.TRUE.
* Vertical grid:
* zstart = surface elevation above sea level, km
* zstop = top of the atmosphere (exospheric), km
* nz = number of vertical levels, equally spaced
* (nz will increase by +1 if zout does not match altitude grid)
* Wavlength grid:
* wstart = starting wavelength, nm
* wstop = final wavelength, nm
* nwint = number of wavelength intervals, equally spaced
* if nwint < 0, the standard atmospheric wavelength grid, not
* equally spaced, from 120 to 735 nm, will be used. In this
* case, wstart and wstop values are ignored.
* Surface condition:
* alsurf = surface albedo, wavelength independent
* psurf = surface pressure, mbar. Set to negative value to use
* US Standard Atmosphere, 1976 (USSA76)
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
* Column amounts of absorbers (in Dobson Units, from surface to space):
* Vertical profile for O3 from USSA76. For SO2 and NO2, vertical
* concentration profile is 2.69e10 molec cm-3 between 0 and
* 1 km above sea level, very small residual (10/largest) above 1 km.
* o3_tc = ozone (O3)
* so2_tc = sulfur dioxide (SO2)
* no2_tc = nitrogen dioxide (NO2)
* Cloud, assumed horizontally uniform, total coverage, single scattering
* albedo = 0.9999, asymmetry factor = 0.85, indep. of wavelength,
* and also uniform vertically between zbase and ztop:
* taucld = vertical optical depth, independent of wavelength
* zbase = altitude of base, km above sea level
* ztop = altitude of top, km above sea level
* Aerosols, assumed vertical provile typical of continental regions from
* Elterman (1968):
* tauaer = aerosol vertical optical depth at 550 nm, from surface to space.
* If negative, will default to Elterman's values (ca. 0.235
* at 550 nm).
* ssaaer = single scattering albedo of aerosols, wavelength-independent.
* alpha = Angstrom coefficient = exponent for wavelength dependence of
* tauaer, so that tauaer1/tauaer2 = (w2/w1)**alpha.
* Directional components of radiation, weighting factors:
* dirsun = direct sun
* difdn = down-welling diffuse
* difup = up-welling diffuse
* e.g. use:
* dirsun = difdn = 1.0, difup = 0 for total down-welling irradiance
* dirsun = difdn = difup = 1.0 for actinic flux from all directions
* dirsun = difdn = 1.0, difup = -1 for net irradiance
dirsun = 1.0
difdn = 1.0
difup = 1.0
* Output altitude:
* zout = altitude, km, for desired output.
* If not within 1 m of altitude grid, an additional
* level will be inserted and nz will be increased by +1.
* zaird = air density (molec. cm-3) at zout. Set to negative value for
* default USSA76 value interpolated to zout.
* ztemp = air temperature (K) at zout. Set to negative value for
* default USSA76 value interpolated to zout.
* Output options, logical switches:
* laflux = output spectral actinic flux
* lmmech = output for NCAR Master Mechanism use
laflux =.FALSE.
lmmech =.FALSE.
* Output options, integer selections:
* ijfix: if > 0, output j-values for reaction ij=ijfix, tabulated
* for different times and altitudes.
* iwfix: if > 0, output spectral irradiance and/or spectral actinic
* flux at wavelength iw=iwfix, tabulated for different times
* and altitudes.
* itfix: if > 0, output spectral irradiance and/or spectral actinic
* flux at time it=itfix, tabulated for different altitudes
* and wavelengths.
* izfix: if > 0, output spectral irradiance and/or spectral actinic
* flux at altitude iz=izfix, tabulated for different times
* and wavelengths.
* nmj: number of j-values that will be reported. Selections must be
* made interactively, or by editing input file.
WRITE(kout,*) 'running TUVMAIN, version 5.3.1'
IF(nstr .LT. 2) THEN
WRITE(kout,*) 'Delta-Eddington 2-stream radiative transfer'
ELSE
WRITE(kout,*) 'Discrete ordinates ',
$ nstr, '-stream radiative transfer'
ENDIF
* ___ SECTION 2: SET GRIDS _________________________________________________
* altitudes (creates altitude grid, locates index for selected output, izout)
CALL gridz(zin,nlevel, zstart, zstop, nz, z, zout, izout,kout)
if(izfix .gt. 0) izout = izfix
* time/zenith (creates time/zenith angle grid, starting at tstart)
c CALL gridt(lat, lon, tmzone,
c $ iyear, imonth, iday,
c $ lzenit, tstart, tstop,
c $ nt, t, sza, esfact)
sza = asza
* wavelength grid, user-set range and spacing.
* NOTE: Wavelengths are in vacuum, and therefore independent of altitude.
* To use wavelengths in air, see options in subroutine gridw
CALL gridw(wstart, wstop, nwint,
$ nw, wl, wc, wu, kout)
* ___ SECTION 3: SET UP VERTICAL PROFILES OF TEMPERATURE, AIR DENSITY, and OZONE______
***** Temperature vertical profile, Kelvin
* can overwrite temperature at altitude z(izout)

ESCOBAR MUNOZ Juan
committed
CALL vptmp(nz,z, tlev,tlay,kout)
c IF(ztemp .GT. nzero) tlev(izout) = ztemp
***** Air density (molec cm-3) vertical profile
* can overwrite air density at altitude z(izout)
CALL vpair(psurf, nz, z,

ESCOBAR MUNOZ Juan
committed
$ aircon, aircol, kout)
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
c IF(zaird .GT. nzero) aircon(izout) = zaird
*****
*! PBL pollutants will be added if zpbl > 0.
* CAUTIONS:
* 1. The top of the PBL, zpbl in km, should be on one of the z-grid altitudes.
* 2. Concentrations, column increments, and optical depths
* will be overwritten between surface and zpbl.
* 3. Inserting PBL constituents may change their total column amount.
* 4. Above pbl, the following are used:
* for O3: USSA or other profile
* for NO2 and SO2: set to zero.
* for aerosols: Elterman
* Turning on pbl will affect subroutines:
* vpo3, setno2, setso2, and setaer. See there for details
zpbl = -999.
* locate z-index for top of pbl
ipbl = 0
IF(zpbl. GT. 0.) THEN
DO iz = 1, nz-1
IF(z(iz+1) .GT. z(1) + zpbl*1.00001) GO TO 19
ENDDO
19 CONTINUE
ipbl = iz - 1
write(*,*) 'top of PBL index, height (km) ', ipbl, z(ipbl)
* specify pbl concetrations, in parts per billion
o3pbl = 100.
so2pbl = 10.
no2pbl = 50.
* PBL aerosol optical depth at 330 nm
* (to change ssa and g of pbl aerosols, go to subroutine setair.f)
aod330 = 0.8
ENDIF
***** Ozone vertical profile
o3_tc = dobnew
CALL vpo3(ipbl, zpbl, o3pbl,

ESCOBAR MUNOZ Juan
committed
$ o3_tc, nz, z, aircol, co3, kout )
* ___ SECTION 4: READ SPECTRAL DATA ____________________________
* read (and grid) extra terrestrial flux data:

ESCOBAR MUNOZ Juan
committed
CALL rdetfl(nw,wl, f, kout )
* read cross section data for
* O2 (will overwrite at Lyman-alpha and SRB wavelengths
* see subroutine la_srb.f)
* O3 (temperature-dependent)
* SO2
* NO2
nzm1 = nz - 1
CALL rdo3xs(mabs,nzm1,tlay,nw,wl, o3xs,kout)
CALL rdso2xs(nw,wl, so2xs,kout)
CALL rdno2xs(nz,tlay,nw,wl, no2xs,kout)
****** Spectral weighting functions
* (Some of these depend on temperature T and pressure P, and therefore
* on altitude z. Therefore they are computed only after the T and P profiles
* are set above with subroutines settmp and setair.)
* Photo-chemical set in swchem.f (cross sections x quantum yields)
* Chemical weighting functions (product of cross-section x quantum yield)
* for many photolysis reactions are known to depend on temperature
* and/or pressure, and therefore are functions of wavelength and altitude.
* Output:
* from swchem: sj(kj,kz,kw) - for each reaction jlabel(kj)
* For swchem, need to know temperature and pressure profiles.
CALL swchem(nw,wl,nz,tlev,aircon, nj,sj,jlabel,tpflag,kout)
******
* ___ SECTION 5: SET ATMOSPHERIC OPTICAL DEPTH INCREMENTS _____________________
* Rayleigh optical depth increments:
CALL odrl(nz, z, nw, wl, aircol, dtrl,kout)
* O2 vertical profile and O2 absorption optical depths
* For now, O2 densitiy assumed as 20.95% of air density, can be changed
* in subroutine.
* Optical depths in Lyman-alpha and SRB will be over-written
* in subroutine la_srb.f
CALL seto2(nz,z,nw,wl,aircol,o2xs1, dto2, kout)
CALL odo3(nz,z,nw,wl,o3xs,co3, dto3,kout)
* SO2 vertical profile and optical depths
so2_tc = 0.
CALL setso2(ipbl, zpbl, so2pbl,
$ so2_tc, nz, z, nw, wl, so2xs,
$ tlay, aircol,
* NO2 vertical profile and optical depths
no2_tc = 0.
CALL setno2(ipbl, zpbl, no2pbl,
$ no2_tc, nz, z, nw, wl, no2xs,
$ tlay, aircol,