SURFEX v8.1
General documentation of Surfex
facine.F90
Go to the documentation of this file.
1 ! Oct-2012 P. Marguinaud 64b LFI
2 ! Jan-2011 P. Marguinaud Thread-safe FA
3 ! Sep-2012 P. Marguinaud Fix uninitialized variables
4 SUBROUTINE facine_fort &
5 & (fa, krep, krang, cdnoma, pchamp, ldcosp, &
6 & pvalco, klongd, kb1par, ldundf, pundf)
7 USE fa_mod, ONLY : fa_com, jpniil, jpprcm
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 ! PREPARATION (codage GRIB ou non) d'un CHAMP HORIZONTAL
15 ! destine a etre ecrit sur un fichier ARPEGE/ALADIN.
16 ! ( Codage Interne d'un (Nouveau ?) champ a Ecrire )
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 ) PCHAMP (Entree) ==> Valeurs REELLES du champ a ecrire;
22 ! LDCOSP (Entree) ==> Vrai si le champ est represente
23 ! par des coefficients spectraux;
24 ! ( Tableau ) PVALCO (Sortie) ==> Donnees destinees a l'ecriture;
25 ! KLONGD (Sortie) ==> Nombre de mots a ecrire;
26 ! ( Tableau ) KB1PAR (Entree+ ==> Image des parametres de la section
27 ! Sortie) 1 de GRIB.
28 !*
29 ! En mode multi-taches, il doit y avoir verrouillage du fichier
30 ! concerne avant l'appel au sous-programme.
31 !
32 ! Modifications
33 ! -------------
34 ! Juin 2001, D. Paradis, DT/DSI/DEV:
35 !
36 ! -retrait du compactage lorsqu'il conduit a un article de longueur
37 ! superieure a celle obtenue sans le compactage (permet aussi de
38 ! dimensionner PVALCO a ILCHAM+2 sans risquer un debordement)
39 !
40 ! Avril 2004, D. Paradis, DT/DSI/DEV:
41 !
42 ! -declaration de ZCHAMP et ZCHAUX en ALLOCATABLE (gain memoire)
43 !
44 ! January 2010 Trygve Aspelien & Ryad El Khatib :
45 ! - workaround against memory leak on IBM
46 !
47 !
48 !
49 TYPE(fa_com) :: FA
50 INTEGER (KIND=JPLIKB) KREP, KRANG, KLONGD
51 !
52 REAL (KIND=JPDBLR) PCHAMP (*)
53 REAL (KIND=JPDBLD) PVALCO (*)
54 INTEGER (KIND=JPLIKB) KB1PAR (fa%jplb1p)
55 REAL (KIND=JPDBLR) PUNDF
56 !
57 LOGICAL LDCOSP, LDUNDF
58 !
59 CHARACTER CDNOMA*(*)
60 !
61 INTEGER (KIND=JPLIKB) ILCHAM, ISTRIA, IVALC1, IVALC2
62 INTEGER (KIND=JPLIKB) J, IDECAL, ICPACK, IPUILA
63 INTEGER (KIND=JPLIKB) ITRONC, IIND, ILOW, IHIGH, JTRON
64 INTEGER (KIND=JPLIKB) IDIMNC, ILDISP, INBITS, INBITSMAX
65 INTEGER (KIND=JPLIKB) IL, IADD, IRANGC, IARR, IILCHAM
66 INTEGER (KIND=JPLIKB) INMOCC, IERR, INIMES
67 INTEGER (KIND=JPLIKB) INUMER, ITRONC2, ILONGFA
68 INTEGER (KIND=JPLIKB) ILONGSEC, ILONGDATA
69 INTEGER (KIND=JPLIKB) ILONGD
70 !
71 INTEGER (KIND=JPLIKB) IB2PAR (fa%jplb2p)
72 !
73 LOGICAL LLARPE, LLMLAM
74 !
75 CHARACTER(LEN=FA%JPLMES) CLMESS
76 CHARACTER(LEN=FA%JPLSPX) CLNSPR
77 LOGICAL LLFATA
78 REAL (KIND=JPDBLR) :: ZTEMP (2)
79 !
80 REAL (KIND=JPDBLR), ALLOCATABLE :: ZCHAMP (:), ZCHAUX (:)
81 REAL (KIND=JPDBLR) ZAVG
82 INTEGER (KIND=JPLIKB) IAVG
83 
84 !**
85 ! 1. - CONTROLES ET INITIALISATIONS.
86 !-----------------------------------------------------------------------
87 !
88 REAL(KIND=JPRB) :: ZHOOK_HANDLE
89 IF (lhook) CALL dr_hook('FACINE_MT',0,zhook_handle)
90 icpack=0
91 IF (krang.LE.0.OR.krang.GT.fa%JPNXFA) THEN
92  krep=-66
93  GOTO 1001
94 ENDIF
95 !**
96 ! 2. - FABRICATION DE L'ARTICLE A ECRIRE SUR LE FICHIER.
97 !-----------------------------------------------------------------------
98 !
99 ivalc1=fa%FICHIER(krang)%NFGRIB
100 llarpe=ivalc1.EQ.2
101 irangc=fa%FICHIER(krang)%NUCADR
102 llmlam=fa%CADRE(irangc)%LIMLAM
103 ib2par=0
104 !
105 ! Initialisation du nombre de valeurs du champ (ILCHAM)
106 ! du type de champ (IVALC2): spectral/pdg
107 ! du type de representation de donnees (IB2PAR(1))
108 ! du nombre de bits utilises pour le compactage
109 ! de la longueur (en mots de 64 bits) de l'enrobage de l'article
110 ! FA (ILONGFA) + les donnees non compactees (en spectral)
111 ! de la longueur (en octets) des sections 0, 1 et 5 du GRIB
112 ! devant apparaitre dans l'article FA (ILONGSEC)
113 ! de la longueur (en bits) de la section 4 du GRIB (ILONGDATA),
114 ! devant etre un multiple de 16 bits.
115 !
116 IF (jpdbld == jpdblr) THEN
117  inbitsmax = 64
118 ELSE
119  inbitsmax = 32
120 ENDIF
121 !
122 ! ILONGSEC= 4 (S0) + 24 (S1) + 4 (S5) pour le GRIB version 0
123 ilongsec=32
124 IF (ldcosp) THEN
125 !
126  ivalc2=1
127  inbits=min(fa%FICHIER(krang)%NBFCSP, inbitsmax)
128 !
129  IF (llmlam) THEN
130  ib2par(1)=34
131  ilcham=fa%CADRE(irangc)%NSFLAM
132  IF (ivalc1.GT.0) THEN
133 ! calcul du nombre de coefficients non compactes ISTRIA
134  icpack=fa%FICHIER(krang)%NSTROF
135  itronc=fa%CADRE(irangc)%MTRONC
136  itronc2=-fa%CADRE(irangc)%NTYPTR
137  istria=4*(1+itronc+itronc2+(icpack*(icpack-1)/2))
138 !
139  ilongfa=3+2*ivalc1+istria
140 ! Les 88 bits correspondent aux 11 octets d'enrobage GRIB V0 de la section 4
141  ilongdata=(ilcham-istria)*inbits + 88
142  ENDIF
143  ELSE
144  IF (ivalc1.EQ.-1) THEN
145  ilcham=(1+fa%CADRE(irangc)%MTRONC)*(2+fa%CADRE(irangc)%MTRONC)
146  ELSE
147  ilcham=(1+fa%CADRE(irangc)%MTRONC)**2
148  ENDIF
149  ib2par(1)=80
150  IF (ivalc1.GT.0) THEN
151  icpack=fa%FICHIER(krang)%NSTROF
152 ! calcul du nombre de coefficients non compactes IDIMNC
153  idimnc=(1+icpack)**2
154  ilongfa=3+2*ivalc1+idimnc
155 ! Les 144 bits correspondent aux 18 octets d'enrobage GRIB V0 de la section 4
156  ilongdata=ilcham*inbits + idimnc*(32-inbits) + 144
157  ENDIF
158  ENDIF
159 !
160 ELSE
161 !
162  ilcham=fa%CADRE(irangc)%NVAPDG
163  ivalc2=0
164  ib2par(1)=34
165  inbits=min(fa%FICHIER(krang)%NBFPDG, inbitsmax)
166  IF (ivalc1.GT.0) THEN
167  ilongfa=1+2*ivalc1
168 ! Les 88 bits correspondent aux 11 octets d'enrobage GRIB V0 de la section 4
169  ilongdata=ilcham*inbits + 88
170  ENDIF
171 !
172 ENDIF
173 !
174 ! Retrait du compactage si celui-ci s'avere conduire
175 ! a un article plus long qu'en l'absence de compactage:
176 !
177 IF (ivalc1.GT.0) THEN
178 ! Arrondi de ILONGDATA au premier multiple de 16 superieur ou egal
179  ilongdata=16*(1+(ilongdata-1)/16)
180 ! Calcul du nombre de mots (64 bits) de la partie GRIB
181  ilongd=1+(ilongdata+8*ilongsec-1)/64
182 ! On ajoute l'enrobage FA et les eventuelles donnees non compactees
183  ilongd=ilongd+ilongfa
184  IF (ilongd .GT. ((ilcham+jpprcm-1)/jpprcm+2)) THEN ! Should work both for simple & double precision
185 ! WRITE (FA%NULOUT,*)
186 ! S '///// FACINE: the packing of article ',CDNOMA,
187 ! S ' is not done because it will generate'
188 ! WRITE (FA%NULOUT,*)
189 ! S ' a size ( ',ILONGD,' words ) bigger than',
190 ! S ' the one ( ',ILCHAM+2,' words ) obtained without packing.'
191  ivalc1=0
192 ! WRITE (FA%NULOUT,*)
193  ENDIF
194 ENDIF
195 !
196 IF (inbits == inbitsmax) THEN
197  ivalc1 = 0
198 ENDIF
199 !
200 istria = 0
201 !
202 IF (ivalc1.EQ.-1.OR.ivalc1.EQ.0) THEN
203 !
204 ! Cas ou il n'y a aucun codage...
205 ! transfert du tableau d'entree a la suite des 2 valeurs
206 ! documentaires stockees ci-dessus dans PVALCO.
207 !
208  IF (jpdblr == jpdbld) THEN
209  DO j = 1, ilcham
210  pvalco(2+j) = REAL (PCHAMP (J), JPDBLD)
211  ENDDO
212  klongd=2+ilcham
213  ELSE
214  DO j = 1, ilcham, 2
215  ztemp(1) = pchamp(j+0)
216  IF (j+1 <= ilcham) THEN
217  ztemp(2) = pchamp(j+1)
218  ELSE
219  ztemp(2) = 0._jpdblr
220  ENDIF
221  pvalco(2+1+(j-1)/2) = transfer(ztemp(1:2), pvalco(2+1+(j-1)/2))
222  ENDDO
223  klongd=2+(ilcham+1)/2
224  ENDIF
225 !
226 ELSE
227 !
228 ! Cas avec codage GRIB (standard ou non).
229 !
230  ALLOCATE (zchamp(ilcham))
231 !
232  idecal=1+2*ivalc1
233  kb1par(1)=98
234  kb1par(2)=1
235  kb1par(3)=254
236  kb1par(4)=0
237  kb1par(5)=255
238  kb1par(9)=mod(fa%FICHIER(krang)%MADATE(1),100_jplikb )
239 !
240  DO j=2,fa%JPLDAT
241  kb1par(8+j)=fa%FICHIER(krang)%MADATE(j)
242  ENDDO
243 !
244  ib2par(6)=2
245  ipuila=fa%FICHIER(krang)%NPUFLA
246  itronc=fa%CADRE(irangc)%MTRONC
247 !
248  IF (ldcosp) THEN
249 !
250 ! Champ en coefficients spectraux... traitement particulier,
251 ! lie a la possibilite de compacter une (pseudo-)puissance de
252 ! laplacien du champ a la place du champ, de maniere a augmenter
253 ! la precision du champ en "aplanissant" le spectre.
254 !
255  CALL facsim_fort (fa, krep,krang,pchamp,zchamp,ipuila,icpack)
256  IF (fa%LFAMOP) THEN
257  print *,'FACINE: puissance Dolby selectionnee ',ipuila
258  ENDIF
259  IF (krep.NE.0) GOTO 1001
260  IF (llmlam) THEN
261 ! Copy the elements to be compacted from ZCHAMP to a work array
262 ! This is that part of the quarter-ellipse which is out of the triangle of no compacting.
263 ! In addition, the axes of ellipse are also excluded because of zero-coefficients
264  ALLOCATE (zchaux(ilcham))
265  iind=0
266 !
267  DO jtron=1,itronc
268  ilow=2+2*jtron+1
269  iadd=4* max(icpack+1-jtron,1_jplikb )
270 !
271  DO j=fa%CADRE(irangc)%NOZPAR(ilow)+iadd, &
272 & fa%CADRE(irangc)%NOZPAR(ilow+1)
273  iind=iind+1
274  zchaux(iind)=zchamp(j)
275  ENDDO
276  ENDDO
277 ! Number of elements in sub-triangle+axes:ISTRIA
278  istria=ilcham-iind
279  idimnc=0
280  ELSE
281  istria=idimnc
282  ENDIF
283 !
284  idecal=idecal+2
285  ildisp=ilcham+2-idecal-(ivalc1-1)*istria
286 !
287  IF (.NOT.llarpe) THEN
288 !
289 ! Recopie des coefficients spectraux "non compactes",
290 ! qui sont codes en fait sur 32 bits dans le cas standard de GRIB.
291 !
292  DO j=1,idimnc
293  zchamp(j)=pchamp(j)
294  ENDDO
295 !
296  ENDIF
297 !
298  ELSE
299 !
300 ! Transfert du tableau d'entree dans un tableau local
301 ! de maniere a eviter l'ecrasement du tableau d'entree par "CODEGA".
302 !
303  DO j=1,ilcham
304  zchamp(j)=pchamp(j)
305  ENDDO
306 !
307 ! Si des valeurs indefinies sont presentes, alors on les remplace
308 ! par la moyenne des valeurs definies
309 !
310  IF (ldundf) THEN
311  zavg = 0._jpdblr
312  iavg = 0
313  DO j = 1, ilcham
314  IF (pchamp(j) /= pundf) THEN
315  zavg = zavg + pchamp(j)
316  iavg = iavg + 1
317  ENDIF
318  ENDDO
319  IF (iavg > 0) THEN
320  zavg = zavg / iavg
321  ELSE
322  zavg = 0._jpdblr
323  ENDIF
324  DO j = 1, ilcham
325  IF (pchamp(j) == pundf) THEN
326  zchamp(j) = zavg
327  ENDIF
328  ENDDO
329  ENDIF
330 
331 !
332  idimnc=0
333  ildisp=ilcham+2-idecal
334  ENDIF
335 !*
336 ! 3.1 - CODAGE GRIB PROPREMENT DIT.
337 !-----------------------------------------------------------------------
338 !
339  iarr=0
340 !
341  IF (ldcosp.AND.llmlam) THEN
342  iilcham=ilcham-istria
343  CALL facodega(zchaux,iilcham,inbits,fa%NBIMAC,kb1par, &
344 & ib2par,fa%CADRE(irangc)%SFOHYB(1,0),2_jplikb , &
345 & pvalco(idecal+1),ildisp,inmocc,iarr, &
346 & 0_jplikb ,ipuila,ierr,pvalco(idecal-1), &
347 & pvalco(idecal),llarpe)
348  ELSE
349  CALL facodega(zchamp,ilcham,inbits,fa%NBIMAC,kb1par,ib2par, &
350 & fa%CADRE(irangc)%SFOHYB(1,0),2_jplikb , &
351 & pvalco(idecal+1),ildisp,inmocc,iarr,icpack, &
352 & ipuila,ierr,pvalco(idecal-1),pvalco(idecal), &
353 & llarpe)
354  ENDIF
355 !
356  IF (ierr.NE.0) THEN
357  krep=-200+ierr
358  GOTO 1001
359  ELSEIF (ldcosp) THEN
360  pvalco(4)=transfer(icpack, pvalco(4))
361  pvalco(5)=transfer(ipuila, pvalco(5))
362 !
363  IF (llarpe) THEN
364 !*
365 ! 3.2 - TRANSFERT DES COEFFICIENTS SPECTRAUX NON COMPACTES.
366 !-----------------------------------------------------------------------
367 ! (et non traites par CODEGA) en fin d'article.
368 !
369  IF (llmlam) THEN
370 ! Copy nonpacked part of kchamp (sub-triangle+axes) into zchaux
371  iind=0
372 !
373  DO jtron=0,itronc
374  il=2+2*jtron+1
375  ilow=fa%CADRE(irangc)%NOZPAR(il)
376 !
377  IF (jtron.EQ.0) THEN
378  ihigh=fa%CADRE(irangc)%NOZPAR(il+1)
379  ELSE
380  ihigh=ilow+4*(icpack+1-jtron)-1
381  IF (ihigh.LE.ilow) ihigh=ilow+3
382  ENDIF
383 !
384  DO j=ilow,ihigh
385  iind=iind+1
386  zchaux(iind)=pchamp(j)
387  ENDDO
388  ENDDO
389 !
390  DO j=1,istria
391  pvalco(idecal+inmocc+j)=zchaux(j)
392  ENDDO
393 !
394  ELSE
395 !
396  DO j=1,idimnc
397  pvalco(idecal+inmocc+j)=REAL (PCHAMP(J), JPDBLD)
398  ENDDO
399 !
400  ENDIF
401 !
402  ENDIF
403 !
404  ENDIF
405 !
406  pvalco(3)=transfer(inbits, pvalco(3))
407 !
408  IF (llmlam) THEN
409  klongd=idecal+inmocc+istria
410  ELSE
411  klongd=idecal+inmocc+idimnc
412  ENDIF
413 !
414 ENDIF
415 !
416 IF (ivalc1 == 0 .AND. (jpdblr /= jpdbld)) ivalc1 = -2
417 pvalco(1)=transfer(ivalc1, pvalco(1))
418 pvalco(2)=transfer(ivalc2, pvalco(2))
419 !**
420 ! 10. - PHASE TERMINALE : MESSAGERIE, AVEC "ABORT" EVENTUEL,
421 ! VIA LE SOUS-PROGRAMME "FAIPAR" .
422 !-----------------------------------------------------------------------
423 !
424 1001 CONTINUE
425 llfata=llmoer(krep,krang)
426 !
427 IF (fa%LFAMOP.OR.llfata) THEN
428  inimes=2
429  clnspr='FACINE'
430  inumer=jpniil
431 !
432  WRITE (unit=clmess,fmt='(''KREP='',I4,'', KRANG='',I4, &
433 & '', CDNOMA='''''',A,'''''', LDCOSP= '',L1, &
434 & '', KLONGD='',I8)') &
435 & krep, krang, cdnoma, ldcosp, klongd
436  CALL faipar_fort &
437 & (fa, inumer,inimes,krep,.false.,clmess, &
438 & clnspr, cdnoma,.false.)
439 ENDIF
440 !
441 IF (lhook) CALL dr_hook('FACINE_MT',1,zhook_handle)
442 
443 CONTAINS
444 
445 #include "facom2.llmoer.h"
446 
447 END SUBROUTINE facine_fort
448 !INTF KREP OUT
449 !INTF KRANG IN
450 !INTF CDNOMA IN
451 !INTF PCHAMP IN DIMS=*
452 !INTF LDCOSP IN
453 !INTF PVALCO OUT DIMS=*
454 !INTF KLONGD OUT
455 !INTF KB1PAR INOUT DIMS=FA%JPLB1P
456 !INTF LDUNDF IN
457 !INTF PUNDF IN
458 
subroutine facsim_fort(FA, KREP, KRANG, PCHAME, PCHAMS, KPULAS, KSTRON)
Definition: facsim.F90:6
subroutine facodega(PFDATA, KLENF, KBITS, KNBIT, KB1PAR, KB2PAR, PVERT, KLENV, KGRIB, KLENG, KWORD, KROUND, KCPACK, KSCALP, KERR, PMIN, PMAX, LDARPE)
Definition: facodega.F90:6
integer, parameter jpdbld
Definition: fa_mod.F90:1
integer, parameter jprb
Definition: parkind1.F90:32
integer(kind=jplikb), parameter jpprcm
Definition: fa_mod.F90:26
integer, parameter jpdblr
subroutine facine_fort(FA, KREP, KRANG, CDNOMA, PCHAMP, LDCOSP, PVALCO, KLONGD, KB1PAR, LDUNDF, PUNDF)
Definition: facine.F90:7
logical lhook
Definition: yomhook.F90:15
subroutine faipar_fort(FA, KNUMER, KNIMES, KCODE, LDFATA, CDMESS, CDNSPR, CDACTI, LDRLFI)
Definition: faipar.F90:6
integer(kind=jplikb), parameter jpniil
Definition: fa_mod.F90:31