source: trunk/LMDZ.PLUTO/libf/muphypluto/lint_locators.F90 @ 3590

Last change on this file since 3590 was 3560, checked in by debatzbr, 5 weeks ago

Addition of the microphysics model in moments.

File size: 6.4 KB
Line 
1! Copyright (c) Université de Reims Champagnne-Ardenne (2010-2015)
2! Contributor: Jérémie Burgalat (jeremie.burgalat@univ-reims.fr)
3!
4! This software is a computer program whose purpose is to compute multi-variate
5! linear interpolation.
6!
7! This software is governed by the CeCILL-B license under French law and
8! abiding by the rules of distribution of free software.  You can  use,
9! modify and/ or redistribute the software under the terms of the CeCILL-B
10! license as circulated by CEA, CNRS and INRIA at the following URL
11! "http://www.cecill.info".
12!
13! As a counterpart to the access to the source code and  rights to copy,
14! modify and redistribute granted by the license, users are provided only
15! with a limited warranty  and the software's author,  the holder of the
16! economic rights,  and the successive licensors  have only  limited
17! liability.
18!
19! In this respect, the user's attention is drawn to the risks associated
20! with loading,  using,  modifying and/or developing or reproducing the
21! software by the user in light of its specific status of free software,
22! that may mean  that it is complicated to manipulate,  and  that  also
23! therefore means  that it is reserved for developers  and  experienced
24! professionals having in-depth computer knowledge. Users are therefore
25! encouraged to load and test the software's suitability as regards their
26! requirements in conditions enabling the security of their systems and/or
27! data to be ensured and,  more generally, to use and operate it in the
28! same conditions as regards security.
29!
30! The fact that you are presently reading this means that you have had
31! knowledge of the CeCILL-B license and that you accept its terms.
32
33!! File:    lint_locators.F90
34!! Summary: Locator functions definition file
35!! Author:  J. Burgalat
36!! Date:    2010-2014
37
38MODULE LINT_LOCATORS
39    !! Locator functions definition module.
40    !!
41    !! This module defines some locator functions which search value in ordered vectors (with no
42    !! duplicates). Two algorithms are provided :
43    !!
44    !! - The binary search algorithm.
45    !! - A simple algorithm for direct access assuming searched vector is regularly
46    !!   spaced.
47    !!
48    !! All these functions satisfy the interface required for the __locator__ argument of linear
49    !! interpolation functions.
50    USE LINT_PREC
51    IMPLICIT NONE
52 
53    PRIVATE :: wp ! from LINT_PREC
54 
55    CONTAINS
56 
57    FUNCTION locate(value,vector) RESULT(res)
58      !! Basic binary search algorithm
59      REAL(kind=wp), INTENT(in)               :: value  !! Value to search
60      REAL(kind=wp), INTENT(in), DIMENSION(:) :: vector !! Input vector to search in
61      INTEGER :: res
62        !! Lowest subscript of the nearest value or __0__ if value is out of range.
63      REAL(kind=wp) :: l,u
64      INTEGER       :: jl,jm,ju, nv
65      res = 0 ; nv = SIZE(vector) ; l = vector(1) ; u = vector(nv)
66      ! Check for out of range value
67      IF ((value>l.AND.value>u).OR.(value<l.AND.value<u)) RETURN
68      ! Search in the array
69      jl=0 ; ju=nv+1
70      DO WHILE (ju-jl > 1)
71        res=(ju+jl)/2
72        IF (res == 0) RETURN   ! should never happen
73        IF((u>=l).EQV.(value >= vector(res))) THEN
74          jl=res
75        ELSE
76          ju=res
77        ENDIF
78      ENDDO
79      res = jl
80      RETURN
81    END FUNCTION locate
82 
83    FUNCTION locate_ext(value,vector) RESULT(res)
84      !! Basic binary search algorithm with extrapolation
85      !!
86      !! The function performs the same computation than [[locators(module):locate(function)]] except
87      !! that if __value__ is out of range, __1__ or __SIZE(vector)-1__ is returned with respect
88      !! to the nearest __vector__'s extremum.
89      REAL(kind=wp), INTENT(in)               :: value  !! Value to search
90      REAL(kind=wp), INTENT(in), DIMENSION(:) :: vector !! Input vector to search in
91      INTEGER :: res                                    !! Lowest subscript of the nearest value
92      REAL(kind=wp) :: l,u
93      INTEGER       :: jl,jm,ju, nv
94      nv = SIZE(vector) ; l = vector(1) ; u= vector(nv)
95      ! Check for out of range value
96      IF ((value>l.AND.value>u).OR.(value<l.AND.value<u)) THEN
97        res=1 ; IF (ABS(l-value) > ABS(u-value)) res=nv-1
98        RETURN
99      ENDIF
100      ! Search in the array
101      jl=0 ; ju=nv+1
102      DO WHILE (ju-jl > 1)
103        res=(ju+jl)/2
104        IF (res == 0) RETURN   ! should never happen
105        IF((u>=l).EQV.(value >= vector(res))) THEN
106          jl=res
107        ELSE
108          ju=res
109        ENDIF
110      ENDDO
111      res = jl
112      RETURN
113    END FUNCTION locate_ext
114 
115    FUNCTION locate_reg(value,vector) RESULT(res)
116      !! Direct subscript access locator method
117      !!
118      !! The function assumes __vector__ is regularly spaced and computes directly
119      !! the lowest subscript using __vector__ step increment.
120      REAL(kind=wp), INTENT(in)               :: value  !! Value to search
121      REAL(kind=wp), INTENT(in), DIMENSION(:) :: vector !! Input vector to search in
122      INTEGER :: res                                   
123        !! Lowest subscript of the nearest value or __0__ if value is out of range.
124      INTEGER       :: nv
125      REAL(kind=wp) :: step,l,u
126      res = 0
127      nv = SIZE(vector)
128      l = vector(1) ; u= vector(nv)
129      IF ((value>l.AND.value>u).OR.(value<l.AND.value<u)) RETURN
130      step = (vector(nv)-vector(1))/(nv-1.)
131      res = MIN(1+FLOOR((value-l)/step),nv-1)
132      RETURN
133    END FUNCTION locate_reg
134 
135    FUNCTION locate_reg_ext(value,vector) RESULT(res)
136      !! Direct subscript access locator method with extrapolation
137      !! 
138      !! The function performs the same computation than [[locators(module):locate_reg(function)]]
139      !! except that if __value__ is out of range, __1__ or __SIZE(vector)-1__ is returned
140      !! with respect to the nearest __vector__'s extremum.
141      REAL(kind=wp), INTENT(in)               :: value  !! Value to search
142      REAL(kind=wp), INTENT(in), DIMENSION(:) :: vector !! Input vector to search in
143      INTEGER :: res                                    !! Lowest subscript of the nearest value
144      INTEGER       :: nv
145      REAL(kind=wp) :: step,l,u
146      res = 0
147      nv = SIZE(vector)
148      l = vector(1) ; u= vector(nv)
149      IF ((value>l.AND.value>u).OR.(value<l.AND.value<u)) THEN
150        res=1 ; IF (ABS(l-value) > ABS(u-value)) res = nv -1
151        RETURN
152      ENDIF
153      step = (vector(nv)-vector(1))/(nv-1.)
154      res = MIN(1+FLOOR((value-l)/step),nv-1)
155      RETURN
156    END FUNCTION locate_reg_ext
157 
158  END MODULE LINT_LOCATORS 
Note: See TracBrowser for help on using the repository browser.