source: trunk/LMDZ.GENERIC/libf/dyn3d/interp_horiz.F @ 1529

Last change on this file since 1529 was 588, checked in by emillour, 13 years ago

Generic GCM:
Some cleanup and bug fixing:

  • "cloudfrac" was not well written to restartfi (wrong size).
  • missing save attribute for "reffrad" in physiq.F90.
  • cleanup recomputation of surface pressure in newstart and change loop order in interp_horiz (which "fixes" an odd behaviour which fills some arrays with zeros, but only when using some versions of ifort!)

EM

File size: 6.2 KB
Line 
1      subroutine interp_horiz (varo,varn,imo,jmo,imn,jmn,lm,
2     &  rlonuo,rlatvo,rlonun,rlatvn) 
3
4c===========================================================
5c  Interpolation Horizontales des variables d'une grille LMDZ
6c (des points SCALAIRES au point SCALAIRES)
7c  dans une autre grille LMDZ en conservant la quantite
8c  totale pour les variables intensives (/m2) : ex : Pression au sol
9c
10c Francois Forget (01/1995)
11c===========================================================
12
13      IMPLICIT NONE
14
15c   Declarations:
16c ==============
17c
18c  ARGUMENTS
19c  """""""""
20       
21       INTEGER,INTENT(IN) :: imo, jmo ! dimensions ancienne grille (input)
22       INTEGER,INTENT(IN) :: imn,jmn  ! dimensions nouvelle grille (input)
23
24       REAL,INTENT(IN) :: rlonuo(imo+1)     !  Latitude et
25       REAL,INTENT(IN) :: rlatvo(jmo)       !  longitude des
26       REAL,INTENT(IN) :: rlonun(imn+1)     !  bord des
27       REAL,INTENT(IN) :: rlatvn(jmn)     !  cases "scalaires" (input)
28
29       INTEGER,INTENT(IN) :: lm ! dimension verticale (input)
30       REAL,INTENT(IN) :: varo (imo+1, jmo+1,lm) ! var dans l'ancienne grille (input)
31       REAL,INTENT(OUT) :: varn (imn+1,jmn+1,lm) ! var dans la nouvelle grille (output)
32
33c Autres variables
34c """"""""""""""""
35       INTEGER imnmx2,jmnmx2
36c       parameter (imnmx2=190,jmnmx2=100)
37       parameter (imnmx2=360,jmnmx2=190)
38       REAL airetest(imnmx2+1,jmnmx2+1)
39       INTEGER ii,jj,l
40
41       REAL,SAVE :: airen ((imnmx2+1)*(jmnmx2+1)) ! aire dans la nouvelle grille
42       REAL airentotn   ! aire totale pole nord dans la nouvelle grille
43       REAL airentots   ! aire totale pole sud dans la nouvelle grille
44c    Info sur les ktotal intersection entre les cases new/old grille
45
46c kmax: le nombre  max  d'intersections entre les 2 grilles horizontales
47c On fixe kmax a la taille de la grille des donnees martiennes (360x179)
48c + des pouiemes (cas ou une maille est a cheval sur 2 ou 4 mailles)
49c  Il y a un test dans iniinterp_h pour s'assurer que ktotal < kmax
50       INTEGER kmax, k
51       integer,save :: ktotal
52       parameter (kmax = 360*179 + 200000)
53c      parameter (kmax = 360*179 + 40000)
54
55       INTEGER,SAVE :: iik(kmax), jjk(kmax),jk(kmax),ik(kmax)
56       REAL,SAVE :: intersec(kmax)
57       REAL r
58       REAL totn, tots
59       integer,save :: prev_sumdim=0
60
61       logical,save :: firsttest=.true. , aire_ok=.true.
62
63       integer,save :: imoS,jmoS,imnS,jmnS
64
65c Test dimensions imnmx2 jmnmx2
66c""""""""""""""""""""""""""""""
67c test dimensionnement tableau airetest
68      if (imn.GT.imnmx2.OR.jmn.GT.jmnmx2) then
69         write(*,*) 'STOP pb dimensionnement tableau airetest'
70         write(*,*) 'il faut imn < imnmx2 et jmn < jmnmx2'
71         write(*,*) 'imn imnmx2', imn,imnmx2
72         write(*,*) 'jmn jmnmx2', jmn,jmnmx2
73         call exit(1)
74      endif
75
76c initialisation
77c --------------
78c Si c'est le premier appel,  on prepare l'interpolation
79c en calculant pour chaque case autour d'un point scalaire de la
80c nouvelle grille, la surface  de intersection avec chaque
81c    case de l'ancienne grille.
82
83c  This must also be done if we change the dimension
84      if (imo+jmo+imn+jmn.ne.prev_sumdim) then
85          firsttest=.true.
86          prev_sumdim=imo+jmo+imn+jmn
87      end if       
88
89      if (firsttest) then
90        call iniinterp_h(imo,jmo,imn,jmn ,kmax,
91     &       rlonuo,rlatvo,rlonun,rlatvn,
92     &          ktotal,iik,jjk,jk,ik,intersec,airen)
93       imoS=imo
94       jmoS=jmo
95       imnS=imn
96       jmnS=jmn
97      else
98       if(imo.NE.imoS.OR.jmo.NE.jmoS.OR.imn.NE.imnS.OR.jmn.NE.jmnS) then
99        call iniinterp_h(imo,jmo,imn,jmn ,kmax,
100     &       rlonuo,rlatvo,rlonun,rlatvn,
101     &          ktotal,iik,jjk,jk,ik,intersec,airen)
102       imoS=imo
103       jmoS=jmo
104       imnS=imn
105       jmnS=jmn
106       end if
107      end if
108
109! initialize varn() to zero
110      varn(1:imn+1,1:jmn+1,1:lm)=0.
111       
112c Interpolation horizontale
113c -------------------------
114c boucle sur toute les ktotal intersections entre les cases
115c de l'ancienne et la  nouvelle grille
116c
117! Ehouarn 2012: for some strange reason, with ifort v12.x,
118!               when the order of the loop below is changed
119!               values of varn(:,:,l=2...) are then sometimes remain zero!   
120      do l=1,lm
121        do k=1,ktotal
122         varn(iik(k),jjk(k),l) = varn(iik(k),jjk(k),l)
123     &   + varo(ik(k), jk(k),l)*intersec(k)/airen(iik(k)
124     &   +(jjk(k)-1)*(imn+1))
125        end do
126      end do
127
128c Une seule valeur au pole pour les variables ! :
129c -----------------------------------------------
130      DO l=1, lm
131         totn =0.
132         tots =0.
133
134
135c moyenne du champ au poles (ponderee par les aires)
136c"""""""""""""""""""""""""""""""
137         airentotn=0.
138         airentots=0.
139
140         do ii =1, imn+1
141            totn = totn + varn(ii,1,l)*airen(ii)
142            tots = tots + varn (ii,jmn+1,l)*airen(jmn*(imn+1)+ii)
143            airentotn=airentotn + airen(ii)
144            airentots=airentots + airen(jmn*(imn+1)+ii)
145         end do
146
147         do ii =1, imn+1
148            varn(ii,1,l) = totn/airentotn
149            varn(ii,jmn+1,l) = tots/airentots
150         end do
151
152      ENDDO ! of DO l=1, lm
153           
154
155c---------------------------------------------------------------
156c  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST  TEST
157      if (firsttest) then
158      firsttest = .false.
159      write (*,*) 'INTERP. HORIZ. : TEST SUR LES AIRES:'
160
161      do jj =1 , jmn+1
162        do ii=1, imn+1
163          airetest(ii,jj) =0.
164        end do
165      end do
166      do k=1,ktotal
167         airetest(iik(k),jjk(k))= airetest(iik(k),jjk(k)) +intersec(k)
168      end do
169      do jj =1 , jmn+1
170       do ii=1, imn+1
171         r = airen(ii+(jj-1)*(imn+1))/airetest(ii,jj)
172         if ((r.gt.1.001).or.(r.lt.0.999)) then
173             write (*,*) '********** PROBLEME D'' AIRES !!!',
174     &                   ' DANS L''INTERPOLATION HORIZONTALE'
175             write(*,*)'ii,jj,airen,airetest',
176     &          ii,jj,airen(ii+(jj-1)*(imn+1)),airetest(ii,jj)
177             aire_ok = .false.
178         end if
179       end do
180      end do
181      if (aire_ok) write(*,*) 'INTERP. HORIZ. : AIRES OK'
182      endif ! of if (firsttest)
183
184c FIN TEST  FIN TEST  FIN TEST  FIN TEST  FIN TEST  FIN TEST  FIN TEST
185c --------------------------------------------------------------------
186
187
188        end
Note: See TracBrowser for help on using the repository browser.