CCPP SciDoc v7.0.x  v7.0.0
Common Community Physics Package Developed at DTC
 
Loading...
Searching...
No Matches
module_ozphys.F90
1
3
36! #########################################################################################
38 use machine, only : kind_phys
39 use funcphys, only : fpkapx
40 implicit none
41
42 public ty_ozphys
43
44! #########################################################################################
51! #########################################################################################
53 ! Prognostic ozone.
54 integer :: nlat
55 integer :: nlev
56 integer :: ntime
57 integer :: ncf
58 real(kind_phys), allocatable :: lat(:)
59 real(kind_phys), allocatable :: pres(:)
60 real(kind_phys), allocatable :: po3(:)
61 real(kind_phys), allocatable :: time(:)
62 real(kind_phys), allocatable :: data(:,:,:,:)
63 ! Climotological ozone.
64 integer :: nlatc
65 integer :: nlevc
66 integer :: ntimec
67 real(kind_phys) :: blatc
68 real(kind_phys) :: dphiozc
69 real(kind_phys), allocatable :: pkstr(:)
70 real(kind_phys), allocatable :: pstr(:)
71 real(kind_phys), allocatable :: datac(:,:,:)
72 integer :: k1oz
73 integer :: k2oz
74 real(kind_phys) :: facoz
75 contains
76 procedure, public :: load_o3prog
77 procedure, public :: setup_o3prog
78 procedure, public :: update_o3prog
79 procedure, public :: run_o3prog_2015
80 procedure, public :: run_o3prog_2006
81 !
82 procedure, public :: load_o3clim
83 procedure, public :: update_o3clim
84 procedure, public :: run_o3clim
85 end type ty_ozphys
86
87contains
88
90 function load_o3prog(this, file, fileID) result (err_message)
91 class(ty_ozphys), intent(inout) :: this
92 integer, intent(in) :: fileid
93 character(len=*), intent(in) :: file
94 character(len=128) :: err_message
95 integer :: i1, i2, i3, ierr
96 real(kind=4), dimension(:), allocatable :: lat4, pres4, time4, tempin
97 real(kind=4) :: blatc4
98
99 ! initialize error message
100 err_message = ""
101
102 ! Get dimensions from data file
103 open(unit=fileid,file=trim(file), form='unformatted', convert='big_endian', iostat=ierr, iomsg=err_message)
104 if (ierr /= 0 ) return
105 read (fileid, iostat=ierr, iomsg=err_message) this%ncf, this%nlat, this%nlev, this%ntime
106 if (ierr /= 0 ) return
107 rewind(fileid)
108
109 allocate (this%lat(this%nlat))
110 allocate (this%pres(this%nlev))
111 allocate (this%po3(this%nlev))
112 allocate (this%time(this%ntime+1))
113 allocate (this%data(this%nlat,this%nlev,this%ncf,this%ntime))
114
115 allocate(lat4(this%nlat), pres4(this%nlev), time4(this%ntime+1))
116 read (fileid, iostat=ierr, iomsg=err_message) this%ncf, this%nlat, this%nlev, this%ntime, lat4, pres4, time4
117 if (ierr /= 0 ) return
118
119 ! Store
120 this%pres(:) = pres4(:)
121 this%po3(:) = log(100.0*this%pres(:)) ! from mb to ln(Pa)
122 this%lat(:) = lat4(:)
123 this%time(:) = time4(:)
124 deallocate(lat4, pres4, time4)
125
126 allocate(tempin(this%nlat))
127 do i1=1,this%ntime
128 do i2=1,this%ncf
129 do i3=1,this%nlev
130 read(fileid, iostat=ierr, iomsg=err_message) tempin
131 if (ierr /= 0 ) return
132 this%data(:,i3,i2,i1) = tempin(:)
133 enddo
134 enddo
135 enddo
136 deallocate(tempin)
137 close(fileid)
138
139 end function load_o3prog
140
143 subroutine setup_o3prog(this, lat, idx1, idx2, idxh)
144 class(ty_ozphys), intent(in) :: this
145 real(kind_phys), intent(in) :: lat(:)
146 integer, intent(out) :: idx1(:), idx2(:)
147 real(kind_phys), intent(out) :: idxh(:)
148 integer :: i,j
149
150 do j=1,size(lat)
151 idx2(j) = this%nlat + 1
152 do i=1,this%nlat
153 if (lat(j) < this%lat(i)) then
154 idx2(j) = i
155 exit
156 endif
157 enddo
158 idx1(j) = max(idx2(j)-1,1)
159 idx2(j) = min(idx2(j),this%nlat)
160 if (idx2(j) .ne. idx1(j)) then
161 idxh(j) = (lat(j) - this%lat(idx1(j))) / (this%lat(idx2(j)) - this%lat(idx1(j)))
162 else
163 idxh(j) = 1.0
164 endif
165 enddo
166
167 end subroutine setup_o3prog
168
170 subroutine update_o3prog(this, idx1, idx2, idxh, rjday, idxt1, idxt2, ozpl)
171 class(ty_ozphys), intent(in) :: this
172 integer, intent(in) :: idx1(:), idx2(:)
173 real(kind_phys), intent(in) :: idxh(:)
174 real(kind_phys), intent(in) :: rjday
175 integer, intent(in) :: idxt1, idxt2
176 real(kind_phys), intent(out) :: ozpl(:,:,:)
177 integer :: nc, l, j, j1, j2
178 real(kind_phys) :: tem, tx1, tx2
179
180 tx1 = (this%time(idxt2) - rjday) / (this%time(idxt2) - this%time(idxt1))
181 tx2 = 1.0 - tx1
182
183 do nc=1,this%ncf
184 do l=1,this%nlev
185 do j=1,size(ozpl(:,1,1))
186 j1 = idx1(j)
187 j2 = idx2(j)
188 tem = 1.0 - idxh(j)
189 ozpl(j,l,nc) = tx1*(tem*this%data(j1,l,nc,idxt1)+idxh(j)*this%data(j2,l,nc,idxt1)) &
190 + tx2*(tem*this%data(j1,l,nc,idxt2)+idxh(j)*this%data(j2,l,nc,idxt2))
191 enddo
192 enddo
193 enddo
194
195 end subroutine update_o3prog
196
197 ! #########################################################################################
198 ! Procedure (type-bound) for NRL prognostic ozone (2015).
199 ! #########################################################################################
200 subroutine run_o3prog_2015(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, &
201 do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz)
202
203 class(ty_ozphys), intent(in) :: this
204 real(kind_phys), intent(in) :: &
205 con_1ovg ! Physical constant: One divided by gravitational acceleration (m-1 s2)
206 real(kind_phys), intent(in) :: &
207 dt ! Model timestep (sec)
208 real(kind_phys), intent(in), dimension(:,:) :: &
209 p, & ! Model Pressure (Pa)
210 t, & ! Model temperature (K)
211 dp ! Model layer thickness (Pa)
212 real(kind_phys), intent(in), dimension(:,:,:) :: &
213 ozpl ! Ozone forcing data
214 real(kind_phys), intent(inout), dimension(:,:) :: &
215 oz ! Ozone concentration updated by physics
216 real(kind_phys), intent(inout), dimension(:,:), optional :: &
217 do3_dt_prd, & ! Physics tendency: production and loss effect
218 do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect
219 do3_dt_temp, & ! Physics tendency: temperature effect
220 do3_dt_ohoz ! Physics tendency: overhead ozone effect
221
222 integer :: k, kmax, kmin, iLev, iCol, nCol, nLev, iCf
223 logical, dimension(size(p,1)) :: flg
224 real(kind_phys) :: pmax, pmin, tem, temp
225 real(kind_phys), dimension(size(p,1)) :: wk1, wk2, wk3, ozib
226 real(kind_phys), dimension(size(p,1),this%ncf) :: prod
227 real(kind_phys), dimension(size(p,1),size(p,2)) :: ozi
228 real(kind_phys), dimension(size(p,1),size(p,2)+1) :: colo3, coloz
229
230 ! Dimensions
231 ncol = size(p,1)
232 nlev = size(p,2)
233
234 ! Temporaries
235 ozi = oz
236
237 colo3(:,nlev+1) = 0.0
238 coloz(:,nlev+1) = 0.0
239
240 do ilev=nlev,1,-1
241 pmin = 1.0e10
242 pmax = -1.0e10
243
244 do icol=1,ncol
245 wk1(icol) = log(p(icol,ilev))
246 pmin = min(wk1(icol), pmin)
247 pmax = max(wk1(icol), pmax)
248 prod(icol,:) = 0._kind_phys
249 enddo
250 kmax = 1
251 kmin = 1
252 do k=1,this%nlev-1
253 if (pmin < this%po3(k)) kmax = k
254 if (pmax < this%po3(k)) kmin = k
255 enddo
256 !
257 do k=kmin,kmax
258 temp = 1.0 / (this%po3(k) - this%po3(k+1))
259 do icol=1,ncol
260 flg(icol) = .false.
261 if (wk1(icol) < this%po3(k) .and. wk1(icol) >= this%po3(k+1)) then
262 flg(icol) = .true.
263 wk2(icol) = (wk1(icol) - this%po3(k+1)) * temp
264 wk3(icol) = 1.0 - wk2(icol)
265 endif
266 enddo
267 do icf=1,this%ncf
268 do icol=1,ncol
269 if (flg(icol)) then
270 prod(icol,icf) = wk2(icol) * ozpl(icol,k,icf) + wk3(icol) * ozpl(icol,k+1,icf)
271 endif
272 enddo
273 enddo
274 enddo
275
276 do icf=1,this%ncf
277 do icol=1,ncol
278 if (wk1(icol) < this%po3(this%nlev)) then
279 prod(icol,icf) = ozpl(icol,this%nlev,icf)
280 endif
281 if (wk1(icol) >= this%po3(1)) then
282 prod(icol,icf) = ozpl(icol,1,icf)
283 endif
284 enddo
285 enddo
286 do icol=1,ncol
287 colo3(icol,ilev) = colo3(icol,ilev+1) + ozi(icol,ilev) * dp(icol,ilev)*con_1ovg
288 coloz(icol,ilev) = coloz(icol,ilev+1) + prod(icol,6) * dp(icol,ilev)*con_1ovg
289 prod(icol,2) = min(prod(icol,2), 0.0)
290 enddo
291 do icol=1,ncol
292 ozib(icol) = ozi(icol,ilev)
293 tem = prod(icol,1) - prod(icol,2) * prod(icol,6) &
294 + prod(icol,3) * (t(icol,ilev) - prod(icol,5)) &
295 + prod(icol,4) * (colo3(icol,ilev)-coloz(icol,ilev))
296 oz(icol,ilev) = (ozib(icol) + tem*dt) / (1.0 - prod(icol,2)*dt)
297 enddo
298
299 ! Diagnostics (optional)
300 if (present(do3_dt_prd)) do3_dt_prd(:,ilev) = prod(:,1) * dt
301 if (present(do3_dt_ozmx)) do3_dt_ozmx(:,ilev) = prod(:,2) * (oz(:,ilev) - prod(:,6)) * dt
302 if (present(do3_dt_temp)) do3_dt_temp(:,ilev) = prod(:,3)*(t(:,ilev)-prod(:,5))*dt
303 if (present(do3_dt_ohoz)) do3_dt_ohoz(:,ilev) = prod(:,4) * (colo3(:,ilev)-coloz(:,ilev))*dt
304
305 enddo
306
307 return
308 end subroutine run_o3prog_2015
309
310 ! #########################################################################################
311 ! Procedure (type-bound) for NRL prognostic ozone (2006).
312 ! #########################################################################################
313 subroutine run_o3prog_2006(this, con_1ovg, dt, p, t, dp, ozpl, oz, do3_dt_prd, &
314 do3_dt_ozmx, do3_dt_temp, do3_dt_ohoz)
315
316 class(ty_ozphys), intent(in) :: this
317 real(kind_phys), intent(in) :: &
318 con_1ovg ! Physical constant: One divided by gravitational acceleration (m-1 s2)
319 real(kind_phys), intent(in) :: &
320 dt ! Model timestep (sec)
321 real(kind_phys), intent(in), dimension(:,:) :: &
322 p, & ! Model Pressure (Pa)
323 t, & ! Model temperature (K)
324 dp ! Model layer thickness (Pa)
325 real(kind_phys), intent(in), dimension(:,:,:) :: &
326 ozpl ! Ozone forcing data
327 real(kind_phys), intent(inout), dimension(:,:) :: &
328 oz ! Ozone concentration updated by physics
329 real(kind_phys), intent(inout), dimension(:,:), optional :: &
330 do3_dt_prd, & ! Physics tendency: production and loss effect
331 do3_dt_ozmx, & ! Physics tendency: ozone mixing ratio effect
332 do3_dt_temp, & ! Physics tendency: temperature effect
333 do3_dt_ohoz ! Physics tendency: overhead ozone effect
334
335 ! Locals
336 integer :: k, kmax, kmin, iLev, iCol, nCol, nLev, iCf
337 logical, dimension(size(p,1)) :: flg
338 real(kind_phys) :: pmax, pmin, tem, temp
339 real(kind_phys), dimension(size(p,1)) :: wk1, wk2, wk3, ozib
340 real(kind_phys), dimension(size(p,1),this%ncf) :: prod
341 real(kind_phys), dimension(size(p,1),size(p,2)) :: ozi
342 real(kind_phys), dimension(size(p,1),size(p,2)+1) :: colo3, coloz
343
344 ! Dimensions
345 ncol = size(p,1)
346 nlev = size(p,2)
347
348 ! Temporaries
349 ozi = oz
350
352 if (this%ncf > 2) then
353 colo3(:,nlev+1) = 0.0
354 do ilev=nlev,1,-1
355 do icol=1,ncol
356 colo3(icol,ilev) = colo3(icol,ilev+1) + ozi(icol,ilev) * dp(icol,ilev) * con_1ovg
357 enddo
358 enddo
359 endif
360
362 do ilev=1,nlev
363 pmin = 1.0e10
364 pmax = -1.0e10
365
366 do icol=1,ncol
367 wk1(icol) = log(p(icol,ilev))
368 pmin = min(wk1(icol), pmin)
369 pmax = max(wk1(icol), pmax)
370 prod(icol,:) = 0._kind_phys
371 enddo
372 kmax = 1
373 kmin = 1
374 do k=1,this%nlev-1
375 if (pmin < this%po3(k)) kmax = k
376 if (pmax < this%po3(k)) kmin = k
377 enddo
378
379 do k=kmin,kmax
380 temp = 1.0 / (this%po3(k) - this%po3(k+1))
381 do icol=1,ncol
382 flg(icol) = .false.
383 if (wk1(icol) < this%po3(k) .and. wk1(icol) >= this%po3(k+1)) then
384 flg(icol) = .true.
385 wk2(icol) = (wk1(icol) - this%po3(k+1)) * temp
386 wk3(icol) = 1.0 - wk2(icol)
387 endif
388 enddo
389 do icf=1,this%ncf
390 do icol=1,ncol
391 if (flg(icol)) then
392 prod(icol,icf) = wk2(icol) * ozpl(icol,k,icf) + wk3(icol) * ozpl(icol,k+1,icf)
393 endif
394 enddo
395 enddo
396 enddo
397
398 do icf=1,this%ncf
399 do icol=1,ncol
400 if (wk1(icol) < this%po3(this%nlev)) then
401 prod(icol,icf) = ozpl(icol,this%nlev,icf)
402 endif
403 if (wk1(icol) >= this%po3(1)) then
404 prod(icol,icf) = ozpl(icol,1,icf)
405 endif
406 enddo
407 enddo
408
409 if (this%ncf == 2) then
410 do icol=1,ncol
411 ozib(icol) = ozi(icol,ilev)
412 oz(icol,ilev) = (ozib(icol) + prod(icol,1)*dt) / (1.0 + prod(icol,2)*dt)
413 enddo
414 endif
415
416 if (this%ncf == 4) then
417 do icol=1,ncol
418 ozib(icol) = ozi(icol,ilev)
419 tem = prod(icol,1) + prod(icol,3)*t(icol,ilev) + prod(icol,4)*colo3(icol,ilev+1)
420 oz(icol,ilev) = (ozib(icol) + tem*dt) / (1.0 + prod(icol,2)*dt)
421 enddo
422 endif
423
424 ! Diagnostics (optional)
425 if (present(do3_dt_prd)) do3_dt_prd(:,ilev) = prod(:,1)*dt
426 if (present(do3_dt_ozmx)) do3_dt_ozmx(:,ilev) = (oz(:,ilev) - ozib(:))
427 if (present(do3_dt_temp)) do3_dt_temp(:,ilev) = prod(:,3) * t(:,ilev) * dt
428 if (present(do3_dt_ohoz)) do3_dt_ohoz(:,ilev) = prod(:,4) * colo3(:,ilev) * dt
429
430 enddo
431
432 return
433 end subroutine run_o3prog_2006
434
436 subroutine run_o3clim(this, lat, prslk, con_pi, oz)
437 class(ty_ozphys), intent(in) :: this
438 real(kind_phys), intent(in) :: &
439 con_pi ! Physics constant: Pi
440 real(kind_phys), intent(in), dimension(:) :: &
441 lat ! Grid latitude
442 real(kind_phys), intent(in), dimension(:,:) :: &
443 prslk ! Exner function
444 real(kind_phys), intent(out), dimension(:,:) :: &
445 oz ! Ozone concentration updated by climotology
446
447 integer :: nCol, iCol, nLev, iLev, j, j1, j2, l, ll
448 real(kind_phys) :: elte, deglat, tem, tem1, tem2, tem3, tem4, temp
449 real(kind_phys), allocatable :: o3i(:,:),wk1(:)
450 logical :: top_at_1
451
452 ncol = size(prslk(:,1))
453 nlev = size(prslk(1,:))
454 allocate(o3i(ncol, this%nlevc),wk1(ncol))
455
456 ! What is vertical ordering?
457 top_at_1 = (prslk(1,1) .lt. prslk(1, nlev))
458
459 elte = this%blatc + (this%nlatc-1)*this%dphiozc
460
461 do icol = 1, ncol
462 deglat = lat(icol) * 180.0 / con_pi
463 if (deglat > this%blatc .and. deglat < elte) then
464 tem1 = (deglat - this%blatc) / this%dphiozc + 1
465 j1 = tem1
466 j2 = j1 + 1
467 tem1 = tem1 - j1
468 elseif (deglat <= this%blatc) then
469 j1 = 1
470 j2 = 1
471 tem1 = 1.0
472 elseif (deglat >= elte) then
473 j1 = this%nlatc
474 j2 = this%nlatc
475 tem1 = 1.0
476 endif
477
478 tem2 = 1.0 - tem1
479 do j = 1, this%nlevc
480 tem3 = tem2*this%datac(j1,j,this%k1oz) + tem1*this%datac(j2,j,this%k1oz)
481 tem4 = tem2*this%datac(j1,j,this%k2oz) + tem1*this%datac(j2,j,this%k2oz)
482 o3i(icol,j) = tem4*this%facoz + tem3*(1.0 - this%facoz)
483 enddo
484 enddo
485
486 do ilev = 1, nlev
487 ll = ilev
488 if (.not. top_at_1) ll = nlev - ilev + 1
489
490 do icol = 1, ncol
491 wk1(icol) = prslk(icol,ll)
492 enddo
493
494 do j = 1, this%nlevc-1
495 temp = 1.0 / (this%pkstr(j+1) - this%pkstr(j))
496 do icol = 1, ncol
497 if (wk1(icol) > this%pkstr(j) .and. wk1(icol) <= this%pkstr(j+1)) then
498 tem = (this%pkstr(j+1) - wk1(icol)) * temp
499 oz(icol,ll) = tem * o3i(icol,j) + (1.0 - tem) * o3i(icol,j+1)
500 endif
501 enddo
502 enddo
503
504 do icol = 1, ncol
505 if (wk1(icol) > this%pkstr(this%nlevc)) oz(icol,ll) = o3i(icol,this%nlevc)
506 if (wk1(icol) < this%pkstr(1)) oz(icol,ll) = o3i(icol,1)
507 enddo
508 enddo
509
510 return
511 end subroutine run_o3clim
512
514 function load_o3clim(this, file, fileID) result (err_message)
515 class(ty_ozphys), intent(inout) :: this
516 integer, intent(in) :: fileid
517 character(len=*), intent(in) :: file
518 character(len=128) :: err_message
519
520 ! Locals
521 real(kind=4) :: blatc4
522 integer :: ilev, ilat, imo, ierr
523 real(kind=4), allocatable :: o3clim4(:,:,:), pstr4(:)
524 integer, allocatable :: imond(:), ilatt(:,:)
525
526 ! initialize error message
527 err_message = ""
528
529 open(unit=fileid,file=trim(file),form='unformatted',convert='big_endian', iostat=ierr, iomsg=err_message)
530 if (ierr /= 0 ) return
531 read (fileid,end=101,iostat=ierr,iomsg=err_message) this%nlatc, this%nlevc, this%ntimec, blatc4
532 if (ierr /= 0 ) return
533
534101 if (this%nlevc < 10 .or. this%nlevc > 100) then
535 rewind(fileid)
536 this%nlevc = 17
537 this%nlatc = 18
538 this%blatc = -85.0
539 else
540 this%blatc = blatc4
541 endif
542 this%nlat = 2
543 this%nlev = 1
544 this%ntimec = 1
545 this%ncf = 0
546 this%dphiozc = -(this%blatc+this%blatc)/(this%nlatc-1)
547
548 allocate (o3clim4(this%nlatc,this%nlevc,12), pstr4(this%nlevc), imond(12), ilatt(this%nlatc,12) )
549
550 allocate (this%pkstr(this%nlevc), this%pstr(this%nlevc), this%datac(this%nlatc,this%nlevc,12))
551 if ( this%nlevc == 17 ) then ! For the operational ozone climatology
552 do ilev = 1, this%nlevc
553 read (fileid,15,iostat=ierr,iomsg=err_message) pstr4(ilev)
554 if (ierr /= 0 ) return
55515 format(f10.3)
556 enddo
557
558 do imo = 1, 12
559 do ilat = 1, this%nlatc
560 read (fileid,16,iostat=ierr,iomsg=err_message) imond(imo), ilatt(ilat,imo), (o3clim4(ilat,ilev,imo),ilev=1,10)
561 if (ierr /= 0 ) return
56216 format(i2,i4,10f6.2)
563 read (fileid,20,iostat=ierr,iomsg=err_message) (o3clim4(ilat,ilev,imo),ilev=11,this%nlevc)
564 if (ierr /= 0 ) return
56520 format(6x,10f6.2)
566 enddo
567 enddo
568 else ! For newer ozone climatology
569 read (fileid)
570 do ilev = 1, this%nlevc
571 read (fileid) pstr4(ilev)
572 enddo
573
574 do imo = 1, 12
575 do ilev = 1, this%nlevc
576 read (fileid,iostat=ierr,iomsg=err_message) (o3clim4(ilat,ilev,imo),ilat=1,this%nlatc)
577 if (ierr /= 0 ) return
578 enddo
579 enddo
580 endif ! end if_this%nlevc_block
581
582 do imo = 1, 12
583 do ilev = 1, this%nlevc
584 do ilat = 1, this%nlatc
585 this%datac(ilat,ilev,imo) = o3clim4(ilat,ilev,imo) * 1.655e-6
586 enddo
587 enddo
588 enddo
589
590 do ilev = 1, this%nlevc
591 this%pstr(ilev) = pstr4(ilev)
592 this%pkstr(ilev) = fpkapx(this%pstr(ilev)*100.0)
593 enddo
594
595 end function load_o3clim
596
599 subroutine update_o3clim(this, imon, iday, ihour, loz1st)
600 class(ty_ozphys), intent(inout) :: this
601 integer, intent(in) :: imon, iday, ihour
602 logical, intent(in) :: loz1st
603
604 integer :: midmon=15, midm=15, midp=45, id
605 integer, parameter, dimension(13) :: mdays = (/31,28,31,30,31,30,31,31,30,31,30,31,30/)
606 logical :: change
607
608 midmon = mdays(imon)/2 + 1
609 change = loz1st .or. ( (iday==midmon) .and. (ihour==0) )
610
611 if ( change ) then
612 if ( iday < midmon ) then
613 this%k1oz = mod(imon+10, 12) + 1
614 midm = mdays(this%k1oz)/2 + 1
615 this%k2oz = imon
616 midp = mdays(this%k1oz) + midmon
617 else
618 this%k1oz = imon
619 midm = midmon
620 this%k2oz = mod(imon, 12) + 1
621 midp = mdays(this%k2oz)/2 + 1 + mdays(this%k1oz)
622 endif
623 endif
624
625 if (iday < midmon) then
626 id = iday + mdays(this%k1oz)
627 else
628 id = iday
629 endif
630
631 this%facoz = float(id - midm) / float(midp - midm)
632
633 end subroutine update_o3clim
634
635 end module module_ozphys
The operational GFS currently parameterizes ozone production and destruction based on monthly mean co...