18 #define _FLATTEN(A) reshape((A), (/size((A))/) )
26 MODULE cloud_interpolator_mod
31 public :: cld_ntrp_linear_cell_interp, cld_ntrp_locate_cell, cld_ntrp_get_cell_values
32 public :: cld_ntrp_expand_index, cld_ntrp_contract_indices
35 #include<file_version.h>
36 real,
parameter :: tol = 10.0*epsilon(1.)
45 pure subroutine cld_ntrp_expand_index(Ic, ie, ier)
46 integer,
intent(in) :: Ic
47 integer,
intent(out) :: ie(:)
48 integer,
intent(out) :: ier
62 ie(j) = mod(ic/2**(j-1), 2)
65 end subroutine cld_ntrp_expand_index
72 pure subroutine cld_ntrp_contract_indices(ie, Ic, ier)
73 integer,
intent(in) :: ie(:)
74 integer,
intent(out) :: Ic
75 integer,
intent(out) :: ier
88 if(ic >= 2**nd) ier = 1
90 end subroutine cld_ntrp_contract_indices
100 pure subroutine cld_ntrp_linear_cell_interp(fvals, ts, f, ier)
101 real,
intent(in) :: fvals(0:)
102 real,
intent(in) :: ts(:)
103 real,
intent(out):: f
104 integer,
intent(out) :: ier
106 integer j, nd, Ic, iflag
107 integer ie(size(fvals))
113 if(
size(fvals) /= 2**nd)
then
120 call cld_ntrp_expand_index(ic, ie, iflag)
122 basis = basis * ( (1.0-real(ie(j)))*(1.0-ts(j)) + real(ie(j))*ts(j) )
124 f = f + fvals(ic)*basis
127 end subroutine cld_ntrp_linear_cell_interp
131 pure subroutine cld_ntrp_locate_cell(axis, x, index, ier)
132 real,
intent(in) :: axis(:)
133 real,
intent(in) :: x
134 integer,
intent(out) :: index
135 integer,
intent(out) :: ier
138 integer n, index1, is
139 real axis_1, axis_n, axis_min, axis_max
152 if(axis_1 > axis_n)
then
158 if(x < axis_min-tol)
then
162 if(x > axis_max+tol)
then
167 index = floor(real(n-1)*(x - axis_1)/(axis_n-axis_1)) + 1
168 index = min(n-1, index)
172 if(axis(index) <= x+tol)
then
173 if(x <= axis(index1)+tol)
then
181 if(axis(index1) >= x-tol)
return
188 if(axis(index) <= x+tol)
return
193 if(axis(index) >= x-tol)
then
194 if(x >= axis(index1)-tol)
then
202 if(axis(index1) <= x+tol)
return
209 if(axis(index) >= x-tol)
return
214 end subroutine cld_ntrp_locate_cell
218 pure subroutine cld_ntrp_get_flat_index(nsizes, indices, flat_index, ier)
219 integer,
intent(in) :: nsizes(:)
220 integer,
intent(in) :: indices(:)
221 integer,
intent(out) :: flat_index
222 integer,
intent(out) :: ier
229 if(nd /=
size(indices))
then
235 flat_index = indices(nd)-1
237 flat_index = flat_index*nsizes(id) + indices(id)-1
239 flat_index = flat_index + 1
241 end subroutine cld_ntrp_get_flat_index
245 pure subroutine cld_ntrp_get_cell_values(nsizes, fnodes, indices, fvals, ier)
246 integer,
intent(in) :: nsizes(:)
247 real,
intent(in) :: fnodes(:)
248 integer,
intent(in) :: indices(:)
249 real,
intent(out) :: fvals(0:)
250 integer,
intent(out) :: ier
252 integer id, nt, nd, flat_index, Ic, iflag
253 integer,
dimension(size(nsizes)) :: cell_indices, node_indices
258 if(nd /=
size(indices))
then
263 if(2**nd >
size(fvals))
then
272 if(nt /=
size(fnodes))
then
279 call cld_ntrp_expand_index(ic, cell_indices, iflag)
280 node_indices = indices + cell_indices
281 call cld_ntrp_get_flat_index(nsizes, node_indices, flat_index, iflag)
282 fvals(ic) = fnodes(flat_index)
285 end subroutine cld_ntrp_get_cell_values
288 end MODULE cloud_interpolator_mod