! $Header$ SUBROUTINE groupeun(jjmax, llmax, q) USE comconst_mod, ONLY: ngroup IMPLICIT NONE include "dimensions.h" include "paramet.h" include "comgeom2.h" INTEGER :: jjmax, llmax REAL :: q(iip1, jjmax, llmax) ! INTEGER ngroup ! PARAMETER (ngroup=3) REAL :: airecn, qn REAL :: airecs, qs INTEGER :: i, j, l, ig, ig2, j1, j2, i0, jd !--------------------------------------------------------------------c ! Strategie d'optimisation c ! stocker les valeurs systematiquement recalculees c ! et identiques d'un pas de temps sur l'autre. Il s'agit des c ! aires des cellules qui sont sommees. S'il n'y a pas de changement c ! de grille au cours de la simulation tout devrait bien se passer. c ! Autre optimisation : determination des bornes entre lesquelles "j" c ! varie, au lieu de faire un test à chaque fois... !--------------------------------------------------------------------c INTEGER :: j_start, j_finish REAL, SAVE :: airen_tab(iip1, jjp1, 0:1) REAL, SAVE :: aires_tab(iip1, jjp1, 0:1) LOGICAL, SAVE :: first = .TRUE. ! INTEGER,SAVE :: i_index(iim,ngroup) INTEGER :: offset ! REAL :: qsum(iim/ngroup) IF (first) THEN CALL INIT_GROUPEUN(airen_tab, aires_tab) first = .FALSE. ENDIF ! Champs 3D jd = jjp1 - jjmax !$OMP DO SCHEDULE(STATIC,OMP_CHUNK) DO l = 1, llm j1 = 1 + jd j2 = 2 DO ig = 1, ngroup ! Concerne le pole nord j_start = j1 - jd j_finish = j2 - jd DO ig2 = 1, ngroup - ig + 1 offset = 2**(ig2 - 1) DO j = j_start, j_finish !CDIR NODEP !CDIR ON_ADB(q) DO i0 = 1, iim, 2**ig2 q(i0, j, l) = q(i0, j, l) + q(i0 + offset, j, l) ENDDO ENDDO ENDDO DO j = j_start, j_finish !CDIR NODEP !CDIR ON_ADB(q) DO i = 1, iim q(i, j, l) = q(i - MOD(i - 1, 2**(ngroup - ig + 1)), j, l) ENDDO ENDDO DO j = j_start, j_finish !CDIR ON_ADB(airen_tab) !CDIR ON_ADB(q) DO i = 1, iim q(i, j, l) = q(i, j, l) * airen_tab(i, j, jd) ENDDO q(iip1, j, l) = q(1, j, l) ENDDO !c Concerne le pole sud j_start = j1 - jd j_finish = j2 - jd DO ig2 = 1, ngroup - ig + 1 offset = 2**(ig2 - 1) DO j = j_start, j_finish !CDIR NODEP !CDIR ON_ADB(q) DO i0 = 1, iim, 2**ig2 q(i0, jjp1 - j + 1 - jd, l) = q(i0, jjp1 - j + 1 - jd, l) & + q(i0 + offset, jjp1 - j + 1 - jd, l) ENDDO ENDDO ENDDO DO j = j_start, j_finish !CDIR NODEP !CDIR ON_ADB(q) DO i = 1, iim q(i, jjp1 - j + 1 - jd, l) = q(i - MOD(i - 1, 2**(ngroup - ig + 1)), & jjp1 - j + 1 - jd, l) ENDDO ENDDO DO j = j_start, j_finish !CDIR ON_ADB(aires_tab) !CDIR ON_ADB(q) DO i = 1, iim q(i, jjp1 - j + 1 - jd, l) = q(i, jjp1 - j + 1 - jd, l) * & aires_tab(i, jjp1 - j + 1, jd) ENDDO q(iip1, jjp1 - j + 1 - jd, l) = q(1, jjp1 - j + 1 - jd, l) ENDDO j1 = j2 + 1 j2 = j2 + 2**ig ENDDO ENDDO !$OMP END DO NOWAIT RETURN END SUBROUTINE groupeun SUBROUTINE INIT_GROUPEUN(airen_tab, aires_tab) USE comconst_mod, ONLY: ngroup IMPLICIT NONE include "dimensions.h" include "paramet.h" include "comgeom2.h" ! INTEGER ngroup ! PARAMETER (ngroup=3) REAL :: airen, airecn REAL :: aires, airecs INTEGER :: i, j, l, ig, j1, j2, i0, jd INTEGER :: j_start, j_finish REAL :: airen_tab(iip1, jjp1, 0:1) REAL :: aires_tab(iip1, jjp1, 0:1) DO jd = 0, 1 j1 = 1 + jd j2 = 2 DO ig = 1, ngroup ! c Concerne le pole nord j_start = j1 - jd j_finish = j2 - jd DO j = j_start, j_finish DO i0 = 1, iim, 2**(ngroup - ig + 1) airen = 0. DO i = i0, i0 + 2**(ngroup - ig + 1) - 1 airen = airen + aire(i, j) ENDDO DO i = i0, i0 + 2**(ngroup - ig + 1) - 1 airen_tab(i, j, jd) = & aire(i, j) / airen ENDDO ENDDO ENDDO ! c Concerne le pole sud j_start = j1 - jd j_finish = j2 - jd DO j = j_start, j_finish DO i0 = 1, iim, 2**(ngroup - ig + 1) aires = 0. DO i = i0, i0 + 2**(ngroup - ig + 1) - 1 aires = aires + aire(i, jjp1 - j + 1) ENDDO DO i = i0, i0 + 2**(ngroup - ig + 1) - 1 aires_tab(i, jjp1 - j + 1, jd) = & aire(i, jjp1 - j + 1) / aires ENDDO ENDDO ENDDO j1 = j2 + 1 j2 = j2 + 2**ig ENDDO ENDDO RETURN END SUBROUTINE INIT_GROUPEUN