7 kilen,parin,kolen,pxout,pyout,parout,odvect, &
8 kluout,ointerp,klsmin,klsmout )
99 USE modi_hor_extrapol_surf
104 USE yomhook
,ONLY : lhook, dr_hook
105 USE parkind1
,ONLY : jprb
113 REAL,
INTENT(IN) :: pila1
114 REAL,
INTENT(IN) :: pilo1
115 REAL,
INTENT(IN) :: pila2
116 REAL,
INTENT(IN) :: pilo2
117 INTEGER,
INTENT(IN) :: kinla
118 INTEGER,
DIMENSION(KINLA),
INTENT(IN) :: kinlo
119 INTEGER,
INTENT(IN) :: kilen
120 REAL,
DIMENSION(KINLA),
INTENT(IN) :: pilatarray
121 REAL,
DIMENSION(KILEN),
INTENT(IN) :: parin
122 INTEGER,
INTENT(IN) :: kolen
123 REAL,
DIMENSION(KOLEN),
INTENT(IN) :: pxout
124 REAL,
DIMENSION(KOLEN),
INTENT(IN) :: pyout
125 REAL,
DIMENSION(KOLEN),
INTENT(OUT) :: parout
126 LOGICAL,
DIMENSION(KOLEN),
INTENT(IN) :: ointerp
127 LOGICAL,
INTENT(IN) :: odvect
128 INTEGER,
INTENT(IN) :: kluout
129 INTEGER,
DIMENSION(KILEN),
INTENT(IN),
OPTIONAL :: klsmin
130 INTEGER,
DIMENSION(KOLEN),
INTENT(IN),
OPTIONAL :: klsmout
138 REAL,
DIMENSION(KINLA+1) :: zidlat
140 INTEGER,
DIMENSION(:),
ALLOCATABLE :: iofs
142 INTEGER :: ioss,ios,ion,ionn
144 INTEGER :: ip1,ip2,ip3,ip4,ip5,ip6,ip7,ip8,ip9,ip10, &
147 REAL :: zlann,zlan,zlas,zlass
148 REAL :: zlop1,zlop2,zlop3,zlop4 ,zlop5 ,zlop6, &
149 zlop7,zlop8,zlop9,zlop10,zlop11,zlop12
151 REAL :: zwnn,zwn,zws,zwss
152 REAL :: zw1,zw2,zw3,zw4,zw5,zw6,zw7,zw8,zw9,zw10, &
156 REAL :: zlsm1,zlsm2 ,zlsm3 ,zlsm4 ,zlsm5 ,zlsm6,zlsm7,zlsm8, &
157 zlsm9,zlsm10,zlsm11,zlsm12,zlsmnn,zlsmn,zlsms,zlsmss,&
171 REAL,
DIMENSION(:),
ALLOCATABLE :: zla
172 REAL,
DIMENSION(:),
ALLOCATABLE :: zlo
173 REAL,
DIMENSION(:),
ALLOCATABLE :: zarin
174 INTEGER,
DIMENSION(:),
ALLOCATABLE :: ilsmin
175 INTEGER,
DIMENSION(:),
ALLOCATABLE :: iinlo
189 INTEGER,
DIMENSION(12) :: ip
192 REAL(KIND=JPRB) :: zhook_handle
198 IF (lhook) CALL dr_hook(
'ADAPT_HORIBL_SURF',0,zhook_handle)
213 IF (present(klsmin) .AND. present(klsmout)) ldlsm = .true.
220 IF (odvect) zvect=-1.
224 IF (zilo2 < 0.) zilo2 = zilo2 + 360.
225 IF (zilo1 < 0.) zilo1 = zilo1 + 360.
226 IF (zilo2 < zilo1) zilo1 = zilo1 - 360.
247 jopos = maxval(kinlo(1:kinla))
248 zilo2 = zilo1 + (zilo2 - zilo1) * jopos / (jopos - 1.)
257 IF (zilo2-360.>zilo1-1.e-3) ggloblon = .true.
258 zidla = (pila2 - pila1) / (kinla - 1)
261 zidlat(jlat)=pilatarray(jlat)-pilatarray(jlat-1)
264 IF ((pila1-zidla>= 90.) .OR. (pila1-zidla<=-90.)) gglobs=ggloblon
265 IF ((pila2+zidla>= 90.) .OR. (pila2+zidla<=-90.)) gglobn=ggloblon
267 IF ( pila2 > 100. )
THEN
276 IF (gglobs ) ibigsize=ibigsize+(4+kinlo( 1))+(4+kinlo( 2))
277 IF (gglobn ) ibigsize=ibigsize+(4+kinlo(kinla))+(4+kinlo(kinla-1))
278 IF (ggloblon) ibigsize=ibigsize+ 4*kinla
282 ALLOCATE (zarin(ibigsize))
283 ALLOCATE (ilsmin(ibigsize))
300 IF (gglobs) jopos=jopos+(4+kinlo(1))+(4+kinlo(2))
303 zarin(jopos ) = parin(jipos+kinlo(jloop1)-2)
304 zarin(jopos+1) = parin(jipos+kinlo(jloop1)-1)
305 zarin(jopos+2:jopos+2+kinlo(jloop1)-1) = parin(jipos:jipos+kinlo(jloop1)-1)
306 zarin(jopos+2+kinlo(jloop1) ) = parin(jipos )
307 zarin(jopos+2+kinlo(jloop1)+1) = parin(jipos+1)
309 ilsmin(jopos ) = klsmin(jipos+kinlo(jloop1)-2)
310 ilsmin(jopos+1) = klsmin(jipos+kinlo(jloop1)-1)
311 ilsmin(jopos+2:jopos+2+kinlo(jloop1)-1) = klsmin(jipos:jipos+kinlo(jloop1)-1)
312 ilsmin(jopos+2+kinlo(jloop1) ) = klsmin(jipos )
313 ilsmin(jopos+2+kinlo(jloop1)+1) = klsmin(jipos+1)
315 jipos = jipos + kinlo(jloop1)
316 jopos = jopos + kinlo(jloop1) + 4
319 zarin(jopos:jopos+kilen-1) = parin(jipos:jipos+kilen-1)
321 ilsmin(jopos:jopos+kilen-1) = klsmin(jipos:jipos+kilen-1)
337 ioffset1 = 4 + kinlo(2)
338 ioffset2 = ioffset1 + 4 + kinlo(1)
339 imiddle = (kinlo(1)+4) / 2
340 zarin(ioffset1+1:ioffset1+imiddle) = &
341 zvect*zarin(ioffset2+1+imiddle-2:ioffset2+2*imiddle-2)
342 zarin(ioffset1+imiddle+1:ioffset1+kinlo(1)+4) = &
343 zvect*zarin(ioffset2+1+2:ioffset2+kinlo(1)+4-imiddle+2)
345 ilsmin(ioffset1+1:ioffset1+imiddle) = &
346 ilsmin(ioffset2+1+imiddle-2:ioffset2+2*imiddle-2)
347 ilsmin(ioffset1+imiddle+1:ioffset1+kinlo(1)+4) = &
348 ilsmin(ioffset2+1+2:ioffset2+kinlo(1)+4-imiddle+2)
350 ioffset2 = ioffset2 + 4 + kinlo(1)
351 imiddle = (kinlo(2)+4) / 2
352 zarin(1:imiddle) = zvect*zarin(ioffset2+1+imiddle-2:ioffset2+2*imiddle-2)
353 zarin(imiddle+1:kinlo(2)+4) = &
354 zvect*zarin(ioffset2+1+2:ioffset2+kinlo(2)+4-imiddle+2)
356 ilsmin(1:imiddle) = ilsmin(ioffset2+1+imiddle:ioffset2+2*imiddle)
357 ilsmin(imiddle+1:kinlo(2)+4) = ilsmin(ioffset2+1+2:ioffset2+kinlo(2)+4-imiddle+2)
364 ioffset1 = ibigsize - (4+kinlo(kinla-1)) - (4+kinlo(kinla))
365 ioffset2 = ioffset1 - (4+kinlo(kinla))
366 imiddle = (kinlo(kinla)+4) / 2
367 zarin(ioffset1+1:ioffset1+imiddle) = &
368 zvect*zarin(ioffset2+1+imiddle-2:ioffset2+2*imiddle-2)
369 zarin(ioffset1+imiddle+1:ioffset1+kinlo(1)+4) = &
370 zvect*zarin(ioffset2+1+2:ioffset2+kinlo(1)+4-imiddle+2)
372 ilsmin(ioffset1+1:ioffset1+imiddle) = &
373 ilsmin(ioffset2+1+imiddle-2:ioffset2+2*imiddle-2)
374 ilsmin(ioffset1+imiddle+1:ioffset1+kinlo(1)+4) = &
375 ilsmin(ioffset2+1+2:ioffset2+kinlo(1)+4-imiddle+2)
377 ioffset1 = ioffset1 + (4+kinlo(kinla))
378 ioffset2 = ioffset2 - (4+kinlo(kinla-1))
379 imiddle = (kinlo(kinla-1)+4) / 2
380 zarin(ioffset1+1:ioffset1+imiddle) = &
381 zvect*zarin(ioffset2+1+imiddle-2:ioffset2+2*imiddle-2)
382 zarin(ioffset1+imiddle+1:ioffset1+kinlo(1)+4) = &
383 zvect*zarin(ioffset2+1+2:ioffset2+kinlo(1)+4-imiddle+2)
385 ilsmin(ioffset1+1:ioffset1+imiddle) = &
386 ilsmin(ioffset2+1+imiddle-2:ioffset2+2*imiddle-2)
387 ilsmin(ioffset1+imiddle+1:ioffset1+kinlo(1)+4) = &
388 ilsmin(ioffset2+1+2:ioffset2+kinlo(1)+4-imiddle+2)
395 IF (gglobs) iinla = iinla + 2
396 IF (gglobn) iinla = iinla + 2
398 ALLOCATE (iinlo(iinla))
401 iinlo(ioffset1+1) = kinlo(2)
402 iinlo(ioffset1+2) = kinlo(1)
403 ioffset1 = ioffset1 + 2
405 iinlo(ioffset1+1:ioffset1+kinla) = kinlo(1:kinla)
406 ioffset1 = ioffset1 + kinla
408 iinlo(ioffset1+1) = kinlo(kinla)
409 iinlo(ioffset1+2) = kinlo(kinla-1)
410 ioffset1 = ioffset1 + 2
415 ALLOCATE (iofs(iinla))
417 IF (ggloblon) iofs(1)=iofs(1)+2
419 iofs(jloop1) = iofs(jloop1-1) + iinlo(jloop1-1)
420 IF (ggloblon) iofs(jloop1) = iofs(jloop1) + 4
433 IF (.NOT. ointerp(jopos)) cycle
436 IF (zolo < zilo1) zolo = zolo + 360.
437 IF (zolo > zilo2) zolo = zolo - 360.
456 IF((zola>=(pilatarray(jlat)-zidlat(jlat )/2.)).AND.(zola<(pilatarray(jlat)&
457 +zidlat(jlat+1)/2.))) ios = jlat
459 zlas = pilatarray(ios)
460 IF (gglobs) ios = ios + 2
465 zlass=pilatarray(1)-zidlat(1)/2.
467 zlass = pilatarray(ios-1)
469 zlan = pilatarray(ios+1)
470 zlann = pilatarray(ion+1)
474 IF (gglobs .AND. ios==2)
THEN
475 zlass = 2. * zsouthpole - zlann
476 zlas = 2. * zsouthpole - zlan
478 IF (gglobs .AND. ios==3)
THEN
479 zlass = 2. * zsouthpole - zlas
481 IF (gglobn .AND. ios==iinla-2)
THEN
482 zlann = 2. * znorthpole - zlass
483 zlan = 2. * znorthpole - zlas
485 IF (gglobn .AND. ios==iinla-3)
THEN
486 zlann = 2. * znorthpole - zlan
489 IF ((ioss<1).OR.(ionn>iinla).OR. &
490 (ioss<1).OR.(ionn>iinla))
THEN
491 WRITE (kluout,
'(A)') &
492 ' -> [HORIBL_SURF.F90] Input domain is smaller than output one - latitude. Abort'
493 CALL
abor1_sfx(
'ADAPT_HORIBLE_SURF: INPUT DOMAIN TOO SMALL - LATITUDE')
497 zidlo = (zilo2 - zilo1) / (iinlo(ionn))
498 ip1 = int((zolo - zilo1) / zidlo)
500 zlop1 = zilo1 + ip1 * zidlo
501 zlop2 = zlop1 + zidlo
504 zidlo = (zilo2 - zilo1) / (iinlo(ion ))
505 ip4 = int((zolo - zilo1) / zidlo)
509 zlop4 = zilo1 + ip4 * zidlo
510 zlop3 = zlop4 - zidlo
511 zlop5 = zlop4 + zidlo
512 zlop6 = zlop5 + zidlo
515 zidlo = (zilo2 - zilo1) / (iinlo(ios ))
516 ip8 = int((zolo - zilo1) / zidlo)
520 zlop8 = zilo1 + ip8 * zidlo
521 zlop7 = zlop8 - zidlo
522 zlop9 = zlop8 + zidlo
523 zlop10= zlop9 + zidlo
526 zidlo = (zilo2 - zilo1) / (iinlo(ioss))
527 ip11 = int((zolo - zilo1) / zidlo)
529 zlop11= zilo1 + ip11* zidlo
530 zlop12= zlop11+ zidlo
534 IF ((ip1 <-2) .OR. (ip2 >iinlo(ionn)+1) .OR. &
535 (ip3 <-2) .OR. (ip6 >iinlo(ion )+1) .OR. &
536 (ip7 <-2) .OR. (ip10>iinlo(ios )+1) .OR. &
537 (ip11<-2) .OR. (ip12>iinlo(ioss)+1))
THEN
538 WRITE (kluout,
'(A,A)') &
539 ' -> [HORIBL_SURF.F90] Input domain is smaller than output one ', &
540 '- longitude global, abort'
541 CALL
abor1_sfx(
'ADAPT_HORIBLE_SURF: INPUT DOMAIN TOO SMALL - LONGITUDE GLOBAL')
544 IF ((ip1 <0) .OR. (ip2 >iinlo(ionn)-1) .OR. &
545 (ip3 <0) .OR. (ip6 >iinlo(ion )-1) .OR. &
546 (ip7 <0) .OR. (ip10>iinlo(ios )-1) .OR. &
547 (ip11<0) .OR. (ip12>iinlo(ioss)-1))
THEN
548 WRITE (kluout,
'(A,A)') &
549 ' -> [HORIBL_SURF.F90] Input domain is smaller than output one ', &
550 '- longitude local, abort'
551 CALL
abor1_sfx(
'ADAPT_HORIBLE_SURF: INPUT DOMAIN TOO SMALL - LONGITUDE LOCAL')
556 ip1 =ip1 + iofs(ionn)
557 ip2 =ip2 + iofs(ionn)
558 ip3 =ip3 + iofs(ion )
559 ip4 =ip4 + iofs(ion )
560 ip5 =ip5 + iofs(ion )
561 ip6 =ip6 + iofs(ion )
562 ip7 =ip7 + iofs(ios )
563 ip8 =ip8 + iofs(ios )
564 ip9 =ip9 + iofs(ios )
565 ip10=ip10+ iofs(ios )
566 ip11=ip11+ iofs(ioss)
567 ip12=ip12+ iofs(ioss)
588 IF (ilsmin(ip1 ).NE.klsmout(jopos)) zlsm1 = 0.
589 IF (ilsmin(ip2 ).NE.klsmout(jopos)) zlsm2 = 0.
590 IF (ilsmin(ip3 ).NE.klsmout(jopos)) zlsm3 = 0.
591 IF (ilsmin(ip4 ).NE.klsmout(jopos)) zlsm4 = 0.
592 IF (ilsmin(ip5 ).NE.klsmout(jopos)) zlsm5 = 0.
593 IF (ilsmin(ip6 ).NE.klsmout(jopos)) zlsm6 = 0.
594 IF (ilsmin(ip7 ).NE.klsmout(jopos)) zlsm7 = 0.
595 IF (ilsmin(ip8 ).NE.klsmout(jopos)) zlsm8 = 0.
596 IF (ilsmin(ip9 ).NE.klsmout(jopos)) zlsm9 = 0.
597 IF (ilsmin(ip10).NE.klsmout(jopos)) zlsm10 = 0.
598 IF (ilsmin(ip11).NE.klsmout(jopos)) zlsm11 = 0.
599 IF (ilsmin(ip12).NE.klsmout(jopos)) zlsm12 = 0.
600 zlsmnn = min(zlsm1 +zlsm2,1.)
601 zlsmn = min(zlsm3 +zlsm4 +zlsm5 +zlsm6,1.)
602 zlsms = min(zlsm7 +zlsm8 +zlsm9 +zlsm10,1.)
603 zlsmss = min(zlsm11+zlsm12,1.)
604 zlsmtot = min(zlsmnn+zlsmn+zlsms+zlsmss,1.)
605 IF (zlsmnn < 1.e-3)
THEN
609 IF (zlsmn < 1.e-3)
THEN
615 IF (zlsms < 1.e-3)
THEN
621 IF (zlsmss < 1.e-3)
THEN
625 IF (zlsmtot < 1.e-3)
THEN
636 zw1 = zlsm1 * (1.+zlsm2 *(zolo -zlop1 )/(zlop1 -zlop2 ))
638 zwnn = zlsmnn* (1.+zlsmn *(zola -zlann)/(zlann-zlan )) &
639 * (1.+zlsms *(zola -zlann)/(zlann-zlas )) &
640 * (1.+zlsmss*(zola -zlann)/(zlann-zlass))
643 zw3 = zlsm3 * (1.+zlsm4 *(zolo -zlop3 )/(zlop3 -zlop4 )) &
644 * (1.+zlsm5 *(zolo -zlop3 )/(zlop3 -zlop5 )) &
645 * (1.+zlsm6 *(zolo -zlop3 )/(zlop3 -zlop6 ))
646 zw4 = zlsm4 * (1.+zlsm3 *(zolo -zlop4 )/(zlop4 -zlop3 )) &
647 * (1.+zlsm5 *(zolo -zlop4 )/(zlop4 -zlop5 )) &
648 * (1.+zlsm6 *(zolo -zlop4 )/(zlop4 -zlop6 ))
649 zw5 = zlsm5 * (1.+zlsm3 *(zolo -zlop5 )/(zlop5 -zlop3 )) &
650 * (1.+zlsm4 *(zolo -zlop5 )/(zlop5 -zlop4 )) &
651 * (1.+zlsm6 *(zolo -zlop5 )/(zlop5 -zlop6 ))
652 zw6 = 1. - zw3 - zw4 - zw5
653 zwn = zlsmn * (1.+zlsmnn*(zola -zlan )/(zlan -zlann)) &
654 * (1.+zlsms *(zola -zlan )/(zlan -zlas )) &
655 * (1.+zlsmss*(zola -zlan )/(zlan -zlass))
658 zw7 = zlsm7 * (1.+zlsm8 *(zolo -zlop7 )/(zlop7 -zlop8 )) &
659 * (1.+zlsm9 *(zolo -zlop7 )/(zlop7 -zlop9 )) &
660 * (1.+zlsm10*(zolo -zlop7 )/(zlop7 -zlop10))
661 zw8 = zlsm8 * (1.+zlsm7 *(zolo -zlop8 )/(zlop8 -zlop7 )) &
662 * (1.+zlsm9 *(zolo -zlop8 )/(zlop8 -zlop9 )) &
663 * (1.+zlsm10*(zolo -zlop8 )/(zlop8 -zlop10))
664 zw9 = zlsm9 * (1.+zlsm7 *(zolo -zlop9 )/(zlop9 -zlop7 )) &
665 * (1.+zlsm8 *(zolo -zlop9 )/(zlop9 -zlop8 )) &
666 * (1.+zlsm10*(zolo -zlop9 )/(zlop9 -zlop10))
667 zw10 = 1. - zw7 - zw8 - zw9
668 zws = zlsms * (1.+zlsmnn*(zola -zlas )/(zlas -zlann)) &
669 * (1.+zlsmn *(zola -zlas )/(zlas -zlan )) &
670 * (1.+zlsmss*(zola -zlas )/(zlas -zlass))
673 zw11 = zlsm11* (1.+zlsm12*(zolo -zlop11)/(zlop11-zlop12))
675 zwss = 1. - zwnn - zwn - zws
691 parout(jopos) = zw1 * zarin(ip1 ) + &
692 zw2 * zarin(ip2 ) + &
693 zw3 * zarin(ip3 ) + &
694 zw4 * zarin(ip4 ) + &
695 zw5 * zarin(ip5 ) + &
696 zw6 * zarin(ip6 ) + &
697 zw7 * zarin(ip7 ) + &
698 zw8 * zarin(ip8 ) + &
699 zw9 * zarin(ip9 ) + &
700 zw10 * zarin(ip10) + &
701 zw11 * zarin(ip11) + &
707 IF (present(klsmin))
THEN
726 IF (zarin(ip(jloop2))==xundef) cycle
728 IF ((zmax==xundef))
THEN
729 zmax=zarin(ip(jloop2))
730 zmin=zarin(ip(jloop2))
732 zmax=max(zmax,zarin(ip(jloop2)))
733 zmin=min(zmin,zarin(ip(jloop2)))
738 parout(jopos) = max(min(parout(jopos),zmax),zmin)
749 WHERE(abs(parout-xundef)<1.e-6) parout=xundef
757 IF (count(parout(:)==xundef .AND. ointerp(:))==0 .AND. lhook) CALL dr_hook(
'ADAPT_HORIBL_SURF',1,zhook_handle)
758 IF (count(parout(:)==xundef .AND. ointerp(:))==0)
RETURN
761 IF (count(parin(:)/=xundef)==0 .AND. lhook) CALL dr_hook(
'ADAPT_HORIBL_SURF',1,zhook_handle)
762 IF (count(parin(:)/=xundef)==0)
RETURN
764 WRITE(kluout,*)
' Remaining horizontal extrapolations'
765 WRITE(kluout,*)
' Total number of input data : ',count(parin(:)/=xundef)
766 WRITE(kluout,*)
' Number of points to interpolate: ',count(parout(:)==xundef .AND. ointerp(:))
775 zidlo = (zilo2-zilo1) / kinlo(jlat)
776 DO jlon=1,kinlo(jlat)
778 zla(jipos) = pilatarray(jlat)
779 zlo(jipos) = zilo1 + (jlon-1) * zidlo
787 IF (lhook) CALL dr_hook(
'ADAPT_HORIBL_SURF',1,zhook_handle)
subroutine abor1_sfx(YTEXT)
subroutine adapt_horibl_surf(PILATARRAY, PILA1, PILO1, PILA2, PILO2, KINLA, KINLO, KILEN, PARIN, KOLEN, PXOUT, PYOUT, PAROUT, ODVECT, KLUOUT, OINTERP, KLSMIN, KLSMOUT)