--- trunk/libf/filtrez/filtreg.f90 2010/04/06 17:52:58 32 +++ trunk/Sources/filtrez/filtreg.f 2015/04/29 15:47:56 134 @@ -4,49 +4,31 @@ contains - SUBROUTINE filtreg(champ, nlat, nbniv, ifiltre, iaire, griscal, iter) + SUBROUTINE filtreg(champ, direct, intensive) ! From filtrez/filtreg.F, version 1.1.1.1, 2004/05/19 12:53:09 - ! Author: P. Le Van - ! Objet : filtre matriciel longitudinal, avec les matrices précalculées - ! pour l'opérateur filtre. - - USE dimens_m, ONLY : iim, jjm - USE parafilt, ONLY: matriceun, matriceus, matricevn, matricevs, matrinvn, & - matrinvs - USE coefils, ONLY : jfiltnu, jfiltnv, jfiltsu, jfiltsv, sddu, sddv, & - unsddu, unsddv - - INTEGER, intent(in):: nlat ! nombre de latitudes a filtrer - integer, intent(in):: nbniv ! nombre de niveaux verticaux a filtrer - - REAL, intent(inout):: champ(iim + 1, nlat, nbniv) - ! en entrée : champ à filtrer, en sortie : champ filtré - - integer, intent(in):: ifiltre - ! +1 Transformee directe - ! -1 Transformee inverse - ! +2 Filtre directe - ! -2 Filtre inverse - ! Variable Intensive - ! ifiltre = 1 filtre directe - ! ifiltre =-1 filtre inverse - ! Variable Extensive - ! ifiltre = 2 filtre directe - ! ifiltre =-2 filtre inverse - - integer, intent(in):: iaire - ! 1 si champ intensif - ! 2 si champ extensif (pondere par les aires) - - integer, intent(in):: iter - ! 1 filtre simple - - LOGICAL, intent(in):: griscal - - ! Variables local to the procedure: + ! Objet : filtre matriciel longitudinal, avec les matrices pr\'ecalcul\'ees + ! pour l'op\'erateur filtre. + USE coefils, ONLY: sddu, sddv, unsddu, unsddv + USE dimens_m, ONLY: iim, jjm + use inifilr_m, only: jfiltnu, jfiltnv, jfiltsu, jfiltsv, matriceun, & + matriceus, matricevn, matricevs, matrinvn, matrinvs + use nr_util, only: assert + + REAL, intent(inout):: champ(:, :, :) ! (iim + 1, nlat, nbniv) + ! en entr\'ee : champ \`a filtrer, en sortie : champ filtr\'e + + logical, intent(in):: direct ! filtre direct ou inverse + + logical, intent(in):: intensive + ! champ intensif ou extensif (pond\'er\'e par les aires) + + ! Local: + LOGICAL griscal + INTEGER nlat ! nombre de latitudes \`a filtrer + integer nbniv ! nombre de niveaux verticaux \`a filtrer INTEGER jdfil1, jdfil2, jffil1, jffil2, jdfil, jffil INTEGER i, j, l, k REAL eignq(iim), sdd1(iim), sdd2(iim) @@ -54,70 +36,46 @@ !----------------------------------------------------------- - IF (ifiltre==1 .OR. ifiltre==-1) STOP & - 'Pas de transformee simple dans cette version' - - IF (iter==2) THEN - PRINT *, ' Pas d iteration du filtre dans cette version !', & - ' Utiliser old_filtreg et repasser !' - STOP - END IF - - IF (ifiltre==-2 .AND. .NOT. griscal) THEN - PRINT *, ' Cette routine ne calcule le filtre inverse que ', & - ' sur la grille des scalaires !' - STOP - END IF - - IF (ifiltre/=2 .AND. ifiltre/=-2) THEN - PRINT *, ' Probleme dans filtreg car ifiltre NE 2 et NE -2', & - ' corriger et repasser !' - STOP + call assert(size(champ, 1) == iim + 1, "filtreg iim + 1") + nlat = size(champ, 2) + nbniv = size(champ, 3) + call assert(nlat == jjm .or. nlat == jjm + 1, "filtreg nlat") + griscal = nlat == jjm + 1 + + IF (.not. direct .AND. nlat == jjm) THEN + PRINT *, 'filtreg: inverse filter on scalar grid only' + STOP 1 END IF IF (griscal) THEN - IF (nlat /= jjm + 1) THEN - PRINT 1111 - STOP + IF (intensive) THEN + sdd1 = sddv + sdd2 = unsddv ELSE - - IF (iaire==1) THEN - sdd1 = sddv - sdd2 = unsddv - ELSE - sdd1 = unsddv - sdd2 = sddv - END IF - - jdfil1 = 2 - jffil1 = jfiltnu - jdfil2 = jfiltsu - jffil2 = jjm + sdd1 = unsddv + sdd2 = sddv END IF + + jdfil1 = 2 + jffil1 = jfiltnu + jdfil2 = jfiltsu + jffil2 = jjm ELSE - IF (nlat/=jjm) THEN - PRINT 2222 - STOP + IF (intensive) THEN + sdd1 = sddu + sdd2 = unsddu ELSE - - IF (iaire==1) THEN - sdd1 = sddu - sdd2 = unsddu - ELSE - sdd1 = unsddu - sdd2 = sddu - END IF - - jdfil1 = 1 - jffil1 = jfiltnv - jdfil2 = jfiltsv - jffil2 = jjm + sdd1 = unsddu + sdd2 = sddu END IF - END IF + jdfil1 = 1 + jffil1 = jfiltnv + jdfil2 = jfiltsv + jffil2 = jjm + END IF - DO hemisph = 1, 2 - + loop_hemisph: DO hemisph = 1, 2 IF (hemisph==1) THEN jdfil = jdfil1 jffil = jffil1 @@ -126,21 +84,16 @@ jffil = jffil2 END IF - - DO l = 1, nbniv - DO j = jdfil, jffil - - + loop_vertical: DO l = 1, nbniv + loop_latitude: DO j = jdfil, jffil DO i = 1, iim champ(i, j, l) = champ(i, j, l)*sdd1(i) END DO - IF (hemisph==1) THEN - - IF (ifiltre==-2) THEN + IF (.not. direct) THEN DO k = 1, iim - eignq(k) = 0.0 + eignq(k) = 0. END DO DO k = 1, iim DO i = 1, iim @@ -149,7 +102,7 @@ END DO ELSE IF (griscal) THEN DO k = 1, iim - eignq(k) = 0.0 + eignq(k) = 0. END DO DO i = 1, iim DO k = 1, iim @@ -159,7 +112,7 @@ END DO ELSE DO k = 1, iim - eignq(k) = 0.0 + eignq(k) = 0. END DO DO i = 1, iim DO k = 1, iim @@ -168,12 +121,10 @@ END DO END DO END IF - ELSE - - IF (ifiltre==-2) THEN + IF (.not. direct) THEN DO k = 1, iim - eignq(k) = 0.0 + eignq(k) = 0. END DO DO i = 1, iim DO k = 1, iim @@ -183,7 +134,7 @@ END DO ELSE IF (griscal) THEN DO k = 1, iim - eignq(k) = 0.0 + eignq(k) = 0. END DO DO i = 1, iim DO k = 1, iim @@ -193,7 +144,7 @@ END DO ELSE DO k = 1, iim - eignq(k) = 0.0 + eignq(k) = 0. END DO DO i = 1, iim DO k = 1, iim @@ -202,10 +153,9 @@ END DO END DO END IF - END IF - IF (ifiltre==2) THEN + IF (direct) THEN DO i = 1, iim champ(i, j, l) = (champ(i, j, l)+eignq(i))*sdd2(i) end DO @@ -216,17 +166,9 @@ END IF champ(iim + 1, j, l) = champ(1, j, l) - - END DO - - END DO - - end DO - -1111 FORMAT (//20X, 'ERREUR dans le dimensionnement du tableau & - & CHAMP a filtrer, sur la grille des scalaires'/) -2222 FORMAT (//20X, 'ERREUR dans le dimensionnement du tableau & - &CHAMP a filtrer, sur la grille de V ou de Z'/) + END DO loop_latitude + END DO loop_vertical + end DO loop_hemisph END SUBROUTINE filtreg