global_cycle  1.11.0
cycle.f90
Go to the documentation of this file.
1 
4 
101  PROGRAM sfc_drv
102 
103  use mpi
104 
105  IMPLICIT NONE
106 !
107  CHARACTER(LEN=3) :: donst
108  INTEGER :: idim, jdim, lsoil, lugb, iy, im, id, ih, ialb
109  INTEGER :: isot, ivegsrc, lensfc, zsea1_mm, zsea2_mm, ierr
110  INTEGER :: nprocs, myrank, num_threads, num_parthds, max_tasks
111  REAL :: fh, deltsfc, zsea1, zsea2
112  LOGICAL :: use_ufo, do_nsst, do_lndinc, do_sfccycle
113 !
114  NAMELIST/namcyc/ idim,jdim,lsoil,lugb,iy,im,id,ih,fh,&
115  deltsfc,ialb,use_ufo,donst, &
116  do_sfccycle,isot,ivegsrc,zsea1_mm, &
117  zsea2_mm, max_tasks, do_lndinc
118 !
119  DATA idim,jdim,lsoil/96,96,4/
120  DATA iy,im,id,ih,fh/1997,8,2,0,0./
121  DATA lugb/51/, deltsfc/0.0/, ialb/1/, max_tasks/99999/
122  DATA isot/1/, ivegsrc/2/, zsea1_mm/0/, zsea2_mm/0/
123 !
124  CALL mpi_init(ierr)
125  CALL mpi_comm_size(mpi_comm_world, nprocs, ierr)
126  CALL mpi_comm_rank(mpi_comm_world, myrank, ierr)
127 
128  if (myrank==0) call w3tagb('GLOBAL_CYCLE',2018,0179,0055,'NP20')
129 
130  num_threads = num_parthds()
131 
132  print*
133  print*,"STARTING CYCLE PROGRAM ON RANK ", myrank
134  print*,"RUNNING WITH ", nprocs, "TASKS"
135  print*,"AND WITH ", num_threads, " THREADS."
136 
137  use_ufo = .false.
138  donst = "NO"
139  do_lndinc = .false.
140  do_sfccycle = .true.
141 
142  print*
143  print*,"READ NAMCYC NAMELIST."
144 
145  CALL baopenr(36, "fort.36", ierr)
146  READ(36, nml=namcyc)
147  !IF (MYRANK==0) WRITE(6,NAMCYC)
148 
149  IF (max_tasks < 99999 .AND. myrank > (max_tasks - 1)) THEN
150  print*,"USER SPECIFIED MAX NUMBER OF TASKS: ", max_tasks
151  print*,"WILL NOT RUN CYCLE PROGRAM ON RANK: ", myrank
152  GOTO 333
153  ENDIF
154 
155  lensfc = idim*jdim ! TOTAL NUMBER OF POINTS FOR THE CUBED-SPHERE TILE
156 
157  zsea1 = float(zsea1_mm) / 1000.0 ! CONVERT FROM MM TO METERS
158  zsea2 = float(zsea2_mm) / 1000.0
159 
160  IF (donst == "YES") THEN
161  do_nsst=.true.
162  ELSE
163  do_nsst=.false.
164  ENDIF
165 
166  print*
167  IF (myrank==0) print*,"LUGB,IDIM,JDIM,ISOT,IVEGSRC,LSOIL,DELTSFC,IY,IM,ID,IH,FH: ", &
168  lugb,idim,jdim,isot,ivegsrc,lsoil,deltsfc,iy,im,id,ih,fh
169 
170  CALL sfcdrv(lugb,idim,jdim,lensfc,lsoil,deltsfc, &
171  iy,im,id,ih,fh,ialb, &
172  use_ufo,do_nsst,do_sfccycle,do_lndinc, &
173  zsea1,zsea2,isot,ivegsrc,myrank)
174 
175  print*
176  print*,'CYCLE PROGRAM COMPLETED NORMALLY ON RANK: ', myrank
177 
178  333 CONTINUE
179 
180  CALL mpi_barrier(mpi_comm_world, ierr)
181 
182  if (myrank==0) call w3tage('GLOBAL_CYCLE')
183 
184  CALL mpi_finalize(ierr)
185 
186  stop
187 
188  END PROGRAM sfc_drv
189 
297  SUBROUTINE sfcdrv(LUGB, IDIM,JDIM,LENSFC,LSOIL,DELTSFC, &
298  IY,IM,ID,IH,FH,IALB, &
299  USE_UFO,DO_NSST,DO_SFCCYCLE,DO_LNDINC,&
300  ZSEA1,ZSEA2,ISOT,IVEGSRC,MYRANK)
301 !
302  USE read_write_data
303  use machine
304  USE mpi
305  USE land_increments, ONLY: add_increment_soil, &
306  add_increment_snow, &
307  calculate_landinc_mask, &
308  apply_land_da_adjustments_soil, &
309  apply_land_da_adjustments_snd, &
310  lsm_noah, lsm_noahmp
311 
312  IMPLICIT NONE
313 
314  INTEGER, INTENT(IN) :: IDIM, JDIM, LENSFC, LSOIL, IALB
315  INTEGER, INTENT(IN) :: LUGB, IY, IM, ID, IH
316  INTEGER, INTENT(IN) :: ISOT, IVEGSRC, MYRANK
317 
318  LOGICAL, INTENT(IN) :: USE_UFO, DO_NSST,DO_SFCCYCLE
319  LOGICAL, INTENT(IN) :: DO_LNDINC
320 
321  REAL, INTENT(IN) :: FH, DELTSFC, ZSEA1, ZSEA2
322 
323  INTEGER, PARAMETER :: NLUNIT=35
324  INTEGER, PARAMETER :: SZ_NML=1
325 
326  CHARACTER(LEN=5) :: TILE_NUM
327  CHARACTER(LEN=500) :: NST_FILE
328  CHARACTER(LEN=500) :: LND_SOI_FILE
329  CHARACTER(LEN=4) :: INPUT_NML_FILE(SZ_NML)
330 
331  INTEGER :: I, IERR
332  INTEGER :: I_INDEX(LENSFC), J_INDEX(LENSFC)
333  INTEGER :: IDUM(IDIM,JDIM)
334  integer :: num_parthds, num_threads
335 
336  LOGICAL :: IS_NOAHMP
337  INTEGER :: LSM
338 
339  real(kind=kind_io8) :: min_ice(lensfc)
340 
341  REAL :: SLMASK(LENSFC), OROG(LENSFC)
342  REAL :: SIHFCS(LENSFC), SICFCS(LENSFC)
343  REAL :: SITFCS(LENSFC), TSFFCS(LENSFC)
344  REAL :: SWEFCS(LENSFC), ZORFCS(LENSFC)
345  REAL :: ALBFCS(LENSFC,4), TG3FCS(LENSFC)
346  REAL :: CNPFCS(LENSFC), SMCFCS(LENSFC,LSOIL)
347  REAL :: STCFCS(LENSFC,LSOIL), SLIFCS(LENSFC)
348  REAL :: AISFCS(LENSFC), F10M(LENSFC)
349  REAL :: VEGFCS(LENSFC), VETFCS(LENSFC)
350  REAL :: SOTFCS(LENSFC), ALFFCS(LENSFC,2)
351  REAL :: CVFCS(LENSFC), CVTFCS(LENSFC)
352  REAL :: CVBFCS(LENSFC), TPRCP(LENSFC)
353  REAL :: SRFLAG(LENSFC), SNDFCS(LENSFC)
354  REAL :: SLCFCS(LENSFC,LSOIL), VMXFCS(LENSFC)
355  REAL :: VMNFCS(LENSFC), T2M(LENSFC)
356  REAL :: Q2M(LENSFC), SLPFCS(LENSFC)
357  REAL :: ABSFCS(LENSFC), OROG_UF(LENSFC)
358  REAL :: USTAR(LENSFC)
359  REAL :: FMM(LENSFC), FHH(LENSFC)
360  REAL :: RLA(LENSFC), RLO(LENSFC)
361  REAL(KIND=4) :: ZSOIL(LSOIL)
362  REAL :: SIG1T(LENSFC)
365  REAL, ALLOCATABLE :: STC_BCK(:,:), SMC_BCK(:,:), SLC_BCK(:,:)
366  REAL, ALLOCATABLE :: SLIFCS_FG(:)
367  INTEGER, ALLOCATABLE :: LANDINC_MASK_FG(:), LANDINC_MASK(:)
368  REAL, ALLOCATABLE :: SND_BCK(:), SND_INC(:), SWE_BCK(:)
369  REAL(KIND=KIND_IO8), ALLOCATABLE :: SLMASKL(:), SLMASKW(:)
370 
371  TYPE(NSST_DATA) :: NSST
372  real, dimension(idim,jdim) :: tf_clm,tf_trd,sal_clm
373  real, dimension(lensfc) :: tf_clm_tile,tf_trd_tile,sal_clm_tile
374  INTEGER :: veg_type_landice
375  INTEGER, DIMENSION(LENSFC) :: STC_UPDATED, SLC_UPDATED
376 
377  LOGICAL :: FILE_EXISTS, DO_SOI_INC, DO_SNO_INC
378 
379 !--------------------------------------------------------------------------------
380 ! NST_FILE is the path/name of the gaussian GSI file which contains NSST
381 ! increments.
382 !--------------------------------------------------------------------------------
383 
384  NAMELIST/namsfcd/ nst_file, lnd_soi_file, do_sno_inc
385 
386  DATA nst_file/'NULL'/
387  DATA lnd_soi_file/'NULL'/
388 
389  do_sno_inc = .false.
390  do_soi_inc = .false.
391 
392 
393  sig1t = 0.0 ! Not a dead start!
394 
395  input_nml_file = "NULL"
396 
397  CALL baopenr(37, "fort.37", ierr)
398  READ (37, nml=namsfcd)
399 
400  print*
401  print*,'IN ROUTINE SFCDRV,IDIM=',idim,'JDIM=',jdim,'FH=',fh
402 
403 !--------------------------------------------------------------------------------
404 ! READ THE OROGRAPHY AND GRID POINT LAT/LONS FOR THE CUBED-SPHERE TILE.
405 !--------------------------------------------------------------------------------
406 
407  CALL read_lat_lon_orog(rla,rlo,orog,orog_uf,tile_num,idim,jdim,lensfc)
408 
409  DO i = 1, idim
410  idum(i,:) = i
411  ENDDO
412 
413  i_index = reshape(idum, (/lensfc/))
414 
415  DO i = 1, jdim
416  idum(:,i) = i
417  ENDDO
418 
419  j_index = reshape(idum, (/lensfc/) )
420 
421  IF (do_nsst) THEN
422  print*
423  print*,"WILL PROCESS NSST RECORDS."
424  ALLOCATE(nsst%C_0(lensfc))
425  ALLOCATE(nsst%C_D(lensfc))
426  ALLOCATE(nsst%D_CONV(lensfc))
427  ALLOCATE(nsst%DT_COOL(lensfc))
428  ALLOCATE(nsst%IFD(lensfc))
429  ALLOCATE(nsst%QRAIN(lensfc))
430  ALLOCATE(nsst%TREF(lensfc))
431  ALLOCATE(nsst%TFINC(lensfc))
432  ALLOCATE(nsst%W_0(lensfc))
433  ALLOCATE(nsst%W_D(lensfc))
434  ALLOCATE(nsst%XS(lensfc))
435  ALLOCATE(nsst%XT(lensfc))
436  ALLOCATE(nsst%XTTS(lensfc))
437  ALLOCATE(nsst%XU(lensfc))
438  ALLOCATE(nsst%XV(lensfc))
439  ALLOCATE(nsst%XZ(lensfc))
440  ALLOCATE(nsst%XZTS(lensfc))
441  ALLOCATE(nsst%Z_C(lensfc))
442  ALLOCATE(nsst%ZM(lensfc))
443  ALLOCATE(slifcs_fg(lensfc))
444  ENDIF
445 
446 IF (do_lndinc) THEN
447  ! identify variables to be updates, and allocate arrays.
448  IF (trim(lnd_soi_file) .NE. "NULL") THEN
449  do_soi_inc = .true.
450  print*
451  print*," APPLYING SOIL INCREMENTS FROM THE GSI"
452  ALLOCATE(stc_bck(lensfc, lsoil), smc_bck(lensfc, lsoil), slc_bck(lensfc,lsoil))
453  ALLOCATE(landinc_mask_fg(lensfc))
454  ENDIF
455  ! FOR NOW, CODE SO CAN DO BOTH, BUT MIGHT NEED TO THINK ABOUT THIS SOME MORE.
456  IF (do_sno_inc) THEN
457  ! ideally, would check here that sfcsub snow DA update is not also requested
458  ! but latter is controlled by fnsol, which is read in within that routine.
459  ! should be done at script level.
460  print*
461  print*," APPLYING SNOW INCREMENTS FROM JEDI"
462  ALLOCATE(snd_bck(lensfc), snd_inc(lensfc), swe_bck(lensfc))
463  ENDIF
464  ! set-up land mask info
465  ALLOCATE(landinc_mask(lensfc))
466  if (ivegsrc == 2) then ! sib
467  veg_type_landice=13
468  else
469  veg_type_landice=15
470  endif
471 ENDIF
472 
473 !--------------------------------------------------------------------------------
474 ! READ THE INPUT SURFACE DATA ON THE CUBED-SPHERE TILE.
475 !--------------------------------------------------------------------------------
476 
477  CALL read_data(lsoil,lensfc,do_nsst,.false.,is_noahmp=is_noahmp, &
478  tsffcs=tsffcs,smcfcs=smcfcs, &
479  swefcs=swefcs,stcfcs=stcfcs,tg3fcs=tg3fcs,zorfcs=zorfcs, &
480  cvfcs=cvfcs, cvbfcs=cvbfcs,cvtfcs=cvtfcs,albfcs=albfcs, &
481  vegfcs=vegfcs,slifcs=slifcs,cnpfcs=cnpfcs,f10m=f10m , &
482  vetfcs=vetfcs,sotfcs=sotfcs,alffcs=alffcs,ustar=ustar , &
483  fmm=fmm ,fhh=fhh ,sihfcs=sihfcs,sicfcs=sicfcs, &
484  sitfcs=sitfcs,tprcp=tprcp ,srflag=srflag,sndfcs=sndfcs, &
485  vmnfcs=vmnfcs,vmxfcs=vmxfcs,slcfcs=slcfcs,slpfcs=slpfcs, &
486  absfcs=absfcs,t2m=t2m ,q2m=q2m ,slmask=slmask, &
487  zsoil=zsoil, nsst=nsst)
488 
489  IF (is_noahmp) THEN
490  lsm=lsm_noahmp
491  ELSE
492  lsm=lsm_noah
493  ENDIF
494 
495  IF (use_ufo) THEN
496  print*
497  print*,'USE UNFILTERED OROGRAPHY.'
498  ELSE
499  orog_uf = 0.0
500  ENDIF
501 
502  DO i=1,lensfc
503  aisfcs(i) = 0.
504  IF(nint(slifcs(i)).EQ.2) aisfcs(i) = 1.
505  ENDDO
506 
507  IF (do_nsst) THEN
508  IF (.NOT. do_sfccycle ) THEN
509  print*
510  print*,"FIRST GUESS MASK ADJUSTED BY IFD RECORD"
511  slifcs_fg = slifcs
512  WHERE(nint(nsst%IFD) == 3) slifcs_fg = 2.0
513  ELSE
514  print*
515  print*,"SAVE FIRST GUESS MASK"
516  slifcs_fg = slifcs
517  ENDIF
518  ENDIF
519 
520  ! CALCULATE MASK FOR LAND INCREMENTS
521  IF (do_lndinc) &
522  CALL calculate_landinc_mask(smcfcs(:,1),swefcs, vetfcs, &
523  lensfc,veg_type_landice, landinc_mask)
524 
525 !--------------------------------------------------------------------------------
526 ! UPDATE SURFACE FIELDS.
527 !
528 ! FIRST, SET WATER AND LAND MASKS - SLMASKW/SLMASKL. FOR UNCOUPLED
529 ! (NON-FRACTIONAL) MODE, THESE ARE IDENTICAL TO THE CURRENT
530 ! MASK - '0' WATER; '1' LAND.
531 !--------------------------------------------------------------------------------
532 
533  IF (do_sfccycle) THEN
534  ALLOCATE(slmaskl(lensfc), slmaskw(lensfc))
535 ! for running uncoupled (non-fractional grid)
536  DO i=1,lensfc
537  IF(nint(slmask(i)) == 1) THEN
538  slmaskl(i) = 1.0_kind_io8
539  slmaskw(i) = 1.0_kind_io8
540  ELSE
541  slmaskl(i) = 0.0_kind_io8
542  slmaskw(i) = 0.0_kind_io8
543  ENDIF
544  if(nint(slmask(i)) == 0) then
545  min_ice(i) = 0.15_kind_io8
546  else
547  min_ice(i) = 0.0_kind_io8
548  endif
549  ENDDO
550  num_threads = num_parthds()
551  print*
552  print*,"CALL SFCCYCLE TO UPDATE SURFACE FIELDS."
553  CALL sfccycle(lugb,lensfc,lsoil,sig1t,deltsfc, &
554  iy,im,id,ih,fh,rla,rlo, &
555  slmaskl,slmaskw, orog, orog_uf, use_ufo, do_nsst, &
556  sihfcs,sicfcs,sitfcs,sndfcs,slcfcs, &
557  vmnfcs,vmxfcs,slpfcs,absfcs, &
558  tsffcs,swefcs,zorfcs,albfcs,tg3fcs, &
559  cnpfcs,smcfcs,stcfcs,slifcs,aisfcs, &
560  vegfcs,vetfcs,sotfcs,alffcs, &
561  cvfcs,cvbfcs,cvtfcs,myrank,num_threads, nlunit, &
562  sz_nml, input_nml_file, &
563  min_ice, &
564  ialb,isot,ivegsrc,tile_num,i_index,j_index)
565  DEALLOCATE(slmaskl, slmaskw)
566  ENDIF
567 
568 !--------------------------------------------------------------------------------
569 ! IF RUNNING WITH NSST, READ IN GSI FILE WITH THE UPDATED INCREMENTS (ON THE
570 ! GAUSSIAN GRID), INTERPOLATE INCREMENTS TO THE CUBED-SPHERE TILE, AND PERFORM
571 ! REQUIRED ADJUSTMENTS AND QC.
572 !--------------------------------------------------------------------------------
573 
574  IF (do_nsst) THEN
575  IF (nst_file == "NULL") THEN
576  print*
577  print*,"NO GSI FILE. ADJUST IFD FOR FORMER ICE POINTS."
578  DO i = 1, lensfc
579  IF (nint(slifcs_fg(i)) == 2 .AND. nint(slifcs(i)) == 0) THEN
580  nsst%IFD(i) = 3.0
581  ENDIF
582  ENDDO
583  nsst%TFINC = 0.0
584  ELSE
585  print*
586  print*,"ADJUST TREF FROM GSI INCREMENT"
587 !
588 ! Get tf climatology at the time
589 !
590  call get_tf_clm(rla,rlo,jdim,idim,iy,im,id,ih,tf_clm,tf_trd)
591  tf_clm_tile(:) = reshape(tf_clm, (/lensfc/) )
592  tf_trd_tile(:) = reshape(tf_trd, (/lensfc/) )
593 !
594 ! Get salinity climatology at the time
595 !
596  call get_sal_clm(rla,rlo,jdim,idim,iy,im,id,ih,sal_clm)
597  sal_clm_tile(:) = reshape(sal_clm, (/lensfc/) )
598 !
599 ! read tf analysis increment generated by GSI
600 !
601  CALL read_gsi_data(nst_file, 'NST')
602 !
603 ! update foundation & surface temperature for NSST
604 !
605  CALL adjust_nsst(rla,rlo,slifcs,slifcs_fg,tsffcs,sitfcs,sicfcs,stcfcs, &
606  nsst,lensfc,lsoil,idim,jdim,zsea1,zsea2,im,id,deltsfc, &
607  tf_clm_tile,tf_trd_tile,sal_clm_tile)
608  ENDIF
609  ENDIF
610 
611 !--------------------------------------------------------------------------------
612 ! READ IN AND APPLY LAND INCREMENTS FROM THE GSI
613 !--------------------------------------------------------------------------------
614 
615  IF (do_lndinc) THEN
616 
617  ! SNOW INCREMENTS
618  ! do snow first, as temperature updates will use snow analaysis
619  IF (do_sno_inc) THEN
620  ! updates are made to snow depth only over land (and not-land ice).
621  ! SWE is then updated from the snow depth analysis, using the model
622  ! forecast density
623 
624  !--------------------------------------------------------------------------------
625  ! read increments in
626  !--------------------------------------------------------------------------------
627 
628  ! Only coded for DA on native model grid (would always be the case for cycling DA)
629  CALL read_data(lsoil,lensfc,.false.,.true.,sndfcs=snd_inc)
630 
631  !--------------------------------------------------------------------------------
632  ! add increments to state vars
633  !--------------------------------------------------------------------------------
634 
635  ! store background states
636  snd_bck = sndfcs
637  swe_bck = swefcs
638 
639  CALL add_increment_snow(snd_inc,landinc_mask,lensfc,sndfcs)
640 
641  !--------------------------------------------------------------------------------
642  ! make any necessary adjustments to dependent variables
643  !--------------------------------------------------------------------------------
644 
645  CALL apply_land_da_adjustments_snd(lsm, lensfc, landinc_mask, swe_bck, snd_bck, &
646  sndfcs, swefcs)
647 
648  ENDIF
649 
650  ! SOIL INCREMENTS
651  IF (do_soi_inc) THEN
652 
653  !--------------------------------------------------------------------------------
654  ! re-calculate soilsnow mask if snow has been updated.
655  !--------------------------------------------------------------------------------
656 
657  landinc_mask_fg = landinc_mask
658 
659  IF (do_sfccycle .OR. do_sno_inc) THEN
660  CALL calculate_landinc_mask(smcfcs(:,1),swefcs, vetfcs, lensfc, &
661  veg_type_landice, landinc_mask )
662  ENDIF
663 
664  !--------------------------------------------------------------------------------
665  ! read increments in
666  !--------------------------------------------------------------------------------
667 
668  INQUIRE(file=trim(lnd_soi_file), exist=file_exists)
669  IF (.not. file_exists) then
670  print *, 'FATAL ERROR: land increment update requested, but file does not exist: ', &
671  trim(lnd_soi_file)
672  call mpi_abort(mpi_comm_world, 10, ierr)
673  ENDIF
674 
675  CALL read_gsi_data(lnd_soi_file, 'LND', lsoil=lsoil)
676 
677  !--------------------------------------------------------------------------------
678  ! add increments to state vars
679  !--------------------------------------------------------------------------------
680  ! when applying increments, will often need to adjust other land states in response
681  ! to the changes made. Need to store bacground, apply the increments, then make
682  ! secondart adjustments. When updating more than one state, be careful about the
683  ! order if increments and secondary adjustments.
684 
685  ! store background states
686  stc_bck = stcfcs
687  smc_bck = smcfcs
688  slc_bck = slcfcs
689 
690  ! below updates [STC/SMC/STC]FCS to hold the analysis
691  CALL add_increment_soil(rla,rlo,stcfcs,smcfcs,slcfcs,stc_updated, slc_updated, &
692  landinc_mask,landinc_mask_fg,lensfc,lsoil,idim,jdim,lsm,myrank)
693 
694  !--------------------------------------------------------------------------------
695  ! make any necessary adjustments to dependent variables
696  !--------------------------------------------------------------------------------
697 
698 
699  CALL apply_land_da_adjustments_soil(lsm, isot, ivegsrc,lensfc, lsoil, &
700  sotfcs, landinc_mask_fg, stc_bck, stcfcs, smcfcs, slcfcs, stc_updated, &
701  slc_updated,zsoil)
702 
703  ENDIF ! soil increments
704 
705 !--------------------------------------------------------------------------------
706 ! clean up
707 !--------------------------------------------------------------------------------
708 
709  ! to do - save and write out STC_INC? (soil temperature increments)
710  IF(ALLOCATED(landinc_mask_fg)) DEALLOCATE(landinc_mask_fg)
711  IF(ALLOCATED(landinc_mask)) DEALLOCATE(landinc_mask)
712  IF(ALLOCATED(stc_bck)) DEALLOCATE(stc_bck)
713  IF(ALLOCATED(smc_bck)) DEALLOCATE(smc_bck)
714  IF(ALLOCATED(slc_bck)) DEALLOCATE(slc_bck)
715  IF(ALLOCATED(snd_bck)) DEALLOCATE(snd_bck)
716  IF(ALLOCATED(swe_bck)) DEALLOCATE(swe_bck)
717  IF(ALLOCATED(snd_inc)) DEALLOCATE(snd_inc)
718 
719  ENDIF
720 !--------------------------------------------------------------------------------
721 ! WRITE OUT UPDATED SURFACE DATA ON THE CUBED-SPHERE TILE.
722 !--------------------------------------------------------------------------------
723 
724  IF (lsm==lsm_noahmp) THEN
725 
726  CALL write_data(lensfc,idim,jdim,lsoil,do_nsst,nsst,vegfcs=vegfcs, &
727  slcfcs=slcfcs,smcfcs=smcfcs,stcfcs=stcfcs)
728 
729  ELSEIF (lsm==lsm_noah) THEN
730 
731  CALL write_data(lensfc,idim,jdim,lsoil, &
732  do_nsst,nsst,slifcs=slifcs,tsffcs=tsffcs,vegfcs=vegfcs, &
733  swefcs=swefcs,tg3fcs=tg3fcs,zorfcs=zorfcs, &
734  albfcs=albfcs,alffcs=alffcs,cnpfcs=cnpfcs, &
735  f10m=f10m,t2m=t2m,q2m=q2m,vetfcs=vetfcs, &
736  sotfcs=sotfcs,ustar=ustar,fmm=fmm,fhh=fhh, &
737  sicfcs=sicfcs,sihfcs=sihfcs,sitfcs=sitfcs,tprcp=tprcp, &
738  srflag=srflag,swdfcs=sndfcs,vmnfcs=vmnfcs, &
739  vmxfcs=vmxfcs,slpfcs=slpfcs,absfcs=absfcs, &
740  slcfcs=slcfcs,smcfcs=smcfcs,stcfcs=stcfcs)
741 
742  ENDIF
743 
744  IF (do_nsst) THEN
745  DEALLOCATE(nsst%C_0)
746  DEALLOCATE(nsst%C_D)
747  DEALLOCATE(nsst%D_CONV)
748  DEALLOCATE(nsst%DT_COOL)
749  DEALLOCATE(nsst%IFD)
750  DEALLOCATE(nsst%QRAIN)
751  DEALLOCATE(nsst%TREF)
752  DEALLOCATE(nsst%TFINC)
753  DEALLOCATE(nsst%W_0)
754  DEALLOCATE(nsst%W_D)
755  DEALLOCATE(nsst%XS)
756  DEALLOCATE(nsst%XT)
757  DEALLOCATE(nsst%XTTS)
758  DEALLOCATE(nsst%XU)
759  DEALLOCATE(nsst%XV)
760  DEALLOCATE(nsst%XZ)
761  DEALLOCATE(nsst%XZTS)
762  DEALLOCATE(nsst%Z_C)
763  DEALLOCATE(nsst%ZM)
764  DEALLOCATE(slifcs_fg)
765  ENDIF
766 
767  RETURN
768 
769  END SUBROUTINE sfcdrv
770 
802  SUBROUTINE adjust_nsst(RLA,RLO,SLMSK_TILE,SLMSK_FG_TILE,SKINT_TILE,&
803  SICET_TILE,sice_tile,SOILT_TILE,NSST,LENSFC,LSOIL, &
804  IDIM,JDIM,ZSEA1,ZSEA2,MON,DAY,DELTSFC, &
805  tf_clm_tile,tf_trd_tile,sal_clm_tile)
807  USE utils
808  USE gdswzd_mod
809  USE read_write_data, ONLY : idim_gaus, jdim_gaus, &
810  slmsk_gaus, dtref_gaus, &
811  nsst_data
812 
813  USE mpi
814 
815  IMPLICIT NONE
816 
817  INTEGER, INTENT(IN) :: LENSFC, LSOIL, IDIM, JDIM, MON, DAY
818 
819  REAL, INTENT(IN) :: SLMSK_TILE(LENSFC), SLMSK_FG_TILE(LENSFC)
820  real, intent(in) :: tf_clm_tile(lensfc),tf_trd_tile(lensfc),sal_clm_tile(lensfc)
821  REAL, INTENT(IN) :: ZSEA1, ZSEA2, DELTSFC
822  REAL, INTENT(INOUT) :: RLA(LENSFC), RLO(LENSFC), SKINT_TILE(LENSFC)
823  REAL, INTENT(INOUT) :: SICET_TILE(LENSFC),sice_tile(lensfc),SOILT_TILE(LENSFC,LSOIL)
824 
825  TYPE(NSST_DATA) :: NSST
826 
827  REAL, PARAMETER :: TMAX=313.0,tzero=273.16
828 
829  INTEGER :: IOPT, NRET, KGDS_GAUS(200)
830  INTEGER :: IGAUS, JGAUS, IJ, II, JJ, III, JJJ, KRAD
831  INTEGER :: ISTART, IEND, JSTART, JEND
832  INTEGER :: MASK_TILE, MASK_FG_TILE
833  INTEGER :: ITILE, JTILE
834  INTEGER :: MAX_SEARCH, J, IERR
835  INTEGER :: IGAUSP1, JGAUSP1
836  integer :: nintp,nsearched,nice,nland
837  integer :: nfill,nfill_tice,nfill_clm
838  integer :: nset_thaw,nset_thaw_s,nset_thaw_i,nset_thaw_c
839 
840  INTEGER, ALLOCATABLE :: ID1(:,:), ID2(:,:), JDC(:,:)
841 
842  LOGICAL :: IS_ICE
843 
844  real :: tfreez
845  REAL :: TREF_SAVE,WSUM,tf_ice,tf_thaw
846  REAL :: FILL, DTZM, GAUS_RES_KM, DTREF
847  REAL, ALLOCATABLE :: XPTS(:), YPTS(:), LATS(:), LONS(:)
848  REAL, ALLOCATABLE :: DUM2D(:,:), LATS_RAD(:), LONS_RAD(:)
849  REAL, ALLOCATABLE :: AGRID(:,:,:), S2C(:,:,:)
850 
851  kgds_gaus = 0
852  kgds_gaus(1) = 4 ! OCT 6 - TYPE OF GRID (GAUSSIAN)
853  kgds_gaus(2) = idim_gaus ! OCT 7-8 - # PTS ON LATITUDE CIRCLE
854  kgds_gaus(3) = jdim_gaus
855  kgds_gaus(4) = 90000 ! OCT 11-13 - LAT OF ORIGIN
856  kgds_gaus(5) = 0 ! OCT 14-16 - LON OF ORIGIN
857  kgds_gaus(6) = 128 ! OCT 17 - RESOLUTION FLAG
858  kgds_gaus(7) = -90000 ! OCT 18-20 - LAT OF EXTREME POINT
859  kgds_gaus(8) = nint(-360000./float(idim_gaus)) ! OCT 21-23 - LON OF EXTREME POINT
860  kgds_gaus(9) = nint((360.0 / float(idim_gaus))*1000.0)
861  ! OCT 24-25 - LONGITUDE DIRECTION INCR.
862  kgds_gaus(10) = jdim_gaus/2 ! OCT 26-27 - NUMBER OF CIRCLES POLE TO EQUATOR
863  kgds_gaus(12) = 255 ! OCT 29 - RESERVED
864  kgds_gaus(20) = 255 ! OCT 5 - NOT USED, SET TO 255
865 
866  print*
867  print*,'ADJUST NSST USING GSI INCREMENTS ON GAUSSIAN GRID'
868 
869 !----------------------------------------------------------------------
870 ! CALL GDSWZD TO COMPUTE THE LAT/LON OF EACH GSI GAUSSIAN GRID POINT.
871 !----------------------------------------------------------------------
872 
873  iopt = 0
874  fill = -9999.
875  ALLOCATE(xpts(idim_gaus*jdim_gaus))
876  ALLOCATE(ypts(idim_gaus*jdim_gaus))
877  ALLOCATE(lats(idim_gaus*jdim_gaus))
878  ALLOCATE(lons(idim_gaus*jdim_gaus))
879  xpts = fill
880  ypts = fill
881  lats = fill
882  lons = fill
883 
884  CALL gdswzd(kgds_gaus,iopt,(idim_gaus*jdim_gaus),fill,xpts,ypts,lons,lats,nret)
885 
886  IF (nret /= (idim_gaus*jdim_gaus)) THEN
887  print*,'FATAL ERROR: PROBLEM IN GDSWZD. STOP.'
888  CALL mpi_abort(mpi_comm_world, 12, ierr)
889  ENDIF
890 
891  DEALLOCATE (xpts, ypts)
892 
893  ALLOCATE(dum2d(idim_gaus,jdim_gaus))
894  dum2d = reshape(lats, (/idim_gaus,jdim_gaus/) )
895  DEALLOCATE(lats)
896 
897  ALLOCATE(lats_rad(jdim_gaus))
898  DO j = 1, jdim_gaus
899  lats_rad(j) = dum2d(1,jdim_gaus-j+1) * 3.1415926 / 180.0
900  ENDDO
901 
902  dum2d = reshape(lons, (/idim_gaus,jdim_gaus/) )
903  DEALLOCATE(lons)
904  ALLOCATE(lons_rad(idim_gaus))
905  lons_rad = dum2d(:,1) * 3.1415926 / 180.0
906 
907  DEALLOCATE(dum2d)
908 
909  ALLOCATE(agrid(idim,jdim,2))
910  agrid(:,:,1) = reshape(rlo, (/idim,jdim/) )
911  agrid(:,:,2) = reshape(rla, (/idim,jdim/) )
912  agrid = agrid * 3.1415926 / 180.0
913 
914  ALLOCATE(id1(idim,jdim))
915  ALLOCATE(id2(idim,jdim))
916  ALLOCATE(jdc(idim,jdim))
917  ALLOCATE(s2c(idim,jdim,4))
918 
919 !----------------------------------------------------------------------
920 ! COMPUTE BILINEAR WEIGHTS FOR EACH MODEL POINT FROM THE NEAREST
921 ! FOUR GSI/GAUSSIAN POINTS. DOES NOT ACCOUNT FOR MASK. THAT
922 ! HAPPENS LATER.
923 !----------------------------------------------------------------------
924 
925  CALL remap_coef( 1, idim, 1, jdim, idim_gaus, jdim_gaus, &
926  lons_rad, lats_rad, id1, id2, jdc, s2c, agrid )
927 
928  DEALLOCATE(lons_rad, lats_rad, agrid)
929 
930 !----------------------------------------------------------------------
931 ! THE MAXIMUM DISTANCE TO SEARCH IS 500 KM. HOW MANY GAUSSIAN
932 ! GRID LENGTHS IS THAT?
933 !----------------------------------------------------------------------
934 
935  gaus_res_km = 360.0 / idim_gaus * 111.0
936  max_search = ceiling(500.0/gaus_res_km)
937 
938  print*
939  print*,'MAXIMUM SEARCH IS ',max_search, ' GAUSSIAN POINTS.'
940  print*
941 
942 !
943 ! Initialize variables for counts statitics to be zeros
944 !
945  nintp = 0
946  nset_thaw = 0
947  nset_thaw_s = 0
948  nset_thaw_i = 0
949  nset_thaw_c = 0
950  nsearched = 0
951  nfill = 0
952  nfill_tice = 0
953  nfill_clm = 0
954  nice = 0
955  nland = 0
956 !----------------------------------------------------------------------
957 ! TREF INCREMENT WILL BE OUTPUT. INITIALIZE TO ZERO.
958 !----------------------------------------------------------------------
959 
960  nsst%TFINC = 0.0
961 
962  ij_loop : DO ij = 1, lensfc
963 
964  mask_tile = nint(slmsk_tile(ij))
965  mask_fg_tile = nint(slmsk_fg_tile(ij))
966 
967 !
968 ! when sea ice exists, get salinity dependent water temperature
969 !
970  tf_ice = tfreez(sal_clm_tile(ij)) + tzero
971 !----------------------------------------------------------------------
972 ! SKIP LAND POINTS. NSST NOT APPLIED AT LAND.
973 !----------------------------------------------------------------------
974 
975  IF (mask_tile == 1) THEN
976  nland = nland + 1
977  cycle ij_loop
978  ENDIF
979 
980 !
981 ! these are ice points. set tref to tf_ice and update tmpsfc.
982 !
983  if (mask_tile == 2) then
984  nsst%tref(ij)=tf_ice ! water part tmp set
985  skint_tile(ij)=(1.0-sice_tile(ij))*nsst%tref(ij)+sice_tile(ij)*sicet_tile(ij)
986  nice = nice + 1
987  cycle ij_loop
988  endif
989 
990 !
991 ! Get i,j index on array of (idim,jdim) from known ij
992 !
993  jtile = (ij-1) / idim + 1
994  itile = mod(ij,idim)
995  IF (itile==0) itile = idim
996 
997 !----------------------------------------------------------------------
998 ! IF THE MODEL POINT WAS ICE COVERED, BUT IS NOW OPEN WATER, SET
999 ! TREF TO searched adjascent open water onea, if failed the search, set to
1000 ! weighted average of tf_ice and tf_clm. For NSST vars, set xz TO '30' AND ALL OTHER FIELDS TO ZERO.
1001 !----------------------------------------------------------------------
1002 
1003  IF (mask_fg_tile == 2 .AND. mask_tile == 0) THEN
1004 !
1005 ! set background for the thaw (just melted water) situation
1006 !
1007  call tf_thaw_set(nsst%tref,nint(slmsk_fg_tile),itile,jtile,tf_ice,tf_clm_tile(ij),tf_thaw,idim,jdim, &
1008  nset_thaw_s,nset_thaw_i,nset_thaw_c)
1009  call nsst_water_reset(nsst,ij,tf_thaw)
1010  nset_thaw = nset_thaw + 1
1011  ENDIF
1012 
1013 !----------------------------------------------------------------------
1014 ! THESE ARE POINTS THAT ARE OPEN WATER AND WERE OPEN WATER PRIOR
1015 ! TO ANY ICE UPDATE BY SFCCYCLE. UPDATE TREF AND SKIN TEMP.
1016 ! AT OPEN WATER POINTS, THE SEA ICE TEMPERATURE (SICET_TILE) AND
1017 ! SOIL COLUMN TEMPERATURE (SOILT_TILE) ARE SET TO THE SKIN TEMP.
1018 ! IT IS SIMPLY A FILLER VALUE. THESE FIELDS ARE NOT USED AT
1019 ! OPEN WATER POINTS.
1020 !----------------------------------------------------------------------
1021 !----------------------------------------------------------------------
1022 ! SEE IF ANY OF THE NEAREST GSI POINTS MASK AREA OPEN WATER.
1023 ! IF SO, APPLY NSST INCREMENT USING BILINEAR INTERPOLATION.
1024 !----------------------------------------------------------------------
1025 
1026  igaus = id1(itile,jtile)
1027  jgaus = jdc(itile,jtile)
1028  igausp1 = id2(itile,jtile)
1029  jgausp1 = jdc(itile,jtile)+1
1030 
1031  IF (slmsk_gaus(igaus,jgaus) == 0 .OR. &
1032  slmsk_gaus(igausp1,jgaus) == 0 .OR. &
1033  slmsk_gaus(igausp1,jgausp1) == 0 .OR. &
1034  slmsk_gaus(igaus,jgausp1) == 0) THEN
1035 
1036  dtref = 0.0
1037  wsum = 0.0
1038 
1039  IF (slmsk_gaus(igaus,jgaus) == 0) THEN
1040  dtref = dtref + (s2c(itile,jtile,1) * dtref_gaus(igaus,jgaus))
1041  wsum = wsum + s2c(itile,jtile,1)
1042  ENDIF
1043 
1044  IF (slmsk_gaus(igausp1,jgaus) == 0) THEN
1045  dtref = dtref + (s2c(itile,jtile,2) * dtref_gaus(igausp1,jgaus))
1046  wsum = wsum + s2c(itile,jtile,2)
1047  ENDIF
1048 
1049  IF (slmsk_gaus(igausp1,jgausp1) == 0) THEN
1050  dtref = dtref + (s2c(itile,jtile,3) * dtref_gaus(igausp1,jgausp1))
1051  wsum = wsum + s2c(itile,jtile,3)
1052  ENDIF
1053 
1054  IF (slmsk_gaus(igaus,jgausp1) == 0) THEN
1055  dtref = dtref + (s2c(itile,jtile,4) * dtref_gaus(igaus,jgausp1))
1056  wsum = wsum + s2c(itile,jtile,4)
1057  ENDIF
1058 
1059  nintp = nintp + 1
1060  dtref = dtref / wsum
1061 
1062  tref_save = nsst%TREF(ij)
1063  nsst%TREF(ij) = nsst%TREF(ij) + dtref
1064  nsst%TREF(ij) = max(nsst%TREF(ij), tf_ice)
1065  nsst%TREF(ij) = min(nsst%TREF(ij), tmax)
1066  nsst%TFINC(ij) = nsst%TREF(ij) - tref_save
1067 
1068  CALL dtzm_point(nsst%XT(ij),nsst%XZ(ij),nsst%DT_COOL(ij), &
1069  nsst%Z_C(ij),zsea1,zsea2,dtzm)
1070 
1071  skint_tile(ij) = nsst%TREF(ij) + dtzm
1072  skint_tile(ij) = max(skint_tile(ij), tf_ice)
1073  skint_tile(ij) = min(skint_tile(ij), tmax)
1074 
1075  sicet_tile(ij) = skint_tile(ij)
1076  soilt_tile(ij,:) = skint_tile(ij)
1077 
1078 !----------------------------------------------------------------------
1079 ! NO NEARBY GSI/GAUSSIAN OPEN WATER POINTS. PERFORM A SPIRAL SEARCH TO
1080 ! FIND NEAREST NON-LAND POINT ON GSI/GAUSSIAN GRID.
1081 !----------------------------------------------------------------------
1082 
1083  ELSE
1084 
1085  is_ice = .false.
1086 
1087  DO krad = 1, max_search
1088 
1089  istart = igaus - krad
1090  iend = igaus + krad
1091  jstart = jgaus - krad
1092  jend = jgaus + krad
1093 
1094  DO jj = jstart, jend
1095  DO ii = istart, iend
1096 
1097  IF((jj == jstart) .OR. (jj == jend) .OR. &
1098  (ii == istart) .OR. (ii == iend)) THEN
1099 
1100  IF ((jj >= 1) .AND. (jj <= jdim_gaus)) THEN
1101 
1102  jjj = jj
1103  IF (ii <= 0) THEN
1104  iii = idim_gaus + ii
1105  ELSE IF (ii >= (idim_gaus+1)) THEN
1106  iii = ii - idim_gaus
1107  ELSE
1108  iii = ii
1109  END IF
1110 
1111 !----------------------------------------------------------------------
1112 ! SEE IF NEARBY POINTS ARE SEA ICE. IF THEY ARE, AND THE SEARCH FOR
1113 ! A GAUSSIAN GRID OPEN WATER POINT FAILS, THEN TREF WILL BE SET TO
1114 ! FREEZING BELOW.
1115 !----------------------------------------------------------------------
1116 
1117  IF (krad <= 2 .AND. slmsk_gaus(iii,jjj) == 2) is_ice = .true.
1118 
1119  IF (slmsk_gaus(iii,jjj) == 0) THEN
1120 
1121 ! PRINT*,'MISMATCH AT TILE POINT ',ITILE,JTILE
1122 ! PRINT*,'UPDATE TREF USING GSI INCREMENT AT ',III,JJJ,DTREF_GAUS(III,JJJ)
1123  nsearched = nsearched + 1
1124 
1125  tref_save = nsst%TREF(ij)
1126  nsst%TREF(ij ) = nsst%TREF(ij) + dtref_gaus(iii,jjj)
1127  nsst%TREF(ij) = max(nsst%TREF(ij), tf_ice)
1128  nsst%TREF(ij) = min(nsst%TREF(ij), tmax)
1129  nsst%TFINC(ij) = nsst%TREF(ij) - tref_save
1130 
1131  CALL dtzm_point(nsst%XT(ij),nsst%XZ(ij),nsst%DT_COOL(ij), &
1132  nsst%Z_C(ij),zsea1,zsea2,dtzm)
1133 
1134  skint_tile(ij) = nsst%TREF(ij) + dtzm
1135  skint_tile(ij) = max(skint_tile(ij), tf_ice)
1136  skint_tile(ij) = min(skint_tile(ij), tmax)
1137 
1138  sicet_tile(ij) = skint_tile(ij)
1139  soilt_tile(ij,:) = skint_tile(ij)
1140  cycle ij_loop
1141 
1142  ENDIF ! GSI/Gaussian mask is open water
1143 
1144  ENDIF
1145 
1146  ENDIF
1147 
1148  ENDDO
1149  ENDDO
1150 
1151  ENDDO ! KRAD LOOP
1152 
1153 !----------------------------------------------------------------------
1154 ! THE SEARCH FAILED. IF THERE IS NEARBY ICE, SET TREF TO FREEZING.
1155 ! ELSE UPDATE TREF BASED ON THE ANNUAL SST CYCLE.
1156 !----------------------------------------------------------------------
1157 
1158 ! PRINT*,'WARNING !!!!!! SEARCH FAILED AT TILE POINT ',ITILE,JTILE
1159 
1160  nfill = nfill + 1
1161  IF (is_ice) THEN
1162  nsst%TREF(ij) = tf_ice
1163 ! PRINT*,"NEARBY ICE. SET TREF TO FREEZING"
1164  nfill_tice = nfill_tice + 1
1165  ELSE
1166  tref_save = nsst%TREF(ij)
1167  nsst%TREF(ij) = nsst%TREF(ij) + tf_trd_tile(ij)
1168  nsst%TREF(ij) = max(nsst%TREF(ij), tf_ice)
1169  nsst%TREF(ij) = min(nsst%TREF(ij), tmax)
1170  nsst%TFINC(ij) = nsst%TREF(ij) - tref_save
1171 ! PRINT*,'UPDATE TREF FROM SST CLIMO ',DTREF
1172  nfill_clm = nfill_clm + 1
1173  ENDIF
1174 
1175  CALL dtzm_point(nsst%XT(ij),nsst%XZ(ij),nsst%DT_COOL(ij), &
1176  nsst%Z_C(ij),zsea1,zsea2,dtzm)
1177 
1178  skint_tile(ij) = nsst%TREF(ij) + dtzm
1179  skint_tile(ij) = max(skint_tile(ij), tf_ice)
1180  skint_tile(ij) = min(skint_tile(ij), tmax)
1181 
1182  sicet_tile(ij) = skint_tile(ij)
1183  soilt_tile(ij,:) = skint_tile(ij)
1184 
1185  ENDIF ! NEARBY GAUSSIAN POINTS ARE OPEN WATER?
1186 
1187  ENDDO ij_loop
1188 
1189  write(*,'(a)') 'statistics of grids number processed for tile : '
1190  write(*,'(a,I8)') ' nintp = ',nintp
1191  write(*,'(a,4I8)') 'nset_thaw,nset_thaw_s,nset_thaw_i,nset_thaw_c =',nset_thaw,nset_thaw_s,nset_thaw_i,nset_thaw_c
1192  write(*,'(a,I8)') ' nsearched = ',nsearched
1193  write(*,'(a,3I6)') ' nfill,nfill_tice,nfill_clm = ',nfill,nfill_tice,nfill_clm
1194  write(*,'(a,I8)') ' nice = ',nice
1195  write(*,'(a,I8)') ' nland = ',nland
1196 
1197  DEALLOCATE(id1, id2, jdc, s2c)
1198 
1199  END SUBROUTINE adjust_nsst
1200 
1211  SUBROUTINE climo_trend(LATITUDE, MON, DAY, DELTSFC, DTREF)
1212  IMPLICIT NONE
1213 
1214  INTEGER, INTENT(IN) :: MON, DAY
1215 
1216  REAL, INTENT(IN) :: LATITUDE, DELTSFC
1217  REAL, INTENT(OUT) :: DTREF
1218 
1219  INTEGER :: NUM_DAYS(12), MON2, MON1
1220 
1221  REAL, TARGET :: SST_80_90(12)
1222  REAL, TARGET :: SST_70_80(12)
1223  REAL, TARGET :: SST_60_70(12)
1224  REAL, TARGET :: SST_50_60(12)
1225  REAL, TARGET :: SST_40_50(12)
1226  REAL, TARGET :: SST_30_40(12)
1227  REAL, TARGET :: SST_20_30(12)
1228  REAL, TARGET :: SST_10_20(12)
1229  REAL, TARGET :: SST_00_10(12)
1230  REAL, TARGET :: SST_M10_00(12)
1231  REAL, TARGET :: SST_M20_M10(12)
1232  REAL, TARGET :: SST_M30_M20(12)
1233  REAL, TARGET :: SST_M40_M30(12)
1234  REAL, TARGET :: SST_M50_M40(12)
1235  REAL, TARGET :: SST_M60_M50(12)
1236  REAL, TARGET :: SST_M70_M60(12)
1237  REAL, TARGET :: SST_M80_M70(12)
1238  REAL, TARGET :: SST_M90_M80(12)
1239 
1240  REAL, POINTER :: SST(:)
1241 
1242  DATA num_days /31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/
1243 
1244  DATA sst_80_90 /271.466, 271.458, 271.448, 271.445, 271.519, 271.636, &
1245  272.023, 272.066, 272.001, 271.698, 271.510, 271.472/
1246 
1247  DATA sst_70_80 /272.149, 272.103, 272.095, 272.126, 272.360, 272.988, &
1248  274.061, 274.868, 274.415, 273.201, 272.468, 272.268/
1249 
1250  DATA sst_60_70 /274.240, 274.019, 273.988, 274.185, 275.104, 276.875, &
1251  279.005, 280.172, 279.396, 277.586, 275.818, 274.803/
1252 
1253  DATA sst_50_60 /277.277, 276.935, 277.021, 277.531, 279.100, 281.357, &
1254  283.735, 285.171, 284.399, 282.328, 279.918, 278.199/
1255 
1256  DATA sst_40_50 /281.321, 280.721, 280.850, 281.820, 283.958, 286.588, &
1257  289.195, 290.873, 290.014, 287.652, 284.898, 282.735/
1258 
1259  DATA sst_30_40 /289.189, 288.519, 288.687, 289.648, 291.547, 293.904, &
1260  296.110, 297.319, 296.816, 295.225, 292.908, 290.743/
1261 
1262  DATA sst_20_30 /294.807, 294.348, 294.710, 295.714, 297.224, 298.703, &
1263  299.682, 300.127, 300.099, 299.455, 297.953, 296.177/
1264 
1265  DATA sst_10_20 /298.878, 298.720, 299.033, 299.707, 300.431, 300.709, &
1266  300.814, 300.976, 301.174, 301.145, 300.587, 299.694/
1267 
1268  DATA sst_00_10 /300.415, 300.548, 300.939, 301.365, 301.505, 301.141, &
1269  300.779, 300.660, 300.818, 300.994, 300.941, 300.675/
1270 
1271  DATA sst_m10_00 /300.226, 300.558, 300.914, 301.047, 300.645, 299.870, &
1272  299.114, 298.751, 298.875, 299.294, 299.721, 299.989/
1273 
1274  DATA sst_m20_m10 /299.547, 299.985, 300.056, 299.676, 298.841, 297.788, &
1275  296.893, 296.491, 296.687, 297.355, 298.220, 298.964/
1276 
1277  DATA sst_m30_m20 /297.524, 298.073, 297.897, 297.088, 295.846, 294.520, &
1278  293.525, 293.087, 293.217, 293.951, 295.047, 296.363/
1279 
1280  DATA sst_m40_m30 /293.054, 293.765, 293.468, 292.447, 291.128, 289.781, &
1281  288.773, 288.239, 288.203, 288.794, 289.947, 291.553/
1282 
1283  DATA sst_m50_m40 /285.052, 285.599, 285.426, 284.681, 283.761, 282.826, &
1284  282.138, 281.730, 281.659, 281.965, 282.768, 283.961/
1285 
1286  DATA sst_m60_m50 /277.818, 278.174, 277.991, 277.455, 276.824, 276.229, &
1287  275.817, 275.585, 275.560, 275.687, 276.142, 276.968/
1288 
1289  DATA sst_m70_m60 /273.436, 273.793, 273.451, 272.813, 272.349, 272.048, &
1290  271.901, 271.838, 271.845, 271.889, 272.080, 272.607/
1291 
1292  DATA sst_m80_m70 /271.579, 271.578, 271.471, 271.407, 271.392, 271.391, &
1293  271.390, 271.391, 271.394, 271.401, 271.422, 271.486/
1294 
1295  DATA sst_m90_m80 /271.350, 271.350, 271.350, 271.350, 271.350, 271.350, &
1296  271.350, 271.350, 271.350, 271.350, 271.350, 271.350/
1297 
1298  NULLIFY(sst)
1299  IF (latitude > 80.0) THEN
1300  sst => sst_80_90
1301  ELSEIF (latitude > 70.0) THEN
1302  sst => sst_70_80
1303  ELSEIF (latitude > 60.0) THEN
1304  sst => sst_60_70
1305  ELSEIF (latitude > 50.0) THEN
1306  sst => sst_50_60
1307  ELSEIF (latitude > 40.0) THEN
1308  sst => sst_40_50
1309  ELSEIF (latitude > 30.0) THEN
1310  sst => sst_30_40
1311  ELSEIF (latitude > 20.0) THEN
1312  sst => sst_20_30
1313  ELSEIF (latitude > 10.0) THEN
1314  sst => sst_10_20
1315  ELSEIF (latitude > 0.0) THEN
1316  sst => sst_00_10
1317  ELSEIF (latitude > -10.0) THEN
1318  sst => sst_m10_00
1319  ELSEIF (latitude > -20.0) THEN
1320  sst => sst_m20_m10
1321  ELSEIF (latitude > -30.0) THEN
1322  sst => sst_m30_m20
1323  ELSEIF (latitude > -40.0) THEN
1324  sst => sst_m40_m30
1325  ELSEIF (latitude > -50.0) THEN
1326  sst => sst_m50_m40
1327  ELSEIF (latitude > -60.0) THEN
1328  sst => sst_m60_m50
1329  ELSEIF (latitude > -70.0) THEN
1330  sst => sst_m70_m60
1331  ELSEIF (latitude > -80.0) THEN
1332  sst => sst_m80_m70
1333  ELSE
1334  sst => sst_m90_m80
1335  END IF
1336 
1337  IF (day >= 15) THEN
1338  mon2 = mon+1
1339  IF(mon2 == 13) mon2 = 1
1340  mon1 = mon
1341  dtref = (sst(mon2) - sst(mon1)) / num_days(mon1)
1342  ELSE
1343  mon1 = mon - 1
1344  IF (mon1 == 0) mon1=12
1345  mon2 = mon
1346  dtref = (sst(mon2) - sst(mon1)) / num_days(mon1)
1347  ENDIF
1348 
1349  dtref = dtref * (deltsfc / 24.0)
1350 
1351  END SUBROUTINE climo_trend
1352 
1364  SUBROUTINE dtzm_point(XT,XZ,DT_COOL,ZC,Z1,Z2,DTZM)
1365  implicit none
1366 
1367  real, intent(in) :: xt,xz,dt_cool,zc,z1,z2
1368  real, intent(out) :: dtzm
1369 
1370  real, parameter :: zero = 0.0
1371  real, parameter :: one = 1.0
1372  real, parameter :: half = 0.5
1373  real :: dt_warm,dtw,dtc
1374 !
1375 ! get the mean warming in the range of z=z1 to z=z2
1376 !
1377  dtw = zero
1378  if ( xt > zero ) then
1379  dt_warm = (xt+xt)/xz ! Tw(0)
1380  if ( z1 < z2) then
1381  if ( z2 < xz ) then
1382  dtw = dt_warm*(one-(z1+z2)/(xz+xz))
1383  elseif ( z1 < xz .and. z2 >= xz ) then
1384  dtw = half*(one-z1/xz)*dt_warm*(xz-z1)/(z2-z1)
1385  endif
1386  elseif ( z1 == z2 ) then
1387  if ( z1 < xz ) then
1388  dtw = dt_warm*(one-z1/xz)
1389  endif
1390  endif
1391  endif
1392 !
1393 ! get the mean cooling in the range of z=z1 to z=z2
1394 !
1395  dtc = zero
1396  if ( zc > zero ) then
1397  if ( z1 < z2) then
1398  if ( z2 < zc ) then
1399  dtc = dt_cool*(one-(z1+z2)/(zc+zc))
1400  elseif ( z1 < zc .and. z2 >= zc ) then
1401  dtc = half*(one-z1/zc)*dt_cool*(zc-z1)/(z2-z1)
1402  endif
1403  elseif ( z1 == z2 ) then
1404  if ( z1 < zc ) then
1405  dtc = dt_cool*(one-z1/zc)
1406  endif
1407  endif
1408  endif
1409 
1410 !
1411 ! get the mean T departure from Tf in the range of z=z1 to z=z2
1412 !
1413  dtzm = dtw - dtc
1414 
1415  END SUBROUTINE dtzm_point
1416 
1436  subroutine tf_thaw_set(tf_ij,mask_ij,itile,jtile,tice,tclm,tf_thaw,nx,ny, &
1437  nset_thaw_s,nset_thaw_i,nset_thaw_c)
1439  real, dimension(nx*ny), intent(in) :: tf_ij
1440  integer, dimension(nx*ny), intent(in) :: mask_ij
1441  real, intent(in) :: tice,tclm
1442  integer, intent(in) :: itile,jtile,nx,ny
1443  real, intent(out) :: tf_thaw
1444  integer, intent(inout) :: nset_thaw_s,nset_thaw_i,nset_thaw_c
1445 ! Local
1446  real, parameter :: bmiss = -999.0
1447  real, dimension(nx,ny) :: tf
1448  integer, dimension(nx,ny) :: mask
1449  integer :: krad,max_search,istart,iend,jstart,jend
1450  integer :: ii,jj,iii,jjj
1451  logical :: is_ice
1452 
1453  max_search = 2
1454 
1455  mask(:,:) = reshape(mask_ij,(/nx,ny/) )
1456  tf(:,:) = reshape(tf_ij,(/nx,ny/) )
1457 
1458  tf_thaw = bmiss
1459 
1460  do krad = 1, max_search
1461 
1462  istart = itile - krad
1463  iend = itile + krad
1464  jstart = jtile - krad
1465  jend = jtile + krad
1466 
1467  do jj = jstart, jend
1468  do ii = istart, iend
1469 
1470 
1471  if ((jj == jstart) .or. (jj == jend) .or. &
1472  (ii == istart) .or. (ii == iend)) then
1473 
1474  if ((jj >= 1) .and. (jj <= ny)) then
1475  jjj = jj
1476  if (ii <= 0) then
1477  iii = nx + ii
1478  else if (ii >= (nx+1)) then
1479  iii = ii - nx
1480  else
1481  iii = ii
1482  endif
1483 
1484 !----------------------------------------------------------------------
1485 ! SEE IF NEARBY POINTS ARE SEA ICE. IF THEY ARE, AND THE SEARCH FOR
1486 ! A GAUSSIAN GRID OPEN WATER POINT FAILS, THEN TREF WILL BE SET TO
1487 ! FREEZING BELOW.
1488 !----------------------------------------------------------------------
1489  if (krad <= 2 .and. mask(iii,jjj) == 2) is_ice = .true.
1490 
1491  if (mask(iii,jjj) == 0) then
1492  tf_thaw = tf(iii,jjj)
1493  nset_thaw_s = nset_thaw_s + 1
1494  write(*,'(a,I4,2F9.3)') 'nset_thaw_s,tf(iii,jjj),tclm : ',nset_thaw_s,tf(iii,jjj),tclm
1495  go to 100
1496  endif ! tile mask is open water
1497 
1498  endif
1499  endif
1500  enddo
1501  enddo
1502  enddo ! krad loop
1503 
1504  100 continue
1505 
1506  if ( tf_thaw == bmiss ) then
1507  if (is_ice) then
1508  tf_thaw = tice
1509  nset_thaw_i = nset_thaw_i + 1
1510  write(*,'(a,I4,F9.3)') 'nset_thaw_i,tf_ice : ',nset_thaw_i,tice
1511  else
1512  tf_thaw = 0.8*tice+0.2*tclm
1513  nset_thaw_c = nset_thaw_c + 1
1514  write(*,'(a,I4,2F9.3)') 'nset_thaw_c,tf_ice,tclm : ',nset_thaw_c,tice,tclm
1515  endif
1516  endif
1517 
1518  end subroutine tf_thaw_set
1519 
1527  subroutine nsst_water_reset(nsst,ij,tf_thaw)
1528  use read_write_data, only : nsst_data
1529  implicit none
1530 
1531  integer, intent(in) :: ij
1532 
1533  real, intent(in) :: tf_thaw
1534 
1535  type(nsst_data), intent(inout) :: nsst
1536 
1537  nsst%c_0(ij) = 0.0
1538  nsst%c_d(ij) = 0.0
1539  nsst%d_conv(ij) = 0.0
1540  nsst%dt_cool(ij) = 0.0
1541  nsst%ifd(ij) = 0.0
1542  nsst%qrain(ij) = 0.0
1543  nsst%tref(ij) = tf_thaw
1544  nsst%w_0(ij) = 0.0
1545  nsst%w_d(ij) = 0.0
1546  nsst%xs(ij) = 0.0
1547  nsst%xt(ij) = 0.0
1548  nsst%xtts(ij) = 0.0
1549  nsst%xu(ij) = 0.0
1550  nsst%xv(ij) = 0.0
1551  nsst%xz(ij) = 30.0
1552  nsst%xzts(ij) = 0.0
1553  nsst%z_c(ij) = 0.0
1554  nsst%zm(ij) = 0.0
1555 
1556  end subroutine nsst_water_reset
1557 
1573 subroutine get_tf_clm(xlats_ij,xlons_ij,ny,nx,iy,im,id,ih,tf_clm,tf_trd)
1574  use read_write_data, only : get_tf_clm_dim
1575 
1576  implicit none
1577 
1578  real, dimension(nx*ny), intent(in) :: xlats_ij
1579  real, dimension(nx*ny), intent(in) :: xlons_ij
1580  real, dimension(nx,ny), intent(out) :: tf_clm
1581  real, dimension(nx,ny), intent(out) :: tf_trd
1582  integer, intent(in) :: iy,im,id,ih,nx,ny
1583 ! local declare
1584  real, allocatable, dimension(:,:) :: tf_clm0 ! sst climatology at the valid time (nxc,nyc)
1585  real, allocatable, dimension(:,:) :: tf_trd0 ! 6-hourly sst climatology tendency valid at atime (nxc,nyc)
1586  real, allocatable, dimension(:) :: cxlats ! latitudes of sst climatology
1587  real, allocatable, dimension(:) :: cxlons ! longitudes of sst climatology
1588 
1589  real, dimension(nx*ny) :: tf_clm_ij ! sst climatology at target grids (nx*ny)
1590  real, dimension(nx*ny) :: tf_trd_ij ! 6-hourly sst climatology tendency
1591  real :: wei1,wei2
1592  integer :: nxc,nyc,mon1,mon2,i,j
1593  character (len=6), parameter :: fin_tf_clm='sstclm' ! sst climatology file name
1594 !
1595 ! get which two months used and their weights from atime
1596 !
1597  call get_tim_wei(iy,im,id,ih,mon1,mon2,wei1,wei2)
1598 !
1599 ! get the dimensions of the sst climatology & allocate the related arrays
1600 !
1601  call get_tf_clm_dim(fin_tf_clm,nyc,nxc)
1602  allocate( tf_clm0(nxc,nyc),tf_trd0(nxc,nyc),cxlats(nyc),cxlons(nxc) )
1603 !
1604 ! get tf_clm at the analysis time from monthly climatology & cxlats, cxlons
1605 !
1606  call get_tf_clm_ta(tf_clm0,tf_trd0,cxlats,cxlons,nyc,nxc,mon1,mon2,wei1,wei2)
1607 !
1608 ! get tf_clm (nx by ny lat/lon) valid at atime
1609 !
1610  if ( nx == nxc .and. ny == nyc ) then
1611  tf_clm(:,:) = tf_clm0(:,:)
1612  tf_trd(:,:) = tf_trd0(:,:)
1613 ! write(*,'(a,2f9.3)') 'same dimensions, tf_clm, min : ',minval(tf_clm),maxval(tf_clm)
1614  else
1615 ! write(*,'(a,4i8)') 'different dimensions,nx,ny,nxc,nyc : ',nx,ny,nxc,nyc
1616  call intp_tile(tf_clm0, cxlats, cxlons, nyc, nxc, &
1617  tf_clm_ij,xlats_ij,xlons_ij,ny, nx)
1618  call intp_tile(tf_trd0, cxlats, cxlons, nyc, nxc, &
1619  tf_trd_ij,xlats_ij,xlons_ij,ny, nx)
1620 ! write(*,'(a,2f9.3)') 'tf_clm0, min, max : ',minval(tf_clm0),maxval(tf_clm0)
1621 
1622  tf_clm(:,:) = reshape(tf_clm_ij, (/nx,ny/) )
1623  tf_trd(:,:) = reshape(tf_trd_ij, (/nx,ny/) )
1624  endif
1625 
1626 end subroutine get_tf_clm
1627 
1642 subroutine get_tf_clm_ta(tf_clm_ta,tf_clm_trend,xlats,xlons,nlat,nlon,mon1,mon2,wei1,wei2)
1643  use read_write_data, only : read_tf_clim_grb
1644  implicit none
1645 
1646 ! input
1647  integer, intent(in) :: nlat,nlon,mon1,mon2
1648  real, intent(in) :: wei1,wei2
1649 ! output
1650  real, dimension(nlon,nlat), intent(out) :: tf_clm_ta,tf_clm_trend
1651  real, dimension(nlat), intent(out) :: xlats
1652  real, dimension(nlon), intent(out) :: xlons
1653 
1654 !input/output data file names
1655  character (len=6), parameter :: fin_tf_clm='sstclm'
1656 
1657 ! local declare
1658  real, dimension(nlon,nlat) :: tf_clm1,tf_clm2
1659 
1660 !
1661 ! read in rtg sst climatology without bitmap (surface mask) for mon1 and mon2
1662 !
1663  call read_tf_clim_grb(trim(fin_tf_clm),tf_clm1,xlats,xlons,nlat,nlon,mon1)
1664  call read_tf_clim_grb(trim(fin_tf_clm),tf_clm2,xlats,xlons,nlat,nlon,mon2)
1665 !
1666 ! tf_clim at the analysis time
1667 !
1668  tf_clm_ta(:,:) = wei1*tf_clm1(:,:)+wei2*tf_clm2(:,:)
1669 !
1670 ! tf_clim trend at the analysis time (month to month)
1671 !
1672  tf_clm_trend(:,:) = (tf_clm2(:,:)-tf_clm1(:,:))/120.0
1673 
1674  write(*,'(a,2f9.3)') 'tf_clm_ta, min, max : ',minval(tf_clm_ta),maxval(tf_clm_ta)
1675  write(*,'(a,2f9.3)') 'tf_clm_trend, min, max : ',minval(tf_clm_trend),maxval(tf_clm_trend)
1676  end subroutine get_tf_clm_ta
1677 
1690 subroutine get_sal_clm(xlats_ij,xlons_ij,ny,nx,iy,im,id,ih,sal_clm)
1691  use read_write_data, only : get_dim_nc
1692  implicit none
1693 
1694  real, dimension(nx*ny), intent(in) :: xlats_ij !
1695  real, dimension(nx*ny), intent(in) :: xlons_ij !
1696  real, dimension(nx,ny), intent(out) :: sal_clm !
1697  integer, intent(in) :: iy,im,id,ih,nx,ny
1698 ! local declare
1699  real, allocatable, dimension(:,:) :: sal_clm0 ! salinity climatology at the valid time
1700  real, allocatable, dimension(:) :: cxlats ! latitudes of sst climatology
1701  real, allocatable, dimension(:) :: cxlons ! longitudes of sst climatology
1702 
1703  real, dimension(nx*ny) :: sal_clm_ij ! salinity climatology at target grids (nx*ny)
1704  real :: wei1,wei2
1705  integer :: nxc,nyc,mon1,mon2,i,j
1706  character (len=6), parameter :: fin_sal_clm='salclm' ! salinity climatology file name
1707 !
1708 ! get which two months used and their weights from atime
1709 !
1710  call get_tim_wei(iy,im,id,ih,mon1,mon2,wei1,wei2)
1711 !
1712 ! get the dimensions of the sst climatology & allocate the related arrays
1713 !
1714  call get_dim_nc(fin_sal_clm,nyc,nxc)
1715  allocate( sal_clm0(nxc,nyc),cxlats(nyc),cxlons(nxc) )
1716 !
1717 ! get sal_clm at the analysis time from monthly climatology & cxlats, cxlons
1718 !
1719  call get_sal_clm_ta(sal_clm0,cxlats,cxlons,nyc,nxc,mon1,mon2,wei1,wei2)
1720 !
1721 ! get sal_clm (nx by ny lat/lon) valid at atime
1722 !
1723  if ( nx == nxc .and. ny == nyc ) then
1724  sal_clm(:,:) = sal_clm0(:,:)
1725 ! write(*,'(a,2f9.3)') 'same dimensions, sal_clm, min : ',minval(sal_clm),maxval(sal_clm)
1726  else
1727 ! write(*,'(a,4i8)') 'different dimensions,nx,ny,nxc,nyc : ',nx,ny,nxc,nyc
1728  call intp_tile(sal_clm0, cxlats, cxlons, nyc, nxc, &
1729  sal_clm_ij,xlats_ij,xlons_ij,ny, nx)
1730 ! write(*,'(a,2f9.3)') 'sal_clm0, min, max : ',minval(sal_clm0),maxval(sal_clm0)
1731 ! write(*,'(a,2f9.3)') 'done with intp_tile for sal_clm, min, max : ',minval(sal_clm_ij),maxval(sal_clm_ij)
1732 
1733  sal_clm(:,:) = reshape(sal_clm_ij, (/nx,ny/) )
1734  endif
1735 
1736 end subroutine get_sal_clm
1737 
1750 subroutine get_sal_clm_ta(sal_clm_ta,xlats,xlons,nlat,nlon,mon1,mon2,wei1,wei2)
1752  use read_write_data, only : read_salclm_gfs_nc
1753  implicit none
1754 
1755 ! input
1756  integer, intent(in) :: nlat,nlon,mon1,mon2
1757  real, intent(in) :: wei1,wei2
1758 ! output
1759  real, dimension(nlon,nlat), intent(out) :: sal_clm_ta
1760  real, dimension(nlat), intent(out) :: xlats
1761  real, dimension(nlon), intent(out) :: xlons
1762 
1763 !input/output data file names
1764  character (len=6), parameter :: fin_sal_clm='salclm'
1765 
1766 ! local declare
1767  real, dimension(nlon,nlat) :: sal_clm1,sal_clm2
1768 
1769 !
1770 ! read in rtg sst climatology without bitmap (surface mask) for mon1 and mon2
1771 !
1772  call read_salclm_gfs_nc(trim(fin_sal_clm),sal_clm1,xlats,xlons,nlat,nlon,mon1)
1773  call read_salclm_gfs_nc(trim(fin_sal_clm),sal_clm2,xlats,xlons,nlat,nlon,mon2)
1774 !
1775 ! sal_clim at the analysis time
1776 !
1777  sal_clm_ta(:,:) = wei1*sal_clm1(:,:)+wei2*sal_clm2(:,:)
1778  write(*,'(a,2f9.3)') 'sal_clm_ta, min, max : ',minval(sal_clm_ta),maxval(sal_clm_ta)
1779  end subroutine get_sal_clm_ta
1780 
1795 subroutine intp_tile(tf_lalo,dlats_lalo,dlons_lalo,jdim_lalo,idim_lalo, &
1796  tf_tile,xlats_tile,xlons_tile,jdim_tile,idim_tile)
1798  use utils
1799 
1800  implicit none
1801 
1802 ! input/output
1803  real, dimension(idim_lalo,jdim_lalo), intent(in) :: tf_lalo
1804  real, dimension(jdim_lalo), intent(in) :: dlats_lalo
1805  real, dimension(idim_lalo), intent(in) :: dlons_lalo
1806  real, dimension(jdim_tile*idim_tile), intent(in) :: xlats_tile
1807  real, dimension(jdim_tile*idim_tile), intent(in) :: xlons_tile
1808  integer, intent(in) :: jdim_lalo,idim_lalo,jdim_tile,idim_tile
1809  real, dimension(jdim_tile*idim_tile), intent(out) :: tf_tile
1810 
1811 ! local
1812  real, parameter :: deg2rad=3.1415926/180.0
1813  real, dimension(jdim_lalo) :: xlats_lalo
1814  real, dimension(idim_lalo) :: xlons_lalo
1815  real :: tf,wsum,res_km
1816  integer :: itile,jtile
1817  integer :: ii,jj,ij,iii,jjj
1818  integer :: ilalo,jlalo,ilalop1,jlalop1
1819  integer :: istart,iend,jstart,jend,krad
1820 
1821  integer, allocatable, dimension(:,:) :: id1,id2,jdc
1822  real, allocatable, dimension(:,:,:) :: agrid,s2c
1823 
1824  print*
1825  print*,'interpolate from lat/lon grids to any one grid with known lat/lon'
1826 
1827  xlats_lalo = dlats_lalo*deg2rad
1828  xlons_lalo = dlons_lalo*deg2rad
1829 
1830  allocate(agrid(idim_tile,jdim_tile,2))
1831  agrid(:,:,1) = reshape(xlons_tile, (/idim_tile,jdim_tile/) )
1832  agrid(:,:,2) = reshape(xlats_tile, (/idim_tile,jdim_tile/) )
1833  agrid = agrid*deg2rad
1834 
1835  allocate(id1(idim_tile,jdim_tile))
1836  allocate(id2(idim_tile,jdim_tile))
1837  allocate(jdc(idim_tile,jdim_tile))
1838  allocate(s2c(idim_tile,jdim_tile,4))
1839 
1840 !----------------------------------------------------------------------
1841 ! compute bilinear weights for each model point from the nearest
1842 ! four lalo points. does not account for mask. that
1843 ! happens later.
1844 !----------------------------------------------------------------------
1845 
1846  call remap_coef( 1, idim_tile, 1, jdim_tile, idim_lalo, jdim_lalo, &
1847  xlons_lalo, xlats_lalo, id1, id2, jdc, s2c, agrid )
1848 
1849  do ij = 1, jdim_tile*idim_tile
1850 
1851  jtile = (ij-1)/idim_tile + 1
1852  itile = mod(ij,idim_tile)
1853  if (itile==0) itile = idim_tile
1854 
1855  ilalo = id1(itile,jtile)
1856  ilalop1 = id2(itile,jtile)
1857  jlalo = jdc(itile,jtile)
1858  jlalop1 = jdc(itile,jtile) + 1
1859 
1860  wsum = s2c(itile,jtile,1) + s2c(itile,jtile,2) + &
1861  s2c(itile,jtile,3) + s2c(itile,jtile,4)
1862 
1863  tf_tile(ij) = ( s2c(itile,jtile,1)*tf_lalo(ilalo,jlalo) + &
1864  s2c(itile,jtile,2)*tf_lalo(ilalop1,jlalo) + &
1865  s2c(itile,jtile,3)*tf_lalo(ilalop1,jlalop1) + &
1866  s2c(itile,jtile,4)*tf_lalo(ilalo,jlalop1) )/wsum
1867  enddo
1868 
1869  deallocate(id1, id2, jdc, s2c)
1870 
1871 end subroutine intp_tile
1872 
1885 subroutine get_tim_wei(iy,im,id,ih,mon1,mon2,wei1,wei2)
1886  implicit none
1887 
1888 ! input
1889  integer, intent(in) :: iy,im,id,ih
1890 ! output
1891  integer, intent(out) :: mon1,mon2
1892  real, intent(out) :: wei1,wei2
1893 
1894 ! local declare
1895  real :: rjday
1896  integer :: mon,monend,monm,monp,jdow,jdoy,jday
1897  integer :: jda(8)
1898 !
1899 !dayhf : julian day of the middle of each month
1900 !
1901  real, dimension(13) :: dayhf
1902  data dayhf/15.5,45.0,74.5,105.0,135.5,166.0,196.5,227.5,258.0,288.5,319.0,349.5,380.5/
1903 
1904 ! 15, 44, 73.5, 104, 134.5, 165, 195.5, 226.5, 257, 287.5, 318.5, 349 ! from
1905 ! woa05
1906 
1907  jda=0
1908  jda(1)=iy
1909  jda(2)=im
1910  jda(3)=id
1911  jda(5)=ih
1912  jdow = 0
1913  jdoy = 0
1914  jday = 0
1915  call w3doxdat(jda,jdow,jdoy,jday)
1916  rjday=jdoy+jda(5)/24.
1917  if(rjday.lt.dayhf(1)) rjday=rjday+365.
1918 
1919  monend = 12
1920  do mon = 1, monend
1921  monm = mon
1922  monp = mon + 1
1923  if( rjday >= dayhf(monm) .and. rjday < dayhf(monp) ) then
1924  mon1 = monm
1925  mon2 = monp
1926  go to 10
1927  endif
1928  enddo
1929 
1930  print *,'FATAL ERROR in get_tim_wei, wrong rjday',rjday
1931  call abort
1932  10 continue
1933 
1934  wei1 = (dayhf(mon2)-rjday)/(dayhf(mon2)-dayhf(mon1))
1935  wei2 = (rjday-dayhf(mon1))/(dayhf(mon2)-dayhf(mon1))
1936 
1937  if( mon2 == 13 ) mon2=1
1938 
1939  write(*,'(a,2i4,3f9.3)') 'mon1,mon2,rjday,wei1,wei2=',mon1,mon2,rjday,wei1,wei2
1940 
1941  end subroutine get_tim_wei
1942 
1952  real function tfreez(salinity)
1954  implicit none
1955 
1956  REAL salinity,sal
1957  REAL a1, a2, a3
1958  parameter(a1 = -0.0575)
1959  parameter(a2 = 1.710523e-3)
1960  parameter(a3 = -2.154996e-4)
1961 
1962  IF (salinity .LT. 0.) THEN
1963  sal = 0.
1964  ELSE
1965  sal = salinity
1966  ENDIF
1967  tfreez = sal*(a1+a2*sqrt(sal)+a3*sal)
1968 
1969  return
1970  end
integer function num_parthds()
Return the number of omp threads.
Definition: num_parthds.f90:10
subroutine get_tf_clm(xlats_ij, xlons_ij, ny, nx, iy, im, id, ih, tf_clm, tf_trd)
Get the sst climatology at the valid time and on the target grid.
Definition: cycle.f90:1574
subroutine get_tf_clm_ta(tf_clm_ta, tf_clm_trend, xlats, xlons, nlat, nlon, mon1, mon2, wei1, wei2)
Get the reference temperature/sst climatology and its trend at analysis time.
Definition: cycle.f90:1643
subroutine get_sal_clm_ta(sal_clm_ta, xlats, xlons, nlat, nlon, mon1, mon2, wei1, wei2)
Get climatological salinity at the analysis time.
Definition: cycle.f90:1751
subroutine tf_thaw_set(tf_ij, mask_ij, itile, jtile, tice, tclm, tf_thaw, nx, ny, nset_thaw_s, nset_thaw_i, nset_thaw_c)
Set the background reference temperature (tf) for points where the ice has just melted.
Definition: cycle.f90:1438
subroutine intp_tile(tf_lalo, dlats_lalo, dlons_lalo, jdim_lalo, idim_lalo, tf_tile, xlats_tile, xlons_tile, jdim_tile, idim_tile)
Interpolate lon/lat grid data to the fv3 native grid (tf_lalo => tf_tile).
Definition: cycle.f90:1797
Module containing utility routines.
Definition: utils.F90:7
real function tfreez(salinity)
Compute the freezing point of water as a function of salinity.
Definition: cycle.f90:1953
subroutine get_tim_wei(iy, im, id, ih, mon1, mon2, wei1, wei2)
For a given date, determine the bounding months and the linear time interpolation weights...
Definition: cycle.f90:1886
subroutine get_sal_clm(xlats_ij, xlons_ij, ny, nx, iy, im, id, ih, sal_clm)
Get salinity climatology at the valid time on the target grid.
Definition: cycle.f90:1691
subroutine nsst_water_reset(nsst, ij, tf_thaw)
If the first guess was sea ice, but the analysis is open water, reset all nsst variables.
Definition: cycle.f90:1528