771
772
777
778
779
780 integer, intent(in) :: ng, tile
781 integer, intent(in) :: LBi, UBi, LBj, UBj, LBij, UBij
782 integer, intent(in) :: IminS, ImaxS, JminS, JmaxS
783 integer, intent(in) :: Linp
784
785# ifdef ASSUMED_SHAPE
786# ifdef MASKING
787 real(r8), intent(in) :: umask(LBi:,LBj:)
788 real(r8), intent(in) :: vmask(LBi:,LBj:)
789# endif
790 real(r8), intent(in) :: Hz(LBi:,LBj:,:)
791 real(r8), intent(in) :: Hz_bry(LBij:,:,:)
792 real(r8), intent(inout) :: ad_Hz(LBi:,LBj:,:)
793 real(r8), intent(inout) :: ad_Hz_bry(LBij:,:,:)
794# else
795# ifdef MASKING
796 real(r8), intent(in) :: umask(LBi:UBi,LBj:UBj)
797 real(r8), intent(in) :: vmask(LBi:UBi,LBj:UBj)
798# endif
799 real(r8), intent(in) :: Hz(LBi:UBi,LBj:UBj,N(ng))
800 real(r8), intent(in) :: Hz_bry(LBij:UBij,N(ng),4)
801 real(r8), intent(inout) :: ad_Hz(LBi:UBi,LBj:UBj,N(ng))
802 real(r8), intent(inout) :: ad_Hz_bry(LBij:UBij,N(ng),4)
803# endif
804
805
806
807 integer :: i, ib, it1, it2, j, k
808 real(r8) :: adfac, fac, fac1, fac2
809 real(r8) :: cff1, ad_cff1, ad_cff2
810
811 real(r8), dimension(0:N(ng)) :: CF
812 real(r8), dimension(0:N(ng)) :: DC
813
814 real(r8), dimension(0:N(ng)) :: ad_CF
815 real(r8), dimension(0:N(ng)) :: ad_DC
816
817# include "set_bounds.h"
818
819
820
821
822
823
824
825 IF (
nbrec(ng).eq.1)
THEN
826 it1=1
827 it2=1
828 fac1=1.0_r8
829 fac2=0.0_r8
830 ELSE
831# ifdef GENERIC_DSTART
833# else
834 it1=max(0,(
iic(ng)-1)/
nobc(ng))+1
835# endif
836 it2=min(it1+1,
nbrec(ng))
839 fac=1.0_r8/(fac1+fac2)
840 fac1=fac*fac1
841 fac2=fac*fac2
842 END IF
843
844
845
846 ad_cff1=0.0_r8
847 ad_cff2=0.0_r8
848 ad_cf=0.0_r8
849 ad_dc=0.0_r8
850
851
852
853
856 &
domain(ng)%Western_Edge(tile))
THEN
858 DO j=jstr,jend
859 dc(0)=0.0_r8
860 cf(0)=0.0_r8
862 dc(k)=0.5_r8*(hz_bry(j,k,
iwest)+ &
863 & hz(i+1,j,k))
864 dc(0)=dc(0)+dc(k)
865 cf(0)=cf(0)+dc(k)*
boundary(ng)%u_west(j,k)
866 END DO
867 cff1=1.0_r8/dc(0)
868
869
870 ad_cff2=
boundary(ng)%ad_ubar_west(j)
872# ifdef MASKING
873
874
875 ad_cff2=ad_cff2*umask(i,j)
876# endif
877
878
879 ad_cff1=ad_cff1+cf(0)*ad_cff2
880 ad_cf(0)=ad_cf(0)+ad_cff2*cff1
881 ad_cff2=0.0_r8
882
883
884 ad_dc(0)=ad_dc(0)-cff1*cff1*ad_cff1
885 ad_cff1=0.0_r8
887
888
889
890
891 ad_dc(k)=ad_dc(k)+
boundary(ng)%u_west(j,k)*ad_cf(0)
893 & dc(k)*ad_cf(0)
894
895
896 ad_dc(k)=ad_dc(k)+ad_dc(0)
897
898
899
900 adfac=0.5_r8*ad_dc(k)
901 ad_hz(i+1,j,k)=ad_hz(i+1,j,k)+adfac
902 ad_hz_bry(j,k,
iwest)=ad_hz_bry(j,k,
iwest)+adfac
903 ad_dc(k)=0.0_r8
904 END DO
905
906
907 ad_dc(0)=0.0_r8
908
909
910 ad_cf(0)=0.0_r8
911 END DO
912 END IF
913
916 &
domain(ng)%Eastern_Edge(tile))
THEN
918 DO j=jstr,jend
919 dc(0)=0.0_r8
920 cf(0)=0.0_r8
922 dc(k)=0.5_r8*(hz(i-1,j,k)+ &
924 dc(0)=dc(0)+dc(k)
925 cf(0)=cf(0)+dc(k)*
boundary(ng)%u_east(j,k)
926 END DO
927 cff1=1.0_r8/dc(0)
928
929
930 ad_cff2=ad_cff2+
boundary(ng)%ad_ubar_east(j)
932# ifdef MASKING
933
934
935 ad_cff2=ad_cff2*umask(i,j)
936# endif
937
938
939 ad_cf(0)=ad_cf(0)+cff1*ad_cff2
940 ad_cff1=ad_cff1+cf(0)*ad_cff2
941 ad_cff2=0.0_r8
942
943
944 ad_dc(0)=ad_dc(0)-cff1*cff1*ad_cff1
945 ad_cff1=0.0_r8
947
948
949
950
951 ad_dc(k)=ad_dc(k)+
boundary(ng)%u_east(j,k)*ad_cf(0)
953 & dc(k)*ad_cf(0)
954
955
956 ad_dc(k)=ad_dc(k)+ad_dc(0)
957
958
959
960 adfac=0.5_r8*ad_dc(k)
961 ad_hz(i-1,j,k)=ad_hz(i-1,j,k)+adfac
962 ad_hz_bry(j,k,
ieast)=ad_hz_bry(j,k,
ieast)+adfac
963 ad_dc(k)=0.0_r8
964 END DO
965
966
967 ad_dc(0)=0.0_r8
968
969
970 ad_cf(0)=0.0_r8
971 END DO
972 END IF
973
976 &
domain(ng)%Southern_Edge(tile))
THEN
978 DO i=istr,iend
979 dc(0)=0.0_r8
980 cf(0)=0.0_r8
982 dc(k)=0.5_r8*(hz_bry(i-1,k,
isouth)+ &
984 dc(0)=dc(0)+dc(k)
985 cf(0)=cf(0)+dc(k)*
boundary(ng)%u_south(i,k)
986 END DO
987 cff1=1.0_r8/dc(0)
988
989
990 ad_cff2=ad_cff2+
boundary(ng)%ad_ubar_south(i)
991 boundary(ng)%ad_ubar_south(i)=0.0_r8
992# ifdef MASKING
993
994
995 ad_cff2=ad_cff2*umask(i,j)
996# endif
997
998
999 ad_cff1=ad_cff1+cf(0)*ad_cff2
1000 ad_cf(0)=ad_cf(0)+cff1*ad_cff2
1001 ad_cff2=0.0_r8
1002
1003
1004 ad_dc(0)=ad_dc(0)-cff1*cff1*ad_cff1
1005 ad_cff1=0.0_r8
1007
1008
1009
1010
1011 ad_dc(k)=ad_dc(k)+
boundary(ng)%u_south(i,k)*ad_cf(0)
1013 & dc(k)*ad_cf(0)
1014
1015
1016 ad_dc(k)=ad_dc(k)+ad_dc(0)
1017
1018
1019
1020 adfac=0.5_r8*ad_dc(k)
1023 ad_dc(k)=0.0_r8
1024 END DO
1025
1026
1027 ad_dc(0)=0.0_r8
1028
1029
1030 ad_cf(0)=0.0_r8
1031 END DO
1032 END IF
1033
1036 &
domain(ng)%Northern_Edge(tile))
THEN
1038 DO i=istr,iend
1039 dc(0)=0.0_r8
1040 cf(0)=0.0_r8
1042 dc(k)=0.5_r8*(hz_bry(i-1,k,
inorth)+ &
1044 dc(0)=dc(0)+dc(k)
1045 cf(0)=cf(0)+dc(k)*
boundary(ng)%u_north(i,k)
1046 END DO
1047 cff1=1.0_r8/dc(0)
1048
1049
1050 ad_cff2=ad_cff2+
boundary(ng)%ad_ubar_north(i)
1051 boundary(ng)%ad_ubar_north(i)=0.0_r8
1052# ifdef MASKING
1053
1054
1055 ad_cff2=ad_cff2*umask(i,j)
1056# endif
1057
1058
1059 ad_cf(0)=ad_cf(0)+cff1*ad_cff2
1060 ad_cff1=ad_cff1+cf(0)*ad_cff2
1061 ad_cff2=0.0_r8
1062
1063
1064 ad_dc(0)=ad_dc(0)-cff1*cff1*ad_cff1
1065 ad_cff1=0.0_r8
1067
1068
1069
1070
1071 ad_dc(k)=ad_dc(k)+
boundary(ng)%u_north(i,k)*ad_cf(0)
1073 & dc(k)*ad_cf(0)
1074 ad_cf(0)=0.0_r8
1075
1076
1077 ad_dc(k)=ad_dc(k)+ad_dc(0)
1078
1079
1080
1081 adfac=0.5_r8*ad_dc(k)
1084 ad_dc(k)=0.0_r8
1085 END DO
1086
1087
1088 ad_dc(0)=0.0_r8
1089
1090
1091 ad_cf(0)=0.0_r8
1092 END DO
1093 END IF
1094
1095
1096
1097
1100 &
domain(ng)%Western_Edge(tile))
THEN
1102 DO j=jstrv,jend
1103 dc(0)=0.0_r8
1104 cf(0)=0.0_r8
1106 dc(k)=0.5_r8*(hz_bry(j-1,k,
iwest)+ &
1107 & hz_bry(j ,k,
iwest))
1108 dc(0)=dc(0)+dc(k)
1109 cf(0)=cf(0)+dc(k)*
boundary(ng)%v_west(j,k)
1110 END DO
1111 cff1=1.0_r8/dc(0)
1112
1113
1114 ad_cff2=ad_cff2+
boundary(ng)%ad_vbar_west(j)
1115 boundary(ng)%ad_vbar_west(j)=0.0_r8
1116# ifdef MASKING
1117
1118
1119 ad_cff2=ad_cff2*vmask(i,j)
1120# endif
1121
1122
1123 ad_cf(0)=ad_cf(0)+cff1*ad_cff2
1124 ad_cff1=ad_cff1+cf(0)*ad_cff2
1125 ad_cff2=0.0_r8
1126
1127
1128 ad_dc(0)=ad_dc(0)-cff1*cff1*ad_cff1
1129 ad_cff1=0.0_r8
1131
1132
1133
1134
1136 & dc(k)*ad_cf(0)
1137 ad_dc(k)=ad_dc(k)+
boundary(ng)%v_west(j,k)*ad_cf(0)
1138
1139
1140 ad_dc(k)=ad_dc(k)+ad_dc(0)
1141
1142
1143
1144 adfac=0.5_r8*ad_dc(k)
1145 ad_hz_bry(j-1,k,
iwest)=ad_hz_bry(j-1,k,
iwest)+adfac
1146 ad_hz_bry(j ,k,
iwest)=ad_hz_bry(j ,k,
iwest)+adfac
1147 ad_dc(k)=0.0_r8
1148 END DO
1149
1150
1151 ad_cf(0)=0.0_r8
1152
1153
1154 ad_dc(0)=0.0_r8
1155 END DO
1156 END IF
1157
1160 &
domain(ng)%Eastern_Edge(tile))
THEN
1162 DO j=jstrv,jend
1163 dc(0)=0.0_r8
1164 cf(0)=0.0_r8
1166 dc(k)=0.5_r8*(hz_bry(j-1,k,
ieast)+ &
1167 & hz_bry(j ,k,
ieast))
1168 dc(0)=dc(0)+dc(k)
1169 cf(0)=cf(0)+dc(k)*
boundary(ng)%v_east(j,k)
1170 END DO
1171 cff1=1.0_r8/dc(0)
1172
1173
1174 ad_cff2=ad_cff2+
boundary(ng)%ad_vbar_east(j)
1175 boundary(ng)%ad_vbar_east(j)=0.0_r8
1176# ifdef MASKING
1177
1178
1179 ad_cff2=ad_cff2*vmask(i,j)
1180# endif
1181
1182
1183 ad_cf(0)=ad_cf(0)+cff1*ad_cff2
1184 ad_cff1=ad_cff1+cf(0)*ad_cff2
1185 ad_cff2=0.0_r8
1186
1187
1188 ad_dc(0)=ad_dc(0)-cff1*cff1*ad_cff1
1189 ad_cff1=0.0_r8
1191
1192
1193
1194
1196 & dc(k)*ad_cf(0)
1197 ad_dc(k)=ad_dc(k)+
boundary(ng)%v_east(j,k)*ad_cf(0)
1198
1199
1200 ad_dc(k)=ad_dc(k)+ad_dc(0)
1201 ad_dc(0)=0.0_r8
1202
1203
1204
1205 adfac=0.5_r8*ad_dc(k)
1206 ad_hz_bry(j-1,k,
ieast)=ad_hz_bry(j-1,k,
ieast)+adfac
1207 ad_hz_bry(j ,k,
ieast)=ad_hz_bry(j ,k,
ieast)+adfac
1208 ad_dc(k)=0.0_r8
1209 END DO
1210
1211
1212 ad_dc(0)=0.0_r8
1213
1214
1215 ad_cf(0)=0.0_r8
1216 END DO
1217 END IF
1218
1221 &
domain(ng)%Southern_Edge(tile))
THEN
1223 DO i=istr,iend
1224 dc(0)=0.0_r8
1225 cf(0)=0.0_r8
1227 dc(k)=0.5_r8*(hz_bry(i,k,
isouth)+ &
1228 & hz(i+1,j,k))
1229 dc(0)=dc(0)+dc(k)
1230 cf(0)=cf(0)+dc(k)*
boundary(ng)%v_south(i,k)
1231 END DO
1232 cff1=1.0_r8/dc(0)
1233
1234
1235 ad_cff2=ad_cff2+
boundary(ng)%ad_vbar_south(i)
1236 boundary(ng)%ad_vbar_south(i)=0.0_r8
1237# ifdef MASKING
1238
1239
1240 ad_cff2=ad_cff2*vmask(i,j)
1241# endif
1242
1243
1244 ad_cf(0)=ad_cf(0)+cff1*ad_cff2
1245 ad_cff1=ad_cff1+cf(0)*ad_cff2
1246 ad_cff2=0.0_r8
1247
1248
1249 ad_dc(0)=ad_dc(0)-cff1*cff1*ad_cff1
1250 ad_cff1=0.0_r8
1252
1253
1254
1255
1257 & dc(k)*ad_cf(0)
1258 ad_dc(k)=ad_dc(k)+
boundary(ng)%v_south(i,k)*ad_cf(0)
1259
1260
1261 ad_dc(k)=ad_dc(k)+ad_dc(0)
1262
1263
1264
1265 adfac=0.5_r8*ad_dc(k)
1267 ad_hz(i+1,j,k)=ad_hz(i+1,j,k)+adfac
1268 ad_dc(k)=0.0_r8
1269 END DO
1270
1271
1272 ad_dc(0)=0.0_r8
1273
1274
1275 ad_cf(0)=0.0_r8
1276 END DO
1277 END IF
1278
1281 &
domain(ng)%Northern_Edge(tile))
THEN
1283 DO i=istr,iend
1284 dc(0)=0.0_r8
1285 cf(0)=0.0_r8
1287 dc(k)=0.5_r8*(hz(i,j-1,k)+ &
1289 dc(0)=dc(0)+dc(k)
1290 cf(0)=cf(0)+dc(k)*
boundary(ng)%v_north(i,k)
1291 END DO
1292 cff1=1.0_r8/dc(0)
1293
1294
1295 ad_cff2=ad_cff2+
boundary(ng)%ad_vbar_north(i)
1296 boundary(ng)%ad_vbar_north(i)=0.0_r8
1297# ifdef MASKING
1298
1299
1300 ad_cff2=ad_cff2*vmask(i,j)
1301# endif
1302
1303
1304 ad_cf(0)=ad_cf(0)+cff1*ad_cff2
1305 ad_cff1=ad_cff1+cf(0)*ad_cff2
1306 ad_cff2=0.0_r8
1307
1308
1309 ad_dc(0)=ad_dc(0)-cff1*cff1*ad_cff1
1310 ad_cff1=0.0_r8
1312
1313
1314
1315
1317 & dc(k)*ad_cf(0)
1318 ad_dc(k)=ad_dc(k)+
boundary(ng)%v_north(i,k)*ad_cf(0)
1319
1320
1321 ad_dc(k)=ad_dc(k)+ad_dc(0)
1322
1323
1324
1325 adfac=0.5_r8*ad_dc(k)
1327 ad_hz(i,j-1,k)=ad_hz(i,j-1,k)+adfac
1328 ad_dc(k)=0.0_r8
1329 END DO
1330
1331
1332 ad_dc(0)=0.0_r8
1333
1334
1335 ad_cf(0)=0.0_r8
1336 END DO
1337 END IF
1338
1339 RETURN
type(t_boundary), dimension(:), allocatable boundary
type(t_lbc), dimension(:,:,:), allocatable ad_lbc
integer, dimension(:), allocatable n
type(t_bounds), dimension(:), allocatable bounds
type(t_domain), dimension(:), allocatable domain
integer, parameter r2dvar
integer, dimension(:), allocatable iic
real(dp), dimension(:), allocatable dt
integer, dimension(:), allocatable nobc
logical, dimension(:,:,:), allocatable lobc
real(dp), dimension(:,:), allocatable obc_time
integer, parameter isouth
real(dp), dimension(:), allocatable time
integer, dimension(:), allocatable ntstart
integer, parameter inorth
integer, dimension(:), allocatable nbrec