Oasis3 4.0.2
cookart.f
Go to the documentation of this file.
00001       SUBROUTINE cookart (kindex, kfield)
00002 C****
00003 C               *****************************
00004 C               * OASIS ROUTINE  -  LEVEL 1 *
00005 C               * -------------     ------- *
00006 C               *****************************
00007 C
00008 C**** *cookart* - More or less clever stuff
00009 C
00010 C
00011 C     Purpose:
00012 C     -------
00013 C     Do subgrid variability, flux conservation or
00014 C     stupid basic linear algebra stuff
00015 C
00016 C**   Interface:
00017 C     ---------
00018 C       *CALL*  *cookart (kindex, kfield)*
00019 C
00020 C     Input:
00021 C     -----
00022 C       kindex : field identificator array (integer 1D)
00023 C       kfield : number of fields for current iteration (integer)
00024 C
00025 C     Output:
00026 C     ------
00027 C     None
00028 C
00029 C     Workspace:
00030 C     ---------
00031 C        zbncoef : additional field coefficients for blasnew (real 1D)
00032 C        iaddr   : memory allocation of the work array (integer 1D)
00033 C        isize   : memory allocation of the work array (integer 1D)
00034 C        iflag   : memory allocation of the work array (integer 1D)
00035 C        clbnfld : additional field names for blasnew (character 1D)
00036 C
00037 C     Externals:
00038 C     ---------
00039 C     conserv, subgrid, blasnew
00040 C
00041 C     Reference:
00042 C     ---------
00043 C     See OASIS manual (1995)
00044 C
00045 C     History:
00046 C     -------
00047 C       Version   Programmer     Date      Description
00048 C       -------   ----------     ----      -----------  
00049 C       2.0       L. Terray      95/09/01  created
00050 C       2.1       L. terray      96/08/05  modified: subgrid analysis
00051 C       2.3       S. Valcke      99/04/30  added: printing levels
00052 C
00053 C %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00054 C
00055 C* --------------- Include files and USE of modules---------------------------
00056 C
00057       USE mod_unit
00058       USE mod_parameter
00059       USE mod_string
00060       USE mod_analysis
00061       USE mod_memory
00062       USE mod_rainbow
00063       USE mod_printing
00064 C
00065 C* ---------------------------- Argument declarations -------------------
00066 C
00067       INTEGER (kind=ip_intwp_p) kindex(kfield)
00068 C
00069 C* ---------------------------- Local declarations ----------------------
00070 C
00071       REAL (kind=ip_realwp_p), DIMENSION(:), ALLOCATABLE :: zbncoef
00072       INTEGER (kind=ip_intwp_p), DIMENSION(:), ALLOCATABLE :: iaddr, 
00073      $    isize, iflag
00074       INTEGER (kind=ip_intwp_p) :: il_err
00075       CHARACTER(len=8),DIMENSION(:), ALLOCATABLE :: clbnfld 
00076       CHARACTER*8 clconmet, clname,  cldqdt
00077       CHARACTER*8 clfldcoa, clfldfin, clfic
00078       LOGICAL lli, llj, llk, llt
00079 C
00080 C* ---------------------------- Poema verses ----------------------------
00081 C
00082 C %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00083 C
00084 C*    1. Initialization and allocation of local arrays
00085 C        ---------------------------------------------
00086 C
00087       IF (nlogprt .GE. 2) THEN
00088           WRITE (UNIT = nulou,FMT = *) ' '
00089           WRITE (UNIT = nulou,FMT = *) ' '
00090           WRITE (UNIT = nulou,FMT = *) 
00091      $    '            ROUTINE cookart  -  Level 1'
00092           WRITE (UNIT = nulou,FMT = *) 
00093      $    '            ***************     *******'
00094           WRITE (UNIT = nulou,FMT = *) ' '
00095           WRITE (UNIT = nulou,FMT = *) 
00096      $    ' Subgrid variability, blas and flux conservation '
00097           WRITE (UNIT = nulou,FMT = *) ' '
00098           CALL FLUSH(nulou)
00099       ENDIF
00100 C
00101       ALLOCATE (zbncoef(ig_maxcomb),stat=il_err)
00102       IF (il_err.NE.0) CALL prtout (
00103 'Error in "zbncoef" allocation of      $    cookart ',il_err,1)
00104       zbncoef(:)=0
00105       ALLOCATE (iaddr(0:ig_maxcomb),stat=il_err)
00106       IF (il_err.NE.0) CALL prtout (
00107 'Error in "iaddr" allocation of      $    cookart ',il_err,1)
00108       iaddr(:)=0
00109       ALLOCATE (isize(0:ig_maxcomb),stat=il_err)
00110       IF (il_err.NE.0) CALL prtout (
00111 'Error in "isize" allocation of      $    cookart ',il_err,1)
00112       isize(:)=0
00113       ALLOCATE (iflag(ig_maxcomb),stat=il_err)
00114       IF (il_err.NE.0) CALL prtout (
00115 'Error in "iflag" allocation of      $    cookart ',il_err,1)
00116       iflag(:)=0
00117       ALLOCATE (clbnfld(ig_maxcomb),stat=il_err)
00118       IF (il_err.NE.0) CALL prtout (
00119 'Error in "clbnfld" allocation of      $    cookart ',il_err,1)
00120       clbnfld(:)=' '
00121 C
00122 
00123 C*    2. Do the job
00124 C        ----------
00125 C
00126       DO 210 jf = 1, kfield
00127 C
00128 C* Assign local variables
00129 C
00130         ifield = kindex(jf)
00131         iadrold = nadrold(ifield)
00132         iadrold_grid = nadrold_grid(ifield)
00133         isizold = nsizold(ifield)
00134         iadrnew = nadrnew(ifield)
00135         iadrnew_grid = nadrnew_grid(ifield)
00136         isiznew = nsiznew(ifield)
00137         clname = cnamout(ifield)
00138 C
00139 C* Print field name
00140 C
00141         IF (nlogprt .GE. 1) THEN 
00142             CALL prcout('Treatment of field : ', clname, 2)
00143         ENDIF
00144 C
00145 C* - Do additional analysis
00146 C
00147         DO 220 ja = 1, ig_ntrans(ifield)
00148 C
00149 C* --->>> Flux conservation
00150 C
00151           IF (canal(ja,ifield) .EQ. 'CONSERV') THEN
00152 C
00153 C* Zero work array
00154 C
00155               CALL szero (work, ig_work)
00156 C
00157 C* Get conservation method and do the job
00158 C
00159               clconmet = cconmet(ifield)
00160               CALL conserv (fldold(iadrold), isizold,
00161      $                      mskold(iadrold_grid), surold(iadrold_grid),
00162      $                      fldnew(iadrnew), isiznew,
00163      $                      msknew(iadrnew_grid), surnew(iadrnew_grid),
00164      $                      work(1), work(1+isizold), clconmet)
00165 C
00166 C* --->>> Subgrid variability
00167 C
00168 C* We have to estimate  Fo = sum_a{ B(o,a)*(Fa + dFa/dTa * (To - Ta))}
00169 C  a and o mean coarse and fine grid respectively 
00170 C  with To on the fine grid initially
00171 C
00172             ELSE IF (canal(ja,ifield) .EQ. 'SUBGRID') THEN
00173 C
00174 C* Zero work array
00175 C
00176               CALL szero (work, ig_work)
00177 C
00178 C* Get names for fields on both fine and coarse grids
00179 C
00180               clfldcoa = cfldcoa(ifield)
00181               clfldfin = cfldfin(ifield)
00182 C
00183 C* No coupling ratio needed unless subgrid deals with non solar flux
00184 C  Initialize anyway local variable cldqdt
00185 C
00186               cldqdt = 'NONE'
00187               IF (ctypsub(ifield) .EQ. 'NONSOLAR') THEN 
00188                   cldqdt = cdqdt(ifield)
00189               ENDIF
00190 C
00191 C* In order not to have problems for solar flux for the dimension checks
00192 C 
00193               itot3 = isizold
00194 C
00195 C* Look for field data
00196 C
00197               DO 230 jn = 1, ig_nfield
00198 C
00199 C* Find Ta field: initially on coarse grid
00200 C  The Ta field is in fact the To field 
00201 C  which has been interpolated at the previous timestep
00202 C
00203                 IF (cnaminp(jn) .EQ. clfldcoa) THEN
00204                     iadr1 = nadrold(jn)
00205                     itot1 = nsizold(jn)
00206 C
00207 C* Find additional field To on fine grid
00208 C
00209                   ELSE IF (cnaminp(jn) .EQ. clfldfin) THEN
00210                     iadr2 = nadrold(jn)
00211                     itot2 = nsizold(jn)
00212 C
00213 C* Find dFa/dTa field :initially on coarse grid, corresponding to 
00214 C  the previous timestep
00215 C
00216                   ELSE IF (cnaminp(jn) .EQ. cldqdt) THEN
00217                     iadr3 = nadrold(jn)
00218                     itot3 = nsizold(jn)
00219                 ENDIF
00220  230          CONTINUE
00221 C* Get Ta
00222               DO 231 ji = 1, itot1
00223                 work(ji) = fldold(iadr1-1+ji)
00224  231          CONTINUE 
00225 C* Get To
00226               DO 232 ji = 1, itot2
00227                 work(itot1+ji) = fldold(iadr2-1+ji)
00228  232          CONTINUE
00229 C* Get dFa/dTa only if we deal with non solar flux
00230               IF (ctypsub(jf) .EQ. 'NONSOLAR') THEN 
00231                   DO 234 ji = 1, itot3
00232                     work(itot1+itot2+ji) = fldold(iadr3-1+ji)
00233  234              CONTINUE
00234               ENDIF 
00235 C
00236 C* Check sizes
00237 C
00238               lli = isizold .EQ. itot1
00239               llj = isiznew .EQ. itot2
00240               llk = isizold .EQ. itot3
00241               IF (.NOT. lli) CALL prcout(
00242 'WARNING: size mismatch     $            between coarse and initial field',clname,2)
00243               IF (.NOT. llj) CALL prcout(
00244 'WARNING: size mismatch     $            between final and fine field',clname,2)
00245               IF (.NOT. llk) CALL prcout(
00246 'WARNING: size mismatch     $            between coarse and dqdt field',clname,2)
00247               llt = lli .AND. llj .AND. llk
00248               IF (.NOT. llt) CALL HALTE('STOP in cookart')
00249 C
00250 C* Do the subgrid interpolation
00251 C
00252 C* assign local variables and get pointer for subgrid interpolation
00253 C
00254               clfic = cgrdsub(ifield)
00255               iunit = nlusub(ifield)
00256               iloc = nsubfl(ifield)
00257               ivoisin = nsubvoi(ifield)
00258               ipdeb = (nsubfl(ifield)-1)*ig_maxsoa*ig_maxgrd+1
00259               CALL subgrid (fldnew(iadrnew), fldold(iadrold),
00260      $                      isiznew, isizold,
00261      $                      work(1), work(1+isizold), 
00262      $                      work(1+isizold+isiznew),
00263      $                      clfic, iunit, iloc, clname,
00264      $                      asubg(ipdeb), nsubg(ipdeb),
00265      $                      ivoisin, lsubg(ifield), ctypsub(ifield))
00266 C
00267 C* --->>> Blasnew
00268 C
00269             ELSE IF (canal(ja,ifield) .EQ. 'BLASNEW') THEN
00270 C
00271 C* Assign local variables to main field coefficient and number of extra fields
00272 C
00273               zfldcobn = afldcobn(ifield)
00274               ibnfld = nbnfld(ifield)
00275 C
00276 C* Read in additional field names and related coefficients
00277 C
00278               DO 240 jc = 1, ibnfld
00279                 clbnfld(jc) = cbnfld(jc,ifield)
00280                 zbncoef(jc) = abncoef(jc,ifield)
00281  240          CONTINUE
00282 C
00283 C* - Get the additional fields parameters (pointers and sizes)
00284 C
00285               CALL szero( work, ig_work)
00286               DO 250 jc = 1, ibnfld
00287 C
00288 C* Constant fields
00289 C
00290                 IF (clbnfld(jc) .EQ. 'CONSTANT') THEN
00291                     isize(jc) = isiznew
00292                 ELSE
00293 C
00294 C* Others
00295 C 
00296                     DO 260 jb = 1, ig_nfield
00297 C
00298 C* Check field names input list
00299 C
00300                       IF (clbnfld(jc) .EQ. cnamout(jb)) THEN
00301                           iflag(jc) = jb
00302                       ENDIF 
00303  260                CONTINUE
00304                     ipointer  = nadrnew(iflag(jc))
00305                     isize(jc) = nsiznew(iflag(jc))
00306                 ENDIF 
00307 C
00308 C* Get memory adresses for array work
00309 C
00310                 IF (jc .EQ. 1) THEN
00311                     iaddr(jc) = 1
00312                 ELSE
00313                     iaddr(jc) = 1 + isize(jc-1)
00314                 ENDIF
00315 C
00316 C* Assign values to temporary array work
00317 C
00318                 IF (clbnfld(jc) .EQ. 'CONSTANT') THEN
00319                     DO 270 jd = 1, isize(jc)
00320                       work(iaddr(jc)+jd-1) = 1.0
00321  270                CONTINUE 
00322                 ELSE 
00323                     DO 280 jd = 1, isize(jc)
00324                       work(iaddr(jc)+jd-1) = fldnew(ipointer+jd-1)
00325  280                CONTINUE 
00326                 ENDIF 
00327  250          CONTINUE
00328 C
00329 C* Get total size for array work ( sum of additional fields sizes)
00330 C
00331               isiztot = iaddr(ibnfld) + isize(ibnfld) - 1
00332               CALL blasnew (fldnew(iadrnew), isiznew, ifield,
00333      $                      zfldcobn, ibnfld, iaddr, isize,
00334      $                      zbncoef, isiztot, work)
00335           ELSE
00336               CONTINUE 
00337           END IF
00338  220    CONTINUE
00339  210  CONTINUE 
00340 C
00341 C
00342 C*    3. Deallocation and end of routine
00343 C        -------------------------------
00344 C
00345       DEALLOCATE (zbncoef)
00346       DEALLOCATE (iaddr)
00347       DEALLOCATE (isize)
00348       DEALLOCATE (iflag)
00349       DEALLOCATE (clbnfld)
00350 C
00351       IF (nlogprt .GE. 2) THEN
00352           WRITE (UNIT = nulou,FMT = *) ' '
00353           WRITE (UNIT = nulou,FMT = *) 
00354      $    '          --------- End of ROUTINE cookart ---------'
00355           CALL FLUSH (nulou)
00356       ENDIF
00357       RETURN
00358       END
 All Data Structures Namespaces Files Functions Variables Defines