Changeset 779 for trunk/AGRIF/AGRIF_FILES/modinterpbasic.F
- Timestamp:
- 2007-12-22T18:04:17+01:00 (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/AGRIF/AGRIF_FILES/modinterpbasic.F
r662 r779 37 37 C 38 38 Real,Dimension(Agrif_MaxRaff) :: tabdiff2, tabdiff3 39 Real,Dimension(:),Allocatable::tabtest4 39 Real,Dimension(5,Agrif_MaxRaff,3) :: tabppm 40 Real,Dimension(:),Allocatable::tabtest4 41 Integer, Dimension(:,:), Allocatable :: indparent 42 Integer, Dimension(:,:), Allocatable :: 43 & indparentppm,indchildppm 44 Integer, Dimension(:), Allocatable :: 45 & indparentppm_1d,indchildppm_1d 46 Real, Dimension(:,:),Allocatable :: coeffparent 40 47 41 48 CONTAINS … … 140 147 C 141 148 End Subroutine Linear1d 149 150 Subroutine Linear1dprecompute2d(np2, np,nc, 151 & s_parent,s_child,ds_parent,ds_child,dir) 152 C 153 CCC Description: 154 CCC Subroutine to compute 2D coefficient and index for a linear 1D interpolation 155 CCC on a child grid (vector y) from its parent grid (vector x). 156 C 157 CC Method: 158 C 159 C Declarations: 160 C 161 162 C 163 C Arguments 164 INTEGER :: np,nc,np2,dir 165 REAL :: s_parent,s_child,ds_parent,ds_child 166 C 167 C Local scalars 168 INTEGER :: i,j,coeffraf,locind_parent_left,inc,inc1,inc2,toto 169 Integer, Dimension(:,:), Allocatable :: indparent_tmp 170 Real, Dimension(:,:), Allocatable :: coeffparent_tmp 171 REAL :: ypos,globind_parent_left,globind_parent_right 172 REAL :: invds, invds2 173 REAL :: ypos2,diff 174 C 175 C 176 177 coeffraf = nint(ds_parent/ds_child) 178 C 179 ypos = s_child 180 181 locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent) 182 183 globind_parent_left = s_parent 184 & + (locind_parent_left - 1)*ds_parent 185 186 globind_parent_right = globind_parent_left + ds_parent 187 188 C 189 invds = 1./ds_parent 190 invds2 = ds_child/ds_parent 191 192 ypos2 = ypos*invds 193 globind_parent_right=globind_parent_right*invds 194 195 if (.not.allocated(indparent)) then 196 allocate(indparent(nc*np2,3),coeffparent(nc*np2,3)) 197 else 198 if (size(indparent,1)<nc*np2) then 199 allocate(coeffparent_tmp(size(indparent,1),size(indparent,2))) 200 allocate(indparent_tmp(size(indparent,1),size(indparent,2))) 201 coeffparent_tmp=coeffparent 202 indparent_tmp=indparent 203 deallocate(indparent,coeffparent) 204 allocate(indparent(nc*np2,3),coeffparent(nc*np2,3)) 205 coeffparent(1:size(coeffparent_tmp,1),1:size(coeffparent_tmp,2)) 206 & = coeffparent_tmp 207 indparent(1:size(indparent_tmp,1),1:size(indparent_tmp,2)) 208 & = indparent_tmp 209 deallocate(indparent_tmp,coeffparent_tmp) 210 endif 211 endif 212 213 do i = 1,nc-1 214 C 215 if (ypos2 > globind_parent_right) then 216 locind_parent_left = locind_parent_left + 1 217 globind_parent_right = globind_parent_right + 1. 218 endif 219 220 diff=(globind_parent_right - ypos2) 221 indparent(i,dir) = locind_parent_left 222 coeffparent(i,dir) = diff 223 224 ypos2 = ypos2 + invds2 225 C 226 enddo 227 C 228 ypos = s_child + (nc-1)*ds_child 229 locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent) 230 231 if (locind_parent_left == np) then 232 indparent(nc,dir) = locind_parent_left-1 233 coeffparent(nc,dir) = 0. 234 else 235 C 236 globind_parent_left = s_parent 237 & + (locind_parent_left - 1)*ds_parent 238 C 239 indparent(nc,dir) = locind_parent_left 240 241 coeffparent(nc,dir) = (globind_parent_left + ds_parent - ypos) 242 & * invds 243 endif 244 245 do i=2, np2 246 inc = i*nc 247 inc1 = (i-1)*nc 248 inc2 = (i-2)*nc 249 !CDIR ALTCODE 250 indparent(1+inc1:inc,dir) = indparent(1+inc2:inc1,dir)+np 251 !CDIR ALTCODE 252 coeffparent(1+inc1:inc,dir) =coeffparent(1:nc,dir) 253 enddo 254 255 Return 256 C 257 C 258 End Subroutine Linear1dprecompute2d 259 260 261 262 Subroutine Linear1dprecompute(np,nc, 263 & s_parent,s_child,ds_parent,ds_child) 264 C 265 CCC Description: 266 CCC Subroutine to compute 1D coefficient and index for a linear 1D interpolation 267 CCC on a child grid (vector y) from its parent grid (vector x). 268 C 269 CC Method: 270 C 271 C Declarations: 272 C 273 274 C 275 C Arguments 276 INTEGER :: np,nc 277 REAL :: s_parent,s_child,ds_parent,ds_child 278 C 279 C Local scalars 280 INTEGER :: i,coeffraf,locind_parent_left 281 REAL :: ypos,globind_parent_left,globind_parent_right 282 REAL :: invds, invds2 283 REAL :: ypos2,diff 284 C 285 C 286 287 coeffraf = nint(ds_parent/ds_child) 288 C 289 if (coeffraf == 1) then 290 C 291 return 292 C 293 endif 294 C 295 ypos = s_child 296 297 locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent) 298 299 globind_parent_left = s_parent 300 & + (locind_parent_left - 1)*ds_parent 301 302 globind_parent_right = globind_parent_left + ds_parent 303 304 C 305 invds = 1./ds_parent 306 invds2 = ds_child/ds_parent 307 308 ypos2 = ypos*invds 309 globind_parent_right=globind_parent_right*invds 310 311 if (.not.allocated(indparent)) then 312 allocate(indparent(nc,1),coeffparent(nc,1)) 313 else 314 if (size(indparent)<nc) then 315 deallocate(indparent,coeffparent) 316 allocate(indparent(nc,1),coeffparent(nc,1)) 317 endif 318 endif 319 320 do i = 1,nc-1 321 C 322 if (ypos2 > globind_parent_right) then 323 locind_parent_left = locind_parent_left + 1 324 globind_parent_right = globind_parent_right + 1. 325 endif 326 327 diff=(globind_parent_right - ypos2) 328 indparent(i,1) = locind_parent_left 329 coeffparent(i,1) = diff 330 ypos2 = ypos2 + invds2 331 C 332 enddo 333 C 334 ypos = s_child + (nc-1)*ds_child 335 locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent) 336 337 if (locind_parent_left == np) then 338 indparent(nc,1) = locind_parent_left-1 339 coeffparent(nc,1) = 0. 340 else 341 C 342 globind_parent_left = s_parent 343 & + (locind_parent_left - 1)*ds_parent 344 C 345 indparent(nc,1) = locind_parent_left 346 347 coeffparent(nc,1) = (globind_parent_left + ds_parent - ypos) 348 & * invds 349 endif 350 C 351 Return 352 C 353 C 354 End Subroutine Linear1dprecompute 355 356 Subroutine Linear1daftercompute(x,y,np,nc, 357 & s_parent,s_child,ds_parent,ds_child,dir) 358 C 359 CCC Description: 360 CCC Subroutine to do a linear 1D interpolation on a child grid (vector y) from 361 CCC its parent grid (vector x) using precomputed coefficient and index. 362 C 363 CC Method: 364 C 365 C Declarations: 366 C 367 368 C 369 C Arguments 370 INTEGER :: np,nc,dir 371 REAL,INTENT(IN), DIMENSION(np) :: x 372 REAL,INTENT(OUT), DIMENSION(nc) :: y 373 REAL :: s_parent,s_child,ds_parent,ds_child 374 C 375 C Local scalars 376 INTEGER :: i,coeffraf,locind_parent_left 377 REAL :: ypos,globind_parent_left,globind_parent_right 378 REAL :: invds, invds2 379 REAL :: ypos2,diff 380 C 381 C 382 383 !CDIR ALTCODE 384 !CDIR NODEP 385 do i = 1,nc 386 C 387 y(i)=coeffparent(i,dir)*x(indparent(i,dir))+ 388 & (1.-coeffparent(i,dir))*x(indparent(i,dir)+1) 389 C 390 enddo 391 C 392 Return 393 C 394 C 395 End Subroutine Linear1daftercompute 142 396 143 397 C … … 569 823 If (coeffraf == 1) Then 570 824 locind_parent_left = 1 + nint((s_child - s_parent)/ds_parent) 825 !CDIR ALTCODE 826 !CDIR SHORTLOOP 571 827 y(1:nc) = x(locind_parent_left:locind_parent_left+nc-1) 572 828 return … … 582 838 Allocate(tabtest4(-2*coeffraf:nc+2*coeffraf)) 583 839 ENDIF 584 ENDIF 840 ENDIF 841 585 842 ypos = s_child 586 843 C … … 595 852 C 596 853 854 !CDIR NOVECTOR 597 855 Do i=1,coeffraf 598 856 tabdiff2(i)=(real(i)-0.5)*invcoeffraf … … 602 860 tabdiff3(1) = (1./3.)*a 603 861 a=2.*a 862 !CDIR NOVECTOR 604 863 Do i=2,coeffraf 605 864 tabdiff3(i) = tabdiff3(i-1)+(real(i)-1)*a … … 621 880 C 622 881 C 882 !CDIR ALTCODE 883 !CDIR SHORTLOOP 623 884 Do i = nmin,nmax 624 885 slope(i) = x(i) - x(i-1) 625 886 Enddo 626 887 888 !CDIR ALTCODE 889 !CDIR SHORTLOOP 627 890 Do i = nmin+1,nmax-1 628 891 xl(i)= 0.5*(x(i-1)+x(i)) … … 631 894 C 632 895 C apply parabolic monotonicity 896 !CDIR ALTCODE 897 !CDIR SHORTLOOP 633 898 Do i = locind_parent_left,locind_parent_last 634 899 delta(i) = xl(i+1) - xl(i) … … 644 909 Do iparent = locind_parent_left,locind_parent_last 645 910 pos=1 911 !CDIR ALTCODE 912 !CDIR SHORTLOOP 646 913 Do jj = ipos - coeffraf/2+diffmod,ipos + coeffraf/2 647 914 C … … 653 920 ipos = ipos + coeffraf 654 921 C 655 End do 656 C 657 C 922 End do 923 C 924 C 925 !CDIR ALTCODE 926 !CDIR SHORTLOOP 658 927 y(1:nc)=tabtest4(1:nc) 659 928 660 929 Return 661 930 End Subroutine ppm1d 931 932 933 Subroutine ppm1dprecompute2d(np2,np,nc, 934 & s_parent,s_child,ds_parent,ds_child,dir) 935 C 936 CCC Description: 937 CCC Subroutine to compute 2D coefficients and index for a 1D interpolation 938 CCC using piecewise parabolic method 939 CC Method: 940 C 941 C Declarations: 942 C 943 Implicit none 944 C 945 C Arguments 946 Integer :: np2,np,nc,dir 947 C Real, Dimension(:),Allocatable :: ytemp 948 Real :: s_parent,s_child,ds_parent,ds_child 949 C 950 C Local scalars 951 Integer, Dimension(:,:), Allocatable :: indparent_tmp 952 Integer, Dimension(:,:), Allocatable :: indchild_tmp 953 Integer :: i,coeffraf,locind_parent_left,locind_parent_last 954 Integer :: iparent,ipos,pos,nmin,nmax 955 Real :: ypos 956 integer :: i1,jj 957 Real :: xpmin,a 958 C 959 Real :: xrmin,xrmax,am3,s2,s1 960 Real, Dimension(np) :: xl,delta,a6,slope 961 INTEGER :: diffmod 962 REAL :: invcoeffraf 963 C 964 coeffraf = nint(ds_parent/ds_child) 965 C 966 invcoeffraf = ds_child/ds_parent 967 C 968 969 if (.not.allocated(indparentppm)) then 970 allocate( 971 & indparentppm(np2*nc,3), 972 & indchildppm(np2*nc,3) 973 & ) 974 else 975 if (size(indparentppm,1)<np2*nc) then 976 allocate( 977 & indparent_tmp(size(indparentppm,1),size(indparentppm,2)), 978 & indchild_tmp(size(indparentppm,1),size(indparentppm,2))) 979 indparent_tmp = indparentppm 980 indchild_tmp = indchildppm 981 deallocate(indparentppm,indchildppm) 982 allocate( 983 &indparentppm(np2*nc,3), 984 &indchildppm(np2*nc,3) 985 & ) 986 indparentppm(1:size(indparent_tmp,1),1:size(indparent_tmp,2)) 987 & = indparent_tmp 988 indchildppm(1:size(indparent_tmp,1),1:size(indparent_tmp,2)) 989 & = indchild_tmp 990 deallocate(indparent_tmp,indchild_tmp) 991 endif 992 endif 993 994 if (.not.allocated(indparentppm_1d)) then 995 allocate(indparentppm_1d(-2*coeffraf:nc+2*coeffraf), 996 & indchildppm_1d(-2*coeffraf:nc+2*coeffraf)) 997 else 998 if (size(indparentppm_1d)<nc+4*coeffraf+1) then 999 deallocate(indparentppm_1d,indchildppm_1d) 1000 allocate(indparentppm_1d(-2*coeffraf:nc+2*coeffraf), 1001 & indchildppm_1d(-2*coeffraf:nc+2*coeffraf)) 1002 endif 1003 endif 1004 1005 1006 ypos = s_child 1007 C 1008 locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent) 1009 locind_parent_last = 1 + 1010 & agrif_ceiling((ypos +(nc - 1) 1011 & *ds_child - s_parent)/ds_parent) 1012 C 1013 xpmin = s_parent + (locind_parent_left-1)*ds_parent 1014 i1 = 1+agrif_int((xpmin-s_child)/ds_child) 1015 C 1016 C 1017 1018 Do i=1,coeffraf 1019 tabdiff2(i)=(real(i)-0.5)*invcoeffraf 1020 EndDo 1021 1022 a = invcoeffraf**2 1023 tabdiff3(1) = (1./3.)*a 1024 a=2.*a 1025 !CDIR ALTCODE 1026 Do i=2,coeffraf 1027 tabdiff3(i) = tabdiff3(i-1)+(real(i)-1)*a 1028 EndDo 1029 1030 !CDIR ALTCODE 1031 Do i=1,coeffraf 1032 tabppm(1,i,dir) = 0.08333333333333* 1033 & (-1.+4*tabdiff2(i)-3*tabdiff3(i)) 1034 tabppm(2,i,dir) = 0.08333333333333* 1035 & (7.-26.*tabdiff2(i)+18.*tabdiff3(i)) 1036 tabppm(3,i,dir) = 0.08333333333333* 1037 & (7.+30*tabdiff2(i)-30*tabdiff3(i)) 1038 tabppm(4,i,dir) = 0.08333333333333* 1039 & (-1.-10.*tabdiff2(i)+18.*tabdiff3(i)) 1040 tabppm(5,i,dir) = 0.08333333333333* 1041 & (2*tabdiff2(i)-3*tabdiff3(i)) 1042 End Do 1043 C 1044 C 1045 diffmod = 0 1046 IF (mod(coeffraf,2) == 0) diffmod = 1 1047 C 1048 ipos = i1 1049 C 1050 Do iparent = locind_parent_left,locind_parent_last 1051 pos=1 1052 !CDIR ALTCODE 1053 Do jj = ipos - coeffraf/2+diffmod,ipos + coeffraf/2 1054 indparentppm_1d(jj) = iparent-2 1055 indchildppm_1d(jj) = pos 1056 pos = pos+1 1057 End do 1058 ipos = ipos + coeffraf 1059 C 1060 End do 1061 1062 Do i=1,np2 1063 1064 indparentppm(1+(i-1)*nc:i*nc,dir) = 1065 & indparentppm_1d(1:nc) + (i-1)*np 1066 indchildppm (1+(i-1)*nc:i*nc,dir) = 1067 & indchildppm_1d (1:nc) + (i-1)*np 1068 1069 End do 1070 1071 Return 1072 End Subroutine ppm1dprecompute2d 1073 1074 1075 Subroutine ppm1dprecompute(np,nc, 1076 & s_parent,s_child,ds_parent,ds_child) 1077 C 1078 CCC Description: 1079 CCC Subroutine to compute coefficient and index for a 1D interpolation 1080 CCC using piecewise parabolic method 1081 CC Method: 1082 C 1083 C Declarations: 1084 C 1085 Implicit none 1086 C 1087 C Arguments 1088 Integer :: np,nc 1089 C Real, Dimension(:),Allocatable :: ytemp 1090 Real :: s_parent,s_child,ds_parent,ds_child 1091 C 1092 C Local scalars 1093 Integer :: i,coeffraf,locind_parent_left,locind_parent_last 1094 Integer :: iparent,ipos,pos,nmin,nmax 1095 Real :: ypos 1096 integer :: i1,jj 1097 Real :: xpmin,a 1098 C 1099 Real :: xrmin,xrmax,am3,s2,s1 1100 Real, Dimension(np) :: xl,delta,a6,slope 1101 C Real, Dimension(:),Allocatable :: diff,diff2,diff3 1102 INTEGER :: diffmod 1103 REAL :: invcoeffraf 1104 C 1105 coeffraf = nint(ds_parent/ds_child) 1106 C 1107 If (coeffraf == 1) Then 1108 return 1109 End If 1110 invcoeffraf = ds_child/ds_parent 1111 C 1112 1113 if (.not.allocated(indparentppm)) then 1114 allocate(indparentppm(-2*coeffraf:nc+2*coeffraf,1), 1115 & indchildppm(-2*coeffraf:nc+2*coeffraf,1)) 1116 else 1117 if (size(indparentppm,1)<nc+4*coeffraf+1) then 1118 deallocate(indparentppm,indchildppm) 1119 allocate(indparentppm(-2*coeffraf:nc+2*coeffraf,1), 1120 & indchildppm(-2*coeffraf:nc+2*coeffraf,1)) 1121 endif 1122 endif 1123 1124 ypos = s_child 1125 C 1126 locind_parent_left = 1 + agrif_int((ypos - s_parent)/ds_parent) 1127 locind_parent_last = 1 + 1128 & agrif_ceiling((ypos +(nc - 1) 1129 & *ds_child - s_parent)/ds_parent) 1130 C 1131 xpmin = s_parent + (locind_parent_left-1)*ds_parent 1132 i1 = 1+agrif_int((xpmin-s_child)/ds_child) 1133 C 1134 C 1135 1136 Do i=1,coeffraf 1137 tabdiff2(i)=(real(i)-0.5)*invcoeffraf 1138 EndDo 1139 1140 a = invcoeffraf**2 1141 tabdiff3(1) = (1./3.)*a 1142 a=2.*a 1143 !CDIR ALTCODE 1144 !!!CDIR SHORTLOOP 1145 Do i=2,coeffraf 1146 tabdiff3(i) = tabdiff3(i-1)+(real(i)-1)*a 1147 EndDo 1148 1149 !CDIR ALTCODE 1150 !!!CDIR SHORTLOOP 1151 Do i=1,coeffraf 1152 tabppm(1,i,1) = 0.08333333333333*(-1.+4*tabdiff2(i)-3*tabdiff3(i)) 1153 tabppm(2,i,1) = 0.08333333333333* 1154 & (7.-26.*tabdiff2(i)+18.*tabdiff3(i)) 1155 tabppm(3,i,1) =0.08333333333333*(7.+30*tabdiff2(i)-30*tabdiff3(i)) 1156 tabppm(4,i,1) = 0.08333333333333* 1157 & (-1.-10.*tabdiff2(i)+18.*tabdiff3(i)) 1158 tabppm(5,i,1) = 0.08333333333333*(2*tabdiff2(i)-3*tabdiff3(i)) 1159 End Do 1160 C 1161 C 1162 diffmod = 0 1163 IF (mod(coeffraf,2) == 0) diffmod = 1 1164 C 1165 ipos = i1 1166 C 1167 Do iparent = locind_parent_left,locind_parent_last 1168 pos=1 1169 !CDIR ALTCODE 1170 !CDIR SHORTLOOP 1171 Do jj = ipos - coeffraf/2+diffmod,ipos + coeffraf/2 1172 indparentppm(jj,1) = iparent-2 1173 indchildppm(jj,1) = pos 1174 pos = pos+1 1175 End do 1176 ipos = ipos + coeffraf 1177 C 1178 End do 1179 1180 Return 1181 End Subroutine ppm1dprecompute 1182 1183 Subroutine ppm1daftercompute(x,y,np,nc, 1184 & s_parent,s_child,ds_parent,ds_child,dir) 1185 C 1186 CCC Description: 1187 CCC Subroutine to do a 1D interpolation and apply monotonicity constraints 1188 CCC using piecewise parabolic method 1189 CCC on a child grid (vector y) from its parent grid (vector x). 1190 CC Method: Use precomputed coefficient and index 1191 C 1192 C Declarations: 1193 C 1194 Implicit none 1195 C 1196 C Arguments 1197 Integer :: np,nc,dir 1198 Real, INTENT(IN),Dimension(np) :: x 1199 Real, INTENT(OUT),Dimension(nc) :: y 1200 C Real, Dimension(:),Allocatable :: ytemp 1201 Real :: s_parent,s_child,ds_parent,ds_child 1202 C 1203 C Local scalars 1204 Integer :: i,coeffraf,locind_parent_left,locind_parent_last 1205 Integer :: iparent,ipos,pos,nmin,nmax 1206 Real :: ypos 1207 integer :: i1,jj 1208 Real :: xpmin,a 1209 C 1210 Real :: xrmin,xrmax,am3,s2,s1 1211 Real, Dimension(np) :: xl,delta,a6,slope 1212 INTEGER :: diffmod 1213 C 1214 C 1215 do i=1,nc 1216 y(i)=tabppm(1,indchildppm(i,dir),dir)*x(indparentppm(i,dir))+ 1217 & tabppm(2,indchildppm(i,dir),dir)*x(indparentppm(i,dir)+1)+ 1218 & tabppm(3,indchildppm(i,dir),dir)*x(indparentppm(i,dir)+2)+ 1219 & tabppm(4,indchildppm(i,dir),dir)*x(indparentppm(i,dir)+3)+ 1220 & tabppm(5,indchildppm(i,dir),dir)*x(indparentppm(i,dir)+4) 1221 enddo 1222 1223 Return 1224 End Subroutine ppm1daftercompute 662 1225 663 1226 C **************************************************************************
Note: See TracChangeset
for help on using the changeset viewer.