Oasis3 4.0.2
|
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