SURFEX v8.1
General documentation of Surfex
fadecx.F90
Go to the documentation of this file.
1 ! Oct-2012 P. Marguinaud 64b LFI
2 ! Jan-2011 P. Marguinaud Thread-safe FA
3 SUBROUTINE fadecx_fort &
4 & (fa, krep, krang, cdnoma, kvalco, klonga, &
5 & pchamp, ldcosp, cdpref, knivau, cdsuff, &
6 & ldundf, pundf, ydgr1tab)
7 USE fa_mod, ONLY : fa_com, jpniil, fagr1tab
8 USE parkind1, ONLY : jprb
9 USE yomhook , ONLY : lhook, dr_hook
10 USE lfi_precision
11 IMPLICIT NONE
12 !****
13 ! Sous-programme INTERNE du logiciel de Fichiers ARPEGE:
14 ! Controle de coherence et decodage (GRIBEX) d'un CHAMP
15 ! HORIZONTAL venant d'etre lu sur un fichier ARPEGE/ALADIN.
16 ! ( DECodage d'un champ gribeX )
17 !**
18 ! Arguments : KREP (Sortie) ==> Code-reponse du sous-programme;
19 ! KRANG (Entree) ==> Rang de l'unite logique;
20 ! CDNOMA (Entree) ==> Nom d'article (prefabrique);
21 ! ( Tableau ) KVALCO (Entree) ==> Donnees issues de la lecture;
22 ! KLONGA (Entree) ==> Nombre de mots lus;
23 ! ( Tableau ) PCHAMP (Sortie) ==> Valeurs REELLES du champ lu;
24 ! LDCOSP (Entree) ==> Vrai si le champ est represente
25 ! par des coefficients spectraux;
26 ! CDPREF (Entree) ==> Prefixe au sens FA
27 ! KNIVAU (Entree) ==> Niveau au sens FA
28 ! CDSUFF (Entree) ==> Suffixe au sens FA
29 ! LDUNDF (Entree) ==> Si ce champ a des valeurs indefinies
30 ! alors inserer PUNDF sur les points
31 ! manquants
32 ! PUNDF (Entree) ==> Dans le cas ou LDUNDF est vrai,
33 ! valeur non definie a inserer dans le champ
34 ! LDUNDF (Sortie) ==> Vrai si ce champ a des valeurs
35 ! indefinies
36 ! PUNDF (Sortie) ==> Dans le cas ou LDUNDF est vrai (en sortie),
37 ! valeur non definie a inserer dans le champ
38 !*
39 ! MODIFICATION :
40 ! JM AUDOIN 15/05/2007 Partie 3.1 Blindage controle changement unite
41 !
42 !
43 !
44 TYPE(fa_com) :: FA
45 TYPE(fagr1tab) :: YDGR1TAB
46 INTEGER (KIND=JPLIKB) KREP, KRANG, KLONGA, KNIVAU
47 !
48 INTEGER (KIND=JPLIKB), TARGET :: KVALCO(klonga)
49 REAL (KIND=JPDBLR) PCHAMP(*)
50 INTEGER (KIND=JPLIKB), POINTER :: IVALCO (:)
51 !
52 REAL (KIND=JPDBLR) PUNDF
53 !
54 LOGICAL LDCOSP, LDUNDF, LLUNDF, LLSWAP
55 !
56 CHARACTER CDNOMA*(*), CDPREF*(*), CDSUFF*(*)
57 !
58 #include "fagribex.h"
59 !
60 REAL (KIND=JPDBLR) ZSEC2(10+2*(fa%jpxniv+1)), ZSEC3(2)
61 REAL (KIND=JPDBLR), ALLOCATABLE :: ZSEC4(:), ZCHAMP(:)
62 REAL (KIND=JPDBLR) ZUNDF
63 REAL (KIND=JPDBLR) ZPULAP
64 !
65 INTEGER (KIND=JPLIKB) ISEC0(2), ISEC1(fa%jpsec1)
66 INTEGER (KIND=JPLIKB) ISEC2(fa%jpsec2), ISEC3(2)
67 INTEGER (KIND=JPLIKB) ISEC4(fa%jpsec4)
68 INTEGER (KIND=JPLIKB) ILCHAM, ISTRIA, IDECAL
69 INTEGER (KIND=JPLIKB) IPOFIN, ILONSEC2
70 INTEGER (KIND=JPLIKB) ITRONC, IIND, ILOW, IHIGH
71 INTEGER (KIND=JPLIKB) IL, IADD, IRANGC, IILCHAM
72 INTEGER (KIND=JPLIKB) INIMES
73 INTEGER (KIND=JPLIKB) IVALC3, IVALC4, IVALC5, IWORD
74 INTEGER (KIND=JPLIKB) INUMER, ILENG, IRET, IDX
75 INTEGER (KIND=JPLIKB) JN, JM, JLAT, JLON, J
76 INTEGER (KIND=JPLIKB) IFAORI, IFAMOD
77 INTEGER (KIND=JPLIKB) INIPAR (8)
78 !
79 LOGICAL LLMLAM, LLCOSP
80 !
81 CHARACTER(LEN=1) CLOPER
82 CHARACTER(LEN=8) CLGRIB
83 !
84 CHARACTER(LEN=FA%JPLMES) CLMESS
85 CHARACTER(LEN=FA%JPLSPX) CLNSPR
86 LOGICAL LLFATA
87 type(fagr1tab) ylgr1tab
88 
89 !**
90 ! 1. - CONTROLES ET INITIALISATIONS.
91 !-----------------------------------------------------------------------
92 !
93 REAL(KIND=JPRB) :: ZHOOK_HANDLE
94 IF (lhook) CALL dr_hook('FADECX_MT',0,zhook_handle)
95 krep=0
96 IF (krang.LE.0.OR.krang.GT.fa%JPNXFA) THEN
97  krep=-66
98  GOTO 1001
99 ENDIF
100 !
101 inumer=fa%FICHIER(krang)%NULOGI
102 !
103 cloper='D'
104 istria=0
105 !**
106 ! 2. - CONTROLE DES DONNEES DE L'ARTICLE
107 !-----------------------------------------------------------------------
108 !
109 IF (kvalco(1).NE.3.OR. &
110 & kvalco(2).LT.0.OR.kvalco(2).GT.1.OR. &
111 & (kvalco(2).EQ.1.AND.kvalco(4).LT.0)) THEN
112  krep=-91
113  GOTO 1001
114 ELSE
115  llcosp=kvalco(2).EQ.1
116 ENDIF
117 !
118 IF ((llcosp.AND..NOT.ldcosp).OR.(.NOT.llcosp.AND.ldcosp)) THEN
119  krep=-92
120  GOTO 1001
121 ENDIF
122 !
123 irangc=fa%FICHIER(krang)%NUCADR
124 llmlam=fa%CADRE(irangc)%LIMLAM
125 itronc=fa%CADRE(irangc)%MTRONC
126 !
127 IF (ldcosp) THEN
128  IF (llmlam) THEN
129  ilcham=fa%CADRE(irangc)%NSFLAM
130  ilonsec2=21+itronc
131  ELSE
132  ilcham=(1+itronc)*(2+itronc)
133  ilonsec2=22
134  ENDIF
135 ELSE
136  ilcham=fa%CADRE(irangc)%NVAPDG
137  IF (llmlam) THEN
138  ilonsec2=22
139  ELSE
140  ilonsec2=22+fa%CADRE(irangc)%NLATIT
141  ENDIF
142 ENDIF
143 !
144 ALLOCATE (zchamp(ilcham), zsec4(ilcham))
145 !
146 !**
147 ! 3. - DECODAGE GRIBEX DES DONNEES DE L'ARTICLE
148 !-----------------------------------------------------------------------
149 !
150 idecal=3
151 ivalc3=kvalco(3)
152 IF (ldcosp) THEN
153  idecal=idecal+2
154 ! IVALC4=ss-tronc non compactee
155 ! IVALC5=puissance de laplacien
156  ivalc4=kvalco(4)
157  ivalc5=kvalco(5)
158 ENDIF
159 
160 iilcham=ilcham
161 !
162 ! Pour Aladin, le calcul du nb de coeff spectraux qui ont
163 ! ete compactes est plus complexe (certains ont ete retires
164 ! pour ne pas etre compactes: ss-tronc triangulaire).
165 !
166 IF (ldcosp.AND.llmlam) THEN
167  istria=4*(1+fa%CADRE(irangc)%NOZPAR(1)+fa%CADRE(irangc)%NOZPAR(2)+ &
168 & ivalc4*(ivalc4-1)/2)
169  iilcham=ilcham-istria
170 ENDIF
171 
172 ! C'est un champ GRIB, mais les octets ont peut-etre ete
173 ! inverses s'il a ete produit sur une architecture differente
174 ! On cherche donc a deviner s'il faut les inverser a nouveau,
175 ! et on inverse le cas echeant
176 
177 clgrib=transfer(kvalco(idecal+1), clgrib)
178 llswap = (clgrib(1:4) /= 'GRIB') .AND. (clgrib(5:8) == 'BIRG')
179 IF (llswap) THEN
180  ALLOCATE (ivalco(klonga))
181  CALL jswap (ivalco(idecal+1), kvalco(idecal+1), 8_jplikm, int(klonga-idecal, jplikm))
182 ELSE
183  ivalco => kvalco
184 ENDIF
185 
186 ! ILENG=longueur disponible en entiers declares INTEGER dans KVALCO.
187 ileng=2*(klonga-idecal)
188 !
189 ! 3.1 - APPEL A GRIBEX
190 !
191 iword=0
192 iret=-1
193 
194 CALL fagribex(isec0,isec1,isec2,zsec2,isec3,zsec3,isec4, &
195 & pchamp,iilcham,ivalco(idecal+1:klonga),ileng,iword, &
196 & cloper,iret)
197 
198 IF (llswap) THEN
199  DEALLOCATE (ivalco)
200  NULLIFY (ivalco)
201 ENDIF
202 
203 IF (fa%LFAMOP) THEN
204  WRITE (unit=fa%NULOUT,fmt=*) &
205 & ' FADECX: KLONGA, IDECAL, ILENG, IILCHAM = ', &
206 & klonga, idecal, ileng, iilcham
207  WRITE (unit=fa%NULOUT,fmt=*) ' * ISEC0 = ',isec0
208  WRITE (unit=fa%NULOUT,fmt=*) ' * ISEC1 = ',isec1
209  WRITE (unit=fa%NULOUT,fmt=*) &
210 & ' * ILONSEC2 ! ISEC2(1:ILONSEC2) = ', &
211 & ilonsec2, ' ! ', isec2(1:ilonsec2)
212  WRITE (unit=fa%NULOUT,fmt=*) ' * ZSEC2(1:2) = ',zsec2(1:2)
213  IF (isec2(12).GT.0) WRITE (unit=fa%NULOUT,fmt=*) &
214 & ' * ISEC2(12) ! ZSEC2(11:10+ISEC2(12)) = ', &
215 & isec2(12), ' ! ', zsec2(11:10+isec2(12))
216  WRITE (unit=fa%NULOUT,fmt=*) ' * FA%JPSEC4 ! ISEC4 = ', &
217 & fa%JPSEC4,' ! ',isec4
218 ENDIF
219 !
220 !
221 IF (krep.NE.0) THEN
222  GOTO 1001
223 ENDIF
224 !
225 !*
226 ! 3.3 - CONTROLES DE COHERENCE
227 !-----------------------------------------------------------------------
228 !
229 
230 IF (iret.GT.0) THEN
231 ! Erreur rapportee par GRIBEX
232  krep=-1000-iret
233  WRITE (unit=fa%NULOUT,fmt=*) ' FADECX: IRET, KREP = ',iret, krep
234  GOTO 1001
235 ELSEIF (iret.LT.0 .AND. ((iret /= -4) .OR. .NOT. ldundf)) THEN ! -4 = "A bitmap was encountered"
236 ! Warning rapporte par GRIBEX
237  WRITE (unit=fa%NULOUT,fmt=*)
238  WRITE (unit=fa%NULOUT,fmt=*) &
239 & '!------------------------------------------'
240  WRITE (unit=fa%NULOUT,fmt=*) &
241 & '! FADECX: WARNING !!! !'
242  WRITE (unit=fa%NULOUT,fmt=*) &
243 & '!------------------------------------------'
244  WRITE (unit=fa%NULOUT,fmt=*) ' Code retour de GRIBEX = ', &
245 & iret,' pour le champ: ',cdnoma
246  WRITE (unit=fa%NULOUT,fmt=*)
247 ENDIF
248 IF (isec4(1).LT.iilcham) THEN
249  krep=-93
250  IF (fa%LFAMOP) THEN
251  WRITE (unit=fa%NULOUT,fmt=*) &
252 & 'FADECX: ERREUR !!! Nbre de valeurs decodees = ', &
253 & isec4(1),' et nbre de valeurs attendues = ',iilcham
254  ENDIF
255  GOTO 1001
256 ELSEIF (isec4(1).GT.iilcham) THEN
257  krep=-94
258  IF (fa%LFAMOP) THEN
259  WRITE (unit=fa%NULOUT,fmt=*) &
260 & 'FADECX: ERREUR !!! Nbre de valeurs decodees = ', &
261 & isec4(1),' et nbre de valeurs attendues = ',iilcham
262  ENDIF
263  IF (llmoer(krep,krang)) GOTO 1001
264 ENDIF
265 !
266 IF (ivalc3.NE.isec4(2).AND.fa%LFAMOP) THEN
267  WRITE (unit=fa%NULOUT,fmt=*) &
268 & ' FADECX: WARNING, le nb de bits de codage qui avait', &
269 & ' ete demande ( ',ivalc3,' ) est different de celui qui a', &
270 & ' ete finalement retenu ( ',isec4(2),' ) par GRIBEX.'
271  WRITE (unit=fa%NULOUT,fmt=*) &
272 & ' => Gain de place sans perte de precision'
273 ENDIF
274 !
275 ! Dans le cas d'un champ spectral ARPEGE
276 !
277 IF (ldcosp.AND..NOT.llmlam.AND.(isec4(18).NE.ivalc4 &
278 & .OR.isec4(17).NE.ivalc5)) THEN
279  IF (fa%LFAMOP) THEN
280  WRITE (unit=fa%NULOUT,fmt=*) &
281 & 'Ss-tronc non compactee dans GRIB = ',isec4(18), &
282 & ' et on attend: ',ivalc4
283  WRITE (unit=fa%NULOUT,fmt=*) &
284 & 'Puissance de laplacien dans GRIB = ',isec4(17), &
285 & ' et on attend: ',ivalc5
286  ENDIF
287  krep=-95
288  GOTO 1001
289 ENDIF
290 !
291 ! Controle de l'adequation entre le nb de mots lus par LFI et le detail:
292 ! ( enrobage FA + message GRIBEX + eventuelles valeurs non-compactees ).
293 !
294 iword=1+(isec0(1)-1)/jplikb
295 IF (fa%LFAMOP) THEN
296  WRITE (unit=fa%NULOUT,fmt=*) ' FADECX: IWORD = ',iword
297 ENDIF
298 ipofin=idecal+iword
299 IF (ldcosp) THEN
300  IF (llmlam) THEN
301  ipofin=ipofin+istria
302  ELSE
303  ipofin=ipofin+(1+ivalc4)*(2+ivalc4)
304  ENDIF
305 ENDIF
306 !
307 IF (klonga.LT.ipofin) THEN
308  krep=-93
309  GOTO 1001
310 ELSEIF (klonga.GT.ipofin) THEN
311  krep=-94
312  IF (llmoer(krep,krang)) GOTO 1001
313 ENDIF
314 !*
315 ! 3.2 - DEMODULATION DES COEFF. SPEC. ALADIN QUI ONT ETE COMPACTES
316 !-----------------------------------------------------------------------
317 !
318 IF (ldcosp.AND.llmlam) THEN
319 ! Transfert des donnees decodees et modulees entieres en nombres reels
320 ! pour les demoduler. Comme PCHAMP est a profil implicite, on ne peut
321 ! s'en servir pour la fonction TRANSFER => il faut passer par ICHAMP!
322  zsec4(1:iilcham) = pchamp(1:iilcham)
323  zchamp=0._jpdblr
324  zpulap=REAL(IVALC5,JPDBLR) * (-0.001_jpdblr)
325  iind=0
326  DO jm=1,fa%CADRE(irangc)%NOMPAR(2)
327  ilow=2+2*jm+1
328  iadd=4*max(ivalc4+1-jm,1_jplikb )
329 !
330  DO idx=fa%CADRE(irangc)%NOMPAR(ilow)+iadd,fa%CADRE(irangc)%NOMPAR(ilow+1)
331  iind=iind+1
332  jn=(idx-fa%CADRE(irangc)%NOMPAR(ilow))/4
333  zchamp(idx)=zsec4(iind) * &
334 & ((REAL(jn**2+jm**2,jpdblr))**zpulap)
335  ENDDO
336  ENDDO
337 ! Transfert des donnees decodees et demodulees reelles en nombres entiers
338 ! disposes aux bons endroits du tableau definitif.
339  pchamp(1:ilcham) = zchamp(1:ilcham)
340 ENDIF
341 !*
342 ! 3.3 - TRANSFERT DES COEFFICIENTS SPECTRAUX NON COMPACTES.
343 !-----------------------------------------------------------------------
344 ! (et non fournis par GRIBEX) stockes en fin d'article.
345 !
346 IF (ldcosp) THEN
347  IF (llmlam) THEN
348  iind=0
349  DO jm=0,fa%CADRE(irangc)%NOMPAR(2)
350  il=2+2*jm+1
351  ilow=fa%CADRE(irangc)%NOMPAR(il)
352 !
353  IF (jm.EQ.0) THEN
354  ihigh=fa%CADRE(irangc)%NOMPAR(il+1)
355  ELSE
356  ihigh=ilow+4*(ivalc4+1-jm)-1
357  IF (ihigh.LE.ilow) ihigh=ilow+3
358  ENDIF
359 !
360  DO idx=ilow,ihigh
361  iind=iind+1
362  pchamp(idx)=transfer(kvalco(idecal+iword+iind), pchamp(idx))
363  ENDDO
364  ENDDO
365  ELSE
366 !
367 ! Cas ARPEGE
368 !
369  pchamp(1:2*(ivalc4+1))= &
370 & transfer(kvalco(idecal+iword+1:idecal+iword+2*(ivalc4+1)), pchamp(1:2*(ivalc4+1)))
371  iind=2*(ivalc4+1)-1
372  idx=2*(itronc+1)-1
373  DO jm=1,ivalc4
374  DO jn=jm,itronc
375  idx=idx+2
376  IF (jn.LE.ivalc4) THEN
377  iind=iind+2
378  pchamp(idx) = transfer(kvalco(idecal+iword+iind), pchamp(idx))
379  pchamp(idx+1) = transfer(kvalco(idecal+iword+iind+1), pchamp(idx+1))
380  ENDIF
381  ENDDO
382  ENDDO
383 !
384  ENDIF
385 ENDIF
386 !*
387 ! 3.4 - Renversement des valeurs en pts de grille des champs
388 ! lat-lon afin de les ranger Sud-Nord plutot que Nord-Sud
389 ! (on conserve le rangt W-E consecutif) a l'image du rangt
390 ! initial effectue par FullPos.
391 !-----------------------------------------------------------------------
392 !
393 IF ((isec2(1)==0.OR.isec2(1)==10.OR.isec2(1)==20.OR. &
394 & isec2(1)==30) .AND. .NOT.ldcosp) THEN
395  IF (fa%LFAMOP) THEN
396  WRITE (unit=fa%NULOUT,fmt=*) &
397 & ' FADECX: Grille LAT-LON issue BDAP -> ', &
398 & ' renversement des valeurs pour etre rangees SN'
399  ENDIF
400  DO jlat=1,fa%CADRE(irangc)%NLATIT
401  DO jlon=1,fa%CADRE(irangc)%NXLOPA
402  jn=jlon+fa%CADRE(irangc)%NXLOPA*(jlat-1)
403  idx=jlon+fa%CADRE(irangc)%NXLOPA*(fa%CADRE(irangc)%NLATIT-jlat)
404  zchamp(idx) = pchamp(jn)
405  ENDDO
406  ENDDO
407  pchamp(1:ilcham) = zchamp(1:ilcham)
408 ENDIF
409 
410 !
411 ! CHANGEMENT D'UNITE DE CERTAINS CHAMPS.
412 ! Il s'agit de champs dont les valeurs sont comprises
413 ! entre 0 et 1 dans le modele mais dont l'unite
414 ! conventionnelle dans le GRIB est le %.
415 !
416 CALL faipag_fort &
417 & (fa, krep, inumer, cdpref, knivau, cdsuff, inipar, &
418 & ylgr1tab)
419 !
420 ! Traitement des valeurs indefinies
421 !
422 llundf = isec1(5) == 192
423 IF (llundf) THEN
424  zundf = zsec3(2)
425 ELSE
426  zundf = 0._jpdblr
427 ENDIF
428 !
429 ! Facteur d'echelle eventuel
430 !
431 IF (ylgr1tab%LMULTI) THEN
432  pchamp(1:ilcham) = pchamp(1:ilcham) / ylgr1tab%FMULTI
433  zundf = zundf / ylgr1tab%FMULTI
434 ENDIF
435 IF (ldundf .AND. llundf) THEN
436  DO j = 1, ilcham
437  IF (pchamp(j) == zundf) THEN
438  pchamp(j) = pundf
439  ENDIF
440  ENDDO
441  zundf = pundf
442 ENDIF
443 ldundf = llundf
444 pundf = zundf
445 
446 !**
447 ! 10. - PHASE TERMINALE : MESSAGERIE, AVEC "ABORT" EVENTUEL,
448 ! VIA LE SOUS-PROGRAMME "FAIPAR" .
449 !-----------------------------------------------------------------------
450 !
451 1001 CONTINUE
452 llfata=llmoer(krep,krang)
453 !
454 IF (fa%LFAMOP.OR.llfata) THEN
455  inimes=2
456  clnspr='FADECX'
457 !
458  WRITE (unit=clmess,fmt='(''KREP='',I5,'', KRANG='',I4, &
459 & '', CDNOMA='''''',A,'''''', KLONGA= '',I8, &
460 & '', LDCOSP='',L1)') &
461 & krep, krang, cdnoma, klonga, ldcosp
462  CALL faipar_fort &
463 & (fa, inumer,inimes,krep,.false.,clmess, &
464 & clnspr,cdnoma,.false.)
465 ENDIF
466 !
467 IF (lhook) CALL dr_hook('FADECX_MT',1,zhook_handle)
468 
469 CONTAINS
470 
471 #include "facom2.llmoer.h"
472 
473 END SUBROUTINE fadecx_fort
474 
475 !INTF KREP OUT
476 !INTF KRANG IN
477 !INTF CDNOMA IN
478 !INTF KVALCO IN DIMS=* KIND=JPLIKB
479 !INTF KLONGA IN
480 !INTF PCHAMP OUT DIMS=*
481 !INTF LDCOSP IN
482 !INTF LDUNDF OUT
483 !INTF PUNDF OUT
484 !INTF YDGR1TAB OUT
485 
integer, parameter jplikb
subroutine fadecx_fort(FA, KREP, KRANG, CDNOMA, KVALCO, KLONGA, PCHAMP, LDCOSP, CDPREF, KNIVAU, CDSUFF, LDUNDF, PUNDF, YDGR1TAB)
Definition: fadecx.F90:7
Definition: fa_mod.F90:1
integer, parameter jprb
Definition: parkind1.F90:32
integer, parameter jpdblr
logical lhook
Definition: yomhook.F90:15
subroutine fagribex(KSEC0, KSEC1, KSEC2, PSEC2, KSEC3, PSEC3, KSEC4, PSEC4, KLENP, KGRIB, KLENG, KWORD, HOPER, KRET)
Definition: fagribex.F90:4
integer, parameter jplikm
subroutine faipar_fort(FA, KNUMER, KNIMES, KCODE, LDFATA, CDMESS, CDNSPR, CDACTI, LDRLFI)
Definition: faipar.F90:6
subroutine faipag_fort(FA, KREP, KNUMER, CDPREF, KNIVAU, CDSUFF, KNIPAR, YDGR1TAB)
Definition: faipag.F90:6
integer(kind=jplikb), parameter jpniil
Definition: fa_mod.F90:31