19 #define _FLATTEN(A) reshape((A), (/size((A))/) )
27 MODULE cloud_interpolator_mod
32 public :: cld_ntrp_linear_cell_interp, cld_ntrp_locate_cell, cld_ntrp_get_cell_values
33 public :: cld_ntrp_expand_index, cld_ntrp_contract_indices
36 #include<file_version.h>
37 real,
parameter :: tol = 10.0*epsilon(1.)
46 pure subroutine cld_ntrp_expand_index(Ic, ie, ier)
47 integer,
intent(in) :: Ic
48 integer,
intent(out) :: ie(:)
49 integer,
intent(out) :: ier
63 ie(j) = mod(ic/2**(j-1), 2)
66 end subroutine cld_ntrp_expand_index
73 pure subroutine cld_ntrp_contract_indices(ie, Ic, ier)
74 integer,
intent(in) :: ie(:)
75 integer,
intent(out) :: Ic
76 integer,
intent(out) :: ier
89 if(ic >= 2**nd) ier = 1
91 end subroutine cld_ntrp_contract_indices
101 pure subroutine cld_ntrp_linear_cell_interp(fvals, ts, f, ier)
102 real,
intent(in) :: fvals(0:)
103 real,
intent(in) :: ts(:)
104 real,
intent(out):: f
105 integer,
intent(out) :: ier
107 integer j, nd, Ic, iflag
108 integer ie(size(fvals))
114 if(
size(fvals) /= 2**nd)
then
121 call cld_ntrp_expand_index(ic, ie, iflag)
123 basis = basis * ( (1.0-real(ie(j)))*(1.0-ts(j)) + real(ie(j))*ts(j) )
125 f = f + fvals(ic)*basis
128 end subroutine cld_ntrp_linear_cell_interp
132 pure subroutine cld_ntrp_locate_cell(axis, x, index, ier)
133 real,
intent(in) :: axis(:)
134 real,
intent(in) :: x
135 integer,
intent(out) :: index
136 integer,
intent(out) :: ier
139 integer n, index1, is
140 real axis_1, axis_n, axis_min, axis_max
153 if(axis_1 > axis_n)
then
159 if(x < axis_min-tol)
then
163 if(x > axis_max+tol)
then
168 index = floor(real(n-1)*(x - axis_1)/(axis_n-axis_1)) + 1
169 index = min(n-1, index)
173 if(axis(index) <= x+tol)
then
174 if(x <= axis(index1)+tol)
then
182 if(axis(index1) >= x-tol)
return
189 if(axis(index) <= x+tol)
return
194 if(axis(index) >= x-tol)
then
195 if(x >= axis(index1)-tol)
then
203 if(axis(index1) <= x+tol)
return
210 if(axis(index) >= x-tol)
return
215 end subroutine cld_ntrp_locate_cell
219 pure subroutine cld_ntrp_get_flat_index(nsizes, indices, flat_index, ier)
220 integer,
intent(in) :: nsizes(:)
221 integer,
intent(in) :: indices(:)
222 integer,
intent(out) :: flat_index
223 integer,
intent(out) :: ier
230 if(nd /=
size(indices))
then
236 flat_index = indices(nd)-1
238 flat_index = flat_index*nsizes(id) + indices(id)-1
240 flat_index = flat_index + 1
242 end subroutine cld_ntrp_get_flat_index
246 pure subroutine cld_ntrp_get_cell_values(nsizes, fnodes, indices, fvals, ier)
247 integer,
intent(in) :: nsizes(:)
248 real,
intent(in) :: fnodes(:)
249 integer,
intent(in) :: indices(:)
250 real,
intent(out) :: fvals(0:)
251 integer,
intent(out) :: ier
253 integer id, nt, nd, flat_index, Ic, iflag
254 integer,
dimension(size(nsizes)) :: cell_indices, node_indices
259 if(nd /=
size(indices))
then
264 if(2**nd >
size(fvals))
then
273 if(nt /=
size(fnodes))
then
280 call cld_ntrp_expand_index(ic, cell_indices, iflag)
281 node_indices = indices + cell_indices
282 call cld_ntrp_get_flat_index(nsizes, node_indices, flat_index, iflag)
283 fvals(ic) = fnodes(flat_index)
286 end subroutine cld_ntrp_get_cell_values
289 end MODULE cloud_interpolator_mod