source: trunk/LMDZ.TITAN/libf/muphytitan/locators.f90 @ 3529

Last change on this file since 3529 was 1793, checked in by jvatant, 7 years ago

Making Titan's hazy again, part I
+ Added the source folder libf/muphytitan which contains

YAMMS ( Titan's microphysical model ) from J. Burgalat

+ Modif. compilation files linked to this change
JVO

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