Changeset 2340 in lmdz_wrf for trunk/tools
- Timestamp:
- Feb 15, 2019, 5:50:02 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/module_generic.f90
r2331 r2340 3 3 4 4 !!!!!!! Subroutines/Functions 5 ! continguos_homogene_zones: Subroutine to look for contiguous zones by looking by continuous grid points 5 6 ! freeunit: provides the number of a free unit in which open a file 6 7 ! GetInNamelist: Subroutine to get a paramter from a namelistfile 8 ! get_xyconlimits: Subroutine for getting the limits of contiguous values from a given point in a 2D matrix 7 9 ! index_list_coordsI: Function to provide the index of a given coordinate within a list of integer coordinates 8 10 ! Index1DArrayI: Function to provide the first index of a given value inside a 1D integer array 9 11 ! Index1DArrayR: Function to provide the first index of a given value inside a 1D real array 10 12 ! Index1DArrayR_K: Function to provide the first index of a given value inside a 1D real(r_k) array 13 ! Index1DArrayL: Function to provide the first index of a given value inside a 1D boolean array 11 14 ! Index2DArrayR: Function to provide the first index of a given value inside a 2D real array 12 15 ! Index2DArrayR_K: Function to provide the first index of a given value inside a 2D real(r_k) array 13 16 ! Nvalues_2DArrayI: Number of different values of a 2D integer array 14 17 ! mat2DPosition: Function to provide the i, j indices of a given value inside a 2D matrix 18 ! multi_Index1DArrayL: Subroutine to provide the indices of a given value inside a 1D boolean array 15 19 ! numberTimes: Function to provide the number of times that a given set of characters happen within a string 16 20 ! RangeI: Function to provide a range of d1 values from 'iniv' to 'endv', of integer values in a vector … … 174 178 175 179 END FUNCTION Index1DArrayR_K 180 181 INTEGER FUNCTION Index1DArrayL(array1D, d1, val) 182 ! Function to provide the first index of a given value inside a 1D boolean array 183 184 IMPLICIT NONE 185 186 INTEGER, INTENT(in) :: d1 187 LOGICAL, INTENT(in) :: val 188 LOGICAL, DIMENSION(d1), INTENT(in) :: array1D 189 190 ! Local 191 INTEGER :: i 192 CHARACTER(LEN=50) :: fname 193 194 fname = 'Index1DArrayL' 195 196 Index1DArrayL = -1 197 198 DO i=1,d1 199 IF (array1d(i) .EQV. val) THEN 200 Index1DArrayL = i 201 EXIT 202 END IF 203 END DO 204 205 END FUNCTION Index1DArrayL 206 207 SUBROUTINE multi_Index1DArrayL(array1D, d1, val, Ntimes, pos) 208 ! Subroutine to provide the indices of a given value inside a 1D boolean array 209 210 IMPLICIT NONE 211 212 INTEGER, INTENT(in) :: d1 213 LOGICAL, INTENT(in) :: val 214 LOGICAL, DIMENSION(d1), INTENT(in) :: array1D 215 INTEGER, INTENT(out) :: Ntimes 216 INTEGER, DIMENSION(d1), INTENT(out) :: pos 217 218 ! Local 219 INTEGER :: i 220 CHARACTER(LEN=50) :: fname 221 222 !!!!!!! Variables 223 ! array1D: 1D Array of values 224 ! d1: length of array 225 ! val: Value to look for 226 ! Ntimes: Number of times val is found within array1D 227 ! pos: positions of the values of val 228 229 fname = 'multi_Index1DArrayL' 230 231 Ntimes = 0 232 pos = -1 233 234 DO i=1,d1 235 IF (array1d(i) .EQV. val) THEN 236 Ntimes = Ntimes + 1 237 pos(Ntimes) = i 238 END IF 239 END DO 240 241 END SUBROUTINE multi_Index1DArrayL 176 242 177 243 FUNCTION Index2DArrayR(array2D, d1, d2, val) … … 704 770 END FUNCTION vectorR_S 705 771 772 SUBROUTINE continguos_homogene_zones(dx, dy, matvals, Nzones, contzones) 773 ! Subroutine to look for contiguous zones by looking by continuous grid points 774 775 IMPLICIT NONE 776 777 INTEGER, INTENT(in) :: dx, dy 778 INTEGER, DIMENSION(dx,dy), INTENT(in) :: matvals 779 INTEGER, INTENT(out) :: Nzones 780 INTEGER, DIMENSION(dx,dy), INTENT(out) :: contzones 781 ! Local 782 INTEGER :: i,j, k 783 INTEGER :: ii, ei, ij, ej 784 INTEGER :: Ncont, Nassigned, Ncontmin 785 LOGICAL, DIMENSION(dx,dy) :: assigned, notdone 786 INTEGER, DIMENSION(:), ALLOCATABLE :: pzones, allzones 787 LOGICAL, DIMENSION(:), ALLOCATABLE :: passigns 788 789 !!!!!!! Variables 790 ! dx, dy: shape of the matrix 791 ! matvals: matrix with the values 792 ! contzones: homogeneous zones found 793 794 fname = 'continguos_homogene_zones' 795 796 ! Vector to keep track of all zone values 797 IF (ALLOCATED(allzones)) DEALLOCATE(allzones) 798 ALLOCATE(allzones(dx*dy/4)) 799 allzones = 0 800 801 assigned = .FALSE. 802 notdone = .TRUE. 803 contzones = -1 804 Nzones = 0 805 DO i=1, dx 806 DO j=1, dy 807 ! First 808 IF (matvals(i,j) /= 0 .AND. notdone(i,j)) THEN 809 CALL get_xyconlimits(dx, dy, matvals, 0, i, j, ii, ei, ij, ej) 810 811 ! Has any point of the rays already been assigned? 812 ! Along x 813 IF (ALLOCATED(pzones)) DEALLOCATE(pzones) 814 ALLOCATE(pzones(ei-ii+1)) 815 IF (ALLOCATED(passigns)) DEALLOCATE(passigns) 816 ALLOCATE(passigns(ei-ii+1)) 817 passigns = assigned(ii:ei,j) 818 CALL multi_Index1DArrayL(passigns, ei-ii+1, .TRUE., Nassigned, pzones) 819 IF (Nassigned /= 0) THEN 820 Ncontmin = 10000000 821 DO k=1, Nassigned 822 IF (contzones(ii+pzones(k)-1,j) < Ncontmin) Ncontmin = contzones(ii+pzones(k)-1,j) 823 END DO 824 ! If there is more than one assigned value change all values to the minimum one 825 DO k=1, Nassigned 826 IF (contzones(ii+pzones(k)-1,j) /= Ncontmin) THEN 827 WHERE (contzones == contzones(ii+pzones(k)-1,j) .AND. contzones /= Ncontmin) 828 contzones = Ncontmin 829 END WHERE 830 allzones(contzones(ii+pzones(k)-1,j)) = 0 831 END IF 832 END DO 833 Ncont = Ncontmin 834 END IF 835 ! Along y 836 IF (ALLOCATED(pzones)) DEALLOCATE(pzones) 837 ALLOCATE(pzones(ej-ij+1)) 838 IF (ALLOCATED(passigns)) DEALLOCATE(passigns) 839 ALLOCATE(passigns(ej-ij+1)) 840 passigns = assigned(i,ij:ej) 841 CALL multi_Index1DArrayL(passigns, ej-ij+1, .TRUE., Nassigned, pzones) 842 IF (Nassigned /= 0) THEN 843 Ncontmin = 10000000 844 DO k=1, Nassigned 845 IF (contzones(i,ij+pzones(k)-1) < Ncontmin) Ncontmin = contzones(i,ij+pzones(k)-1) 846 END DO 847 ! If there is more than one assigned value change all values to the minimum one 848 DO k=1, Nassigned 849 IF (contzones(i,ij+pzones(k)-1) /= Ncontmin) THEN 850 WHERE (contzones == contzones(i,ij+pzones(k)-1) .AND. contzones /= Ncontmin) 851 contzones = Ncontmin 852 END WHERE 853 allzones(contzones(i,ij+pzones(k)-1)) = 0 854 END IF 855 END DO 856 Ncont = Ncontmin 857 END IF 858 859 IF (.NOT.assigned(i,j)) THEN 860 Nzones = Nzones + 1 861 Ncont = Nzones 862 allzones(Nzones) = 1 863 ELSE 864 Ncont = contzones(i,j) 865 END IF 866 contzones(i,j) = Ncont 867 contzones(ii:ei,j) = Ncont 868 contzones(i,ij:ej) = Ncont 869 notdone(i,j) = .FALSE. 870 assigned(i,j) = .TRUE. 871 assigned(ii:ei,j) = .TRUE. 872 assigned(i,ij:ej) = .TRUE. 873 END IF 874 END DO 875 END DO 876 877 ! Using allzones to provide continuous assigned values 878 Nzones = 0 879 DO k=1, dx*dy/4 880 IF (allzones(k) /= 0) THEN 881 Nzones = Nzones + 1 882 IF (allzones(k) /= Nzones) THEN 883 WHERE(contzones == allzones(k)) 884 contzones = Nzones 885 END WHERE 886 END IF 887 END IF 888 END DO 889 890 RETURN 891 892 END SUBROUTINE continguos_homogene_zones 893 894 SUBROUTINE get_xyconlimits(d1, d2, matv, NOval, i, j, ix, ex, iy, ey) 895 ! Subroutine for getting the limits of contiguous values from a given point in a 2D matrix 896 897 IMPLICIT NONE 898 899 INTEGER, INTENT(in) :: d1, d2, i, j, NOval 900 INTEGER, DIMENSION(d1,d2), INTENT(in) :: matv 901 INTEGER, INTENT(out) :: ix, ex, iy, ey 902 903 ! Local 904 INTEGER :: i1, j1 905 LOGICAL :: found 906 907 !!!!!!! Variables 908 ! d1, d2: Shape of input 2D values 909 ! i, j: grid point from which get the contiguous values 910 ! NOval: value for grid points without data 911 ! matv: 2D matrx values 912 ! ix, ex, iy, ey: limits from a grid point 913 914 fname = 'get_xyconlimits' 915 916 ix = -1 917 ex = -1 918 iy = -1 919 ey = -1 920 921 ! Before i 922 IF (i > 1) THEN 923 ix = i 924 found = .FALSE. 925 DO i1=i-1,1,-1 926 IF (matv(i1,j) == NOval) THEN 927 ix = i1 + 1 928 found = .TRUE. 929 EXIT 930 END IF 931 END DO 932 IF (.NOT.found) ix=1 933 ELSE 934 ix = 1 935 END IF 936 ! After i 937 IF (i < d1) THEN 938 ex = i 939 found = .FALSE. 940 DO i1=i+1,d1 941 IF (matv(i1,j) == NOval) THEN 942 ex = i1 - 1 943 found = .TRUE. 944 EXIT 945 END IF 946 END DO 947 IF (.NOT.found) ex=d1 948 ELSE 949 ex = d1 950 END IF 951 952 ! Before j 953 IF (j > 1) THEN 954 iy = j 955 found = .FALSE. 956 DO j1=j-1,1,-1 957 IF (matv(i,j1) == NOval) THEN 958 iy = j1 + 1 959 found = .TRUE. 960 EXIT 961 END IF 962 END DO 963 IF (.NOT.found) iy=1 964 ELSE 965 iy = 1 966 END IF 967 ! After j 968 IF (j < d2) THEN 969 ey = j 970 found = .FALSE. 971 DO j1=j+1,d2 972 IF (matv(i,j1) == NOval) THEN 973 ey = j1 - 1 974 found = .TRUE. 975 EXIT 976 END IF 977 END DO 978 IF (.NOT.found) ey=d2 979 ELSE 980 ey = d2 981 END IF 982 983 RETURN 984 985 END SUBROUTINE get_xyconlimits 986 706 987 END MODULE module_generic
Note: See TracChangeset
for help on using the changeset viewer.