*IF DEF,OCEAN OLBCFRS1.2 C *****************************COPYRIGHT****************************** OLBCFRS1.3 C (c) CROWN COPYRIGHT 1998, METEOROLOGICAL OFFICE, All Rights Reserved. OLBCFRS1.4 C OLBCFRS1.5 C Use, duplication or disclosure of this code is subject to the OLBCFRS1.6 C restrictions as set forth in the contract. OLBCFRS1.7 C OLBCFRS1.8 C Meteorological Office OLBCFRS1.9 C London Road OLBCFRS1.10 C BRACKNELL OLBCFRS1.11 C Berkshire UK OLBCFRS1.12 C RG12 2SZ OLBCFRS1.13 C OLBCFRS1.14 C If no contract has been raised with this copy of the code, the use, OLBCFRS1.15 C duplication or disclosure of it is strictly prohibited. Permission OLBCFRS1.16 C to do so must first be obtained in writing from the Head of Numerical OLBCFRS1.17 C Modelling at the above address. OLBCFRS1.18 C ******************************COPYRIGHT****************************** OLBCFRS1.19 !+ Set open boundaries using flow relaxation scheme OLBCFRS1.20 ! OLBCFRS1.21 ! Subroutine Interface OLBCFRS1.22subroutine o_lbc_frs(ncols,nrows,n_cols_bdy,n_rows_bdy, 1OLBCFRS1.23 & levn, d1_field, f_type, OLBCFRS1.24 & levels_dataset,rimwidth,rimweights, OLBCFRS1.25 & l_obdy_north,l_obdy_east,l_obdy_south,l_obdy_west, OLBCFRS1.26 & bdy_n, bdy_e, bdy_s, bdy_w, OLBCFRS1.27 & l_apply_lsm, land_val, icode, cmessage) OLBCFRS1.28 OLBCFRS1.29 implicit none OLBCFRS1.30 !--------------------------------------------------------------------- OLBCFRS1.31 ! Program: o_lbc_frs OLBCFRS1.32 ! OLBCFRS1.33 ! Purpose: This routine creates open north/east/south/west OLBCFRS1.34 ! boundaries using the Flow Relaxation Scheme (FRS). OLBCFRS1.35 ! This is the scheme which is presently used in the OLBCFRS1.36 ! atmosphere LAM's and is based on the subroutine OLBCFRS1.37 ! mergefld called from boundval. OLBCFRS1.38 ! OLBCFRS1.39 ! Author: Mike Bell OLBCFRS1.40 ! OLBCFRS1.41 ! History OLBCFRS1.42 ! Model Date Modification history from model version 4.5 OLBCFRS1.43 ! version OLBCFRS1.44 ! 4.5 07/07/98 New subroutine/deck. M.Bell,S.Ineson OLBCFRS1.45 ! OLBCFRS1.46 !-------------------------------------------------------------------- OLBCFRS1.47 ! Subroutine Arguments: OLBCFRS1.48 OLBCFRS1.49 integer ncols ! IN number of columns (on tracer grid) OLBCFRS1.50 integer nrows ! IN number of rows OLBCFRS1.51 integer n_cols_bdy ! IN number of cols in boundary data OLBCFRS1.52 integer n_rows_bdy ! IN number of rows in boundary data OLBCFRS1.53 integer levn ! IN present level number OLBCFRS1.54 OLBCFRS1.55 real d1_field(ncols*nrows) ! IN/OUT section of the D1 array to OLBCFRS1.56 ! be updated OLBCFRS1.57 OLBCFRS1.58 integer f_type ! IN: field type indicator OLBCFRS1.59 real levels_dataset(ncols,nrows) ! IN levels dataset for this OLBCFRS1.60 ! field type OLBCFRS1.61 OLBCFRS1.62 integer rimwidth ! IN width of rim to update(max 4) OLBCFRS1.63 real rimweights(rimwidth) ! IN rim weights for each row OLBCFRS1.64 OLBCFRS1.65 logical l_obdy_north ! IN T=> update north lateral bdy OLBCFRS1.66 logical l_obdy_east ! IN T=> update east lateral bdy OLBCFRS1.67 logical l_obdy_south ! IN T=> update south lateral bdy OLBCFRS1.68 logical l_obdy_west ! IN T=> update west lateral bdy OLBCFRS1.69 OLBCFRS1.70 real bdy_n(n_cols_bdy*rimwidth) ! IN north part of boundary data OLBCFRS1.71 real bdy_e(n_rows_bdy*rimwidth) ! IN east part of boundary data OLBCFRS1.72 real bdy_s(n_cols_bdy*rimwidth) ! IN south part of boundary data OLBCFRS1.73 real bdy_w(n_rows_bdy*rimwidth) ! IN west part of boundary data OLBCFRS1.74 OLBCFRS1.75 logical l_apply_lsm ! IN: T => apply lsm at boundaries OLBCFRS1.76 real land_val ! IN value to use for fields at land points OLBCFRS1.77 OLBCFRS1.78 integer icode ! OUT Return code OLBCFRS1.79 character*(80) cmessage ! OUT Error message OLBCFRS1.80 CL-------------------------------------------------------------------- OLBCFRS1.81 OLBCFRS1.82 CL Global variables OLBCFRS1.83 *CALL PARVARS
OLBCFRS1.84 *IF -DEF,MPP OLBCFRS1.85 OLBCFRS1.86 INTEGER OLBCFRS1.87 & fld_type_p ! indicates a grid on P points OLBCFRS1.88 &, fld_type_u ! indicates a grid on U points OLBCFRS1.89 &, fld_type_unknown ! indicates a non-standard grid. OLBCFRS1.90 PARAMETER ( OLBCFRS1.91 & fld_type_p=1 OLBCFRS1.92 &, fld_type_u=2 OLBCFRS1.93 &, fld_type_unknown=-1) OLBCFRS1.94 OLBCFRS1.95 integer Offx, Offy OLBCFRS1.96 logical atright, atleft, atbase, attop OLBCFRS1.97 *ENDIF OLBCFRS1.98 OLBCFRS1.99 C Local scalars OLBCFRS1.100 OLBCFRS1.101 integer i ! loop over columns OLBCFRS1.102 integer j ! loop over rows OLBCFRS1.103 integer irim ! pointer to position in bdy data arrays OLBCFRS1.104 integer ifld ! pointer to position in field to update OLBCFRS1.105 real rwt ! rimweight for present boundary pt OLBCFRS1.106 OLBCFRS1.107 integer row_start ! start row (not counting offsets) for E & W OLBCFRS1.108 integer row_end ! end row (not counting offsets) for E & W bdys OLBCFRS1.109 integer irim_start ! initial value of irim for E and W bdys - OLBCFRS1.110 ! depends on value of l_obdy_south. OLBCFRS1.111 OLBCFRS1.112 C---------------------------------------------------------------------- OLBCFRS1.113 CL 0.0 Set grid off-sets and indicators showing if domain lies next to OLBCFRS1.114 CL each model boundary; non-mpp settings for offsets are zero and OLBCFRS1.115 CL for boundary indicators are true. This allows the same code OLBCFRS1.116 CL to be used for MPP and non-MPP cases. OLBCFRS1.117 CL OLBCFRS1.118 OLBCFRS1.119 *IF -DEF,MPP OLBCFRS1.120 Offx = 0 OLBCFRS1.121 Offy = 0 OLBCFRS1.122 atright = .true. OLBCFRS1.123 atleft = .true. OLBCFRS1.124 atbase = .true. OLBCFRS1.125 attop = .true. OLBCFRS1.126 *ENDIF OLBCFRS1.127 OLBCFRS1.128 CL 0.1 Set row_start and row_end and irim_start OLBCFRS1.129 OLBCFRS1.130 if ( atright .and. l_obdy_east .or. OLBCFRS1.131 # atleft .and. l_obdy_west) then OLBCFRS1.132 OLBCFRS1.133 row_start = 1 OLBCFRS1.134 irim_start=1 OLBCFRS1.135 if (attop .and. l_obdy_south) then OLBCFRS1.136 row_start = rimwidth + 1 OLBCFRS1.137 irim_start = rimwidth * rimwidth + 1 OLBCFRS1.138 endif OLBCFRS1.139 OLBCFRS1.140 row_end = n_rows_bdy ! first guess ! OLBCFRS1.141 if (atbase .and. l_obdy_north) then OLBCFRS1.142 row_end = n_rows_bdy - rimwidth OLBCFRS1.143 else if ( atbase .and. .not. l_obdy_north .and. OLBCFRS1.144 # f_type .eq. fld_type_u ) then OLBCFRS1.145 row_end = n_rows_bdy - 1 OLBCFRS1.146 end if OLBCFRS1.147 OLBCFRS1.148 end if ! if east or west boundaries to update OLBCFRS1.149 OLBCFRS1.150 OLBCFRS1.151 CL 1.1 Northern boundary: set all points including those in corners at OLBCFRS1.152 CL east or west boundaries OLBCFRS1.153 OLBCFRS1.154 if ( l_obdy_north .and. atbase ) then OLBCFRS1.155 OLBCFRS1.156 irim = 1 OLBCFRS1.157 OLBCFRS1.158 do j = n_rows_bdy-rimwidth+1,n_rows_bdy OLBCFRS1.159 do i = 1, n_cols_bdy OLBCFRS1.160 OLBCFRS1.161 ! note: ncols IS the number of columns of data stored for all cases OLBCFRS1.162 ifld = i + Offx + (j+Offy-1)*ncols OLBCFRS1.163 OLBCFRS1.164 rwt = rimweights(n_rows_bdy+1-j) ! first guess OLBCFRS1.165 OLBCFRS1.166 ! rim weights are reduced in the corners OLBCFRS1.167 if (atleft .and. i .lt. n_rows_bdy+1-j) then OLBCFRS1.168 rwt = rimweights(i) OLBCFRS1.169 else if ( atright .and. OLBCFRS1.170 # i .gt. n_cols_bdy - n_rows_bdy + j ) then OLBCFRS1.171 rwt = rimweights(n_cols_bdy + 1 - i) OLBCFRS1.172 end if OLBCFRS1.173 OLBCFRS1.174 d1_field(ifld) = bdy_n(irim)*rwt + OLBCFRS1.175 & d1_field(ifld)*(1.0-rwt) OLBCFRS1.176 OLBCFRS1.177 if (l_apply_lsm .and. levels_dataset(i,j) .lt. levn) then OLBCFRS1.178 d1_field(ifld) = land_val OLBCFRS1.179 endif OLBCFRS1.180 OLBCFRS1.181 irim=irim+1 OLBCFRS1.182 OLBCFRS1.183 enddo ! i OLBCFRS1.184 enddo ! j OLBCFRS1.185 OLBCFRS1.186 endif ! northern boundary OLBCFRS1.187 OLBCFRS1.188 CL 1.2 Southern boundary: as for northern boundary OLBCFRS1.189 OLBCFRS1.190 OLBCFRS1.191 if (l_obdy_south .and. attop ) then OLBCFRS1.192 OLBCFRS1.193 irim=1 OLBCFRS1.194 OLBCFRS1.195 do j = 1,rimwidth OLBCFRS1.196 do i = 1, n_cols_bdy OLBCFRS1.197 OLBCFRS1.198 ifld = i + Offx + (j+Offy-1)*ncols OLBCFRS1.199 OLBCFRS1.200 rwt = rimweights(j) OLBCFRS1.201 OLBCFRS1.202 if (atleft .and. i .lt. j) then OLBCFRS1.203 rwt = rimweights(i) OLBCFRS1.204 else if (atright .and. OLBCFRS1.205 # i .gt. n_cols_bdy + 1 - j ) then OLBCFRS1.206 rwt = rimweights(n_cols_bdy + 1 - i) OLBCFRS1.207 endif OLBCFRS1.208 OLBCFRS1.209 d1_field(ifld) = bdy_s(irim)*rwt + OLBCFRS1.210 & d1_field(ifld)*(1.0-rwt) OLBCFRS1.211 OLBCFRS1.212 if (l_apply_lsm .and. levels_dataset(i,j) .lt. levn) then OLBCFRS1.213 d1_field(ifld) = land_val OLBCFRS1.214 endif OLBCFRS1.215 OLBCFRS1.216 irim=irim+1 OLBCFRS1.217 OLBCFRS1.218 enddo ! i OLBCFRS1.219 enddo ! j OLBCFRS1.220 endif ! southern boundary OLBCFRS1.221 OLBCFRS1.222 CL 1.3 Eastern boundary: does not calculate values for corner points OLBCFRS1.223 CL if they have already been set. OLBCFRS1.224 OLBCFRS1.225 if (atright .and. l_obdy_east) then OLBCFRS1.226 OLBCFRS1.227 irim = irim_start OLBCFRS1.228 OLBCFRS1.229 do j = row_start,row_end OLBCFRS1.230 OLBCFRS1.231 do i = n_cols_bdy - rimwidth + 1, n_cols_bdy OLBCFRS1.232 OLBCFRS1.233 ifld = i + Offx + (j+Offy-1)*ncols OLBCFRS1.234 rwt = rimweights(n_cols_bdy+1-i) OLBCFRS1.235 OLBCFRS1.236 d1_field(ifld) = bdy_e(irim)*rwt+ d1_field(ifld)*(1.0-rwt) OLBCFRS1.237 OLBCFRS1.238 if (l_apply_lsm .and. levels_dataset(i,j) .lt. levn) then OLBCFRS1.239 d1_field(ifld) = land_val OLBCFRS1.240 endif OLBCFRS1.241 OLBCFRS1.242 irim=irim+1 OLBCFRS1.243 OLBCFRS1.244 enddo OLBCFRS1.245 enddo OLBCFRS1.246 OLBCFRS1.247 endif OLBCFRS1.248 OLBCFRS1.249 C 1.4 Western boundary: same as for eastern boundary OLBCFRS1.250 OLBCFRS1.251 if (atleft .and.l_obdy_west) then OLBCFRS1.252 OLBCFRS1.253 irim = irim_start OLBCFRS1.254 OLBCFRS1.255 do j = row_start,row_end OLBCFRS1.256 OLBCFRS1.257 do i = 1,rimwidth OLBCFRS1.258 OLBCFRS1.259 ifld = i + Offx + (j+Offy-1)*ncols OLBCFRS1.260 rwt = rimweights(i) OLBCFRS1.261 OLBCFRS1.262 d1_field(ifld) = bdy_w(irim)*rwt+ d1_field(ifld)*(1.0-rwt) OLBCFRS1.263 OLBCFRS1.264 if (l_apply_lsm .and. levels_dataset(i,j) .lt. levn) then OLBCFRS1.265 d1_field(i+((j-1)*ncols)) = land_val OLBCFRS1.266 endif OLBCFRS1.267 OLBCFRS1.268 irim=irim+1 OLBCFRS1.269 OLBCFRS1.270 enddo ! i OLBCFRS1.271 enddo ! j OLBCFRS1.272 OLBCFRS1.273 endif ! western boundary OLBCFRS1.274 OLBCFRS1.275 return OLBCFRS1.276 OLBCFRS1.277 end OLBCFRS1.278 *ENDIF OLBCFRS1.279