afivo-streamer 1.1
1D/2D/3D streamer simulations with AMR
Loading...
Searching...
No Matches
m_lookup_table.f90
Go to the documentation of this file.
1!> A Fortran 90 module for creating lookup tables. These tables can be used to
2!> efficiently interpolate one or more values.
3!>
4!> Author: Jannis Teunissen
6 implicit none
7 private
8
9 ! The precision of the real numbers used in the tables
10 integer, parameter :: dp = kind(1.0d0)
11
12 ! Table spacing
13 integer, parameter, public :: lt_xspacing_linear = 1
14 integer, parameter, public :: lt_xspacing_quadratic = 2
15 integer, parameter, public :: lt_xspacing_cubic = 3
16
17 ! ** Routines for finding indices in sorted lists **
18 public :: find_index_linear
19 public :: find_index_bsearch
20 public :: find_index_adaptive
21
22 !> The lookup table type. There can be one or more columns, for which values
23 !> can be looked up for a given 'x-coordinate'.
24 type lt_t
25 integer :: n_points !< The number of points
26 integer :: n_cols !< The number of columns
27 integer :: xspacing !< Type of table spacing
28 real(dp) :: x_min !< The minimum lookup coordinate
29 real(dp) :: inv_fac !< The inverse x-spacing
30 logical :: extrapolate_above !< Linearly extrapolate above x_max
31
32 ! The table is stored in two ways, to speed up different types of lookups.
33 real(dp), allocatable :: x(:) !< The x values in the table
34 real(dp), allocatable :: cols_rows(:, :)
35 real(dp), allocatable :: rows_cols(:, :)
36 end type lt_t
37
38 !> The 2D lookup table type
39 type lt2_t
40 integer :: n_points(2) !< The size of the table
41 integer :: n_cols !< The number of columns/variables
42 integer :: xspacing(2) !< Type of table spacing
43 real(dp) :: x_min(2) !< The minimum lookup coordinate
44 real(dp) :: inv_fac(2) !< The inverse x-spacing
45 real(dp), allocatable :: x1(:) !< The x values in the table
46 real(dp), allocatable :: x2(:) !< The x values in the table
47 real(dp), allocatable :: rows_cols(:, :, :)
48 end type lt2_t
49
50 !> Type to indicate a location in the lookup table, which can be used to speed
51 !> up multiple lookups of different columns.
53 integer :: low_ix !< The x-value lies between low_ix and low_ix+1
54 real(dp) :: low_frac !< The distance from low_ix (up to low_ix+1), given
55 !< as a real number between 0 and 1.
56 end type lt_loc_t
57
58 !> Type to indicate a location in a 2D lookup table
60 !> The x-value lies between low_ix and low_ix+1
61 integer :: low_ix(2)
62 !> The distance from low_ix (up to low_ix+1), given as a real number
63 !> between 0 and 1.
64 real(dp) :: low_frac(2)
65 end type lt2_loc_t
66
67 ! Public types
68 public :: lt_t
69 public :: lt_loc_t
70 public :: lt2_t
71 public :: lt2_loc_t
72
73 ! Generic methods
74 public :: lt_get_spaced_data ! Convert values to regularly spaced
75 public :: lt_lin_interp_list ! Linearly interpolate a list
76
77 ! Public methods
78 public :: lt_create ! Create a new lookup table
79 public :: lt_set_col ! Set one table column
80 public :: lt_set_col_data ! Set one table column
81 public :: lt_add_col ! Add a column
82 public :: lt_get_loc ! Get the index (row) of a value
83 public :: lt_get_col ! Interpolate one column
84 public :: lt_get_mcol ! Interpolate multiple columns
85 public :: lt_get_col_at_loc ! Get one column at location
86 public :: lt_get_mcol_at_loc ! Get multiple columns at location
87 public :: lt_to_file ! Store lookup table in file
88 public :: lt_from_file ! Restore lookup table from file
89
90 ! Public methods for 2D tables
91 public :: lt2_create ! Create a new lookup table
92 public :: lt2_set_col ! Set one table column
93 public :: lt2_set_col_data ! Set one table column
94 public :: lt2_get_loc ! Get the index (row) of a value
95 public :: lt2_get_col ! Interpolate one column
96 public :: lt2_get_col_at_loc ! Get one column at location
97
98contains
99
100 ! ** Routines for finding indices **
101
102 !> Linear search of sorted list for the smallest ix such that list(ix) >= val.
103 !> On failure, returns size(list)+1
104 pure function find_index_linear(list, val) result(ix)
105 real(dp), intent(in) :: list(:) !< Sorted list
106 real(dp), intent(in) :: val !< Value to search for
107 integer :: ix
108
109 do ix = 1, size(list)
110 if (list(ix) >= val) exit
111 end do
112 end function find_index_linear
113
114 !> Binary search of sorted list for the smallest ix such that list(ix) >= val.
115 !> On failure, returns size(list)+1
116 pure function find_index_bsearch(list, val) result(ix)
117 real(dp), intent(in) :: list(:) !< Sorted list
118 real(dp), intent(in) :: val !< Value to search for
119 integer :: ix, i_min, i_max, i_middle
120
121 i_min = 1
122 i_max = size(list)
123
124 do while (i_min < i_max)
125 ! This safely performs: i_middle = (i_max + i_min) / 2
126 i_middle = i_min + ishft(i_max - i_min, -1)
127
128 if (list(i_middle) >= val) then
129 i_max = i_middle
130 else
131 i_min = i_middle + 1
132 end if
133 end do
134
135 ix = i_min
136 if (val > list(ix)) ix = size(list) + 1
137 end function find_index_bsearch
138
139 !> Adaptive search (combination of linear and binary search) of sorted list
140 !> for the smallest ix such that list(ix) >= val. On failure, returns
141 !> size(list)+1
142 pure function find_index_adaptive(list, val) result(ix)
143 real(dp), intent(in) :: list(:) !< Sorted list
144 real(dp), intent(in) :: val !< Value to search for
145 integer :: ix
146 integer, parameter :: binary_search_limit = 40
147
148 if (size(list) < binary_search_limit) then
149 ix = find_index_linear(list, val)
150 else
151 ix = find_index_bsearch(list, val)
152 end if
153 end function find_index_adaptive
154
155 !> Compute by use of linear interpolation the value in the middle
156 ! of a domain D = [x_list(1) , x_list(size(x_list))].
157 ! If x_value is left of domain D,
158 ! then the value becomes the value at the left side of D,
159 ! if x_value is right of domain D,
160 ! then the value becomes the value at the rigth side of D
161 pure subroutine lt_lin_interp_list(x_list, y_list, x_value, y_value)
162 real(dp), intent(in) :: x_list(:), y_list(:)
163 real(dp), intent(in) :: x_value
164 real(dp), intent(out) :: y_value
165
166 integer :: ix, imin, imax
167 real(dp) :: temp
168
169 imin = 1
170 imax = size(x_list)
171
172 if (x_value <= x_list(imin)) then
173 y_value = y_list(imin)
174 else if (x_value >= x_list(imax)) then
175 y_value = y_list(imax)
176 else
177 ix = find_index_adaptive(x_list, x_value)
178 temp = (x_value - x_list(ix-1)) / (x_list(ix) - x_list(ix-1))
179 y_value = (1 - temp) * y_list(ix-1) + temp * y_list(ix)
180 end if
181 end subroutine lt_lin_interp_list
182
183 ! ** 1D lookup table routines **
184
185 !> This function returns a new lookup table
186 function lt_create(x_min, x_max, n_points, n_cols, xspacing, &
187 extrapolate_above) result(my_lt)
188 real(dp), intent(in) :: x_min !< Minimum x-coordinate
189 real(dp), intent(in) :: x_max !< Maximum x-coordinate
190 integer, intent(in) :: n_points !< How many x-values to store
191 integer, intent(in) :: n_cols !< Number of variables that will be looked up
192 integer, intent(in), optional :: xspacing !< Spacing of data
193 !> Linearly extrapolate above x_max
194 logical, intent(in), optional :: extrapolate_above
195 type(lt_t) :: my_lt
196
197 if (x_max <= x_min) error stop "x_max should be > x_min"
198 if (n_points <= 1) error stop "n_points should be bigger than 1"
199
200 my_lt%n_points = n_points
201 my_lt%n_cols = n_cols
202 my_lt%x_min = x_min
203 my_lt%xspacing = lt_xspacing_linear
204 if (present(xspacing)) my_lt%xspacing = xspacing
205 my_lt%extrapolate_above = .false.
206 if (present(extrapolate_above)) my_lt%extrapolate_above = extrapolate_above
207
208 allocate(my_lt%x(n_points))
209 call table_set_x(n_points, my_lt%xspacing, x_min, x_max, &
210 my_lt%x, my_lt%inv_fac)
211
212 allocate(my_lt%cols_rows(n_cols, n_points))
213 allocate(my_lt%rows_cols(n_points, n_cols))
214 my_lt%cols_rows = 0
215 my_lt%rows_cols = 0
216 end function lt_create
217
218 subroutine table_set_x(n_points, xspacing, x_min, x_max, x, inv_fac)
219 integer, intent(in) :: n_points
220 integer, intent(in) :: xspacing
221 real(dp), intent(in) :: x_min, x_max
222 real(dp), intent(out) :: x(n_points)
223 real(dp), intent(out) :: inv_fac
224
225 select case (xspacing)
226 case (lt_xspacing_linear)
227 inv_fac = (n_points - 1)/(x_max - x_min)
229 inv_fac = (n_points - 1.0_dp)**2/(x_max - x_min)
230 case (lt_xspacing_cubic)
231 inv_fac = (n_points - 1.0_dp)**3/(x_max - x_min)
232 case default
233 error stop "Unknown spacing"
234 end select
235
236 x = get_x(x_min, x_max, n_points, xspacing)
237 end subroutine table_set_x
238
239 !> Linearly interpolate the (x, y) input data to the new_x coordinates
240 function lt_get_spaced_data(in_x, in_y, new_x) result(out_yy)
241 real(dp), intent(in) :: in_x(:), in_y(:), new_x(:)
242 real(dp) :: out_yy(size(new_x))
243 integer :: ix, n
244
245 n = size(in_x)
246 if (n < 2) error stop "size(in_x) < 2"
247 if (size(in_x) /= size(in_y)) error stop "in_x and in_y not of same size"
248 if (minval(in_x(2:) - in_x(1:n-1)) <= 0) &
249 error stop "in_x should strictly increase"
250
251 do ix = 1, size(new_x)
252 call lt_lin_interp_list(in_x, in_y, new_x(ix), out_yy(ix))
253 end do
254 end function lt_get_spaced_data
255
256 !> Fill the column with index col_ix after linearly interpolating
257 subroutine lt_set_col(my_lt, col_ix, x, y)
258 type(lt_t), intent(inout) :: my_lt
259 integer, intent(in) :: col_ix
260 real(dp), intent(in) :: x(:), y(:)
261
262 if (col_ix < 0 .or. col_ix > my_lt%n_cols) &
263 error stop "should have 1 <= col_ix <= n_cols"
264
265 my_lt%cols_rows(col_ix, :) = lt_get_spaced_data(x, y, my_lt%x)
266 my_lt%rows_cols(:, col_ix) = my_lt%cols_rows(col_ix, :)
267 end subroutine lt_set_col
268
269 !> Fill the column with index col_ix with y data
270 subroutine lt_set_col_data(my_lt, col_ix, y)
271 type(lt_t), intent(inout) :: my_lt
272 integer, intent(in) :: col_ix
273 real(dp), intent(in) :: y(:)
274
275 if (col_ix < 0 .or. col_ix > my_lt%n_cols) &
276 error stop "should have 1 <= col_ix <= n_cols"
277 if (size(y) /= my_lt%n_points) error stop "size(y) /= number of rows"
278
279 my_lt%cols_rows(col_ix, :) = y
280 my_lt%rows_cols(:, col_ix) = y
281 end subroutine lt_set_col_data
282
283 !> Add a new column by linearly interpolating the (x, y) data
284 subroutine lt_add_col(my_lt, x, y)
285 type(lt_t), intent(inout) :: my_lt
286 real(dp), intent(in) :: x(:), y(:)
287 type(lt_t) :: temp_lt
288
289 temp_lt = my_lt
290 deallocate(my_lt%cols_rows)
291 deallocate(my_lt%rows_cols)
292 allocate(my_lt%rows_cols(my_lt%n_points, my_lt%n_cols+1))
293 allocate(my_lt%cols_rows(my_lt%n_cols+1, my_lt%n_points))
294
295 my_lt%cols_rows(1:my_lt%n_cols, :) = temp_lt%cols_rows
296 my_lt%rows_cols(:, 1:my_lt%n_cols) = temp_lt%rows_cols
297 my_lt%n_cols = my_lt%n_cols + 1
298 my_lt%cols_rows(my_lt%n_cols, :) = lt_get_spaced_data(x, y, my_lt%x)
299 my_lt%rows_cols(:, my_lt%n_cols) = my_lt%cols_rows(my_lt%n_cols, :)
300 end subroutine lt_add_col
301
302 !> Returns the x-coordinates of the lookup table
303 pure function get_x(x_min, x_max, n_points, xspacing) result(x)
304 real(dp), intent(in) :: x_min, x_max
305 integer, intent(in) :: n_points, xspacing
306 real(dp) :: x(n_points), tmp
307 integer :: ix
308
309 tmp = 1.0_dp / (n_points-1)
310
311 select case (xspacing)
312 case (lt_xspacing_linear)
313 do ix = 1, n_points
314 x(ix) = (ix-1) * tmp
315 end do
317 do ix = 1, n_points
318 x(ix) = ((ix-1) * tmp)**2
319 end do
320 case (lt_xspacing_cubic)
321 do ix = 1, n_points
322 x(ix) = ((ix-1) * tmp)**3
323 end do
324 end select
325
326 x = x_min + x * (x_max - x_min)
327 end function get_x
328
329 !> Get a location in the lookup table
330 elemental function lt_get_loc(my_lt, x) result(my_loc)
331 type(lt_t), intent(in) :: my_lt
332 real(dp), intent(in) :: x
333 type(lt_loc_t) :: my_loc
334 real(dp) :: frac
335 real(dp), parameter :: one_third = 1/3.0_dp
336
337 frac = (x - my_lt%x_min) * my_lt%inv_fac
338
339 select case (my_lt%xspacing)
341 if (frac > 0) frac = sqrt(frac)
342 case (lt_xspacing_cubic)
343 if (frac > 0) frac = frac**one_third
344 end select
345
346 ! Check bounds
347 if (frac <= 0) then
348 my_loc%low_ix = 1
349 my_loc%low_frac = 1
350 else if (frac >= my_lt%n_points - 1) then
351 my_loc%low_ix = my_lt%n_points - 1
352 if (my_lt%extrapolate_above) then
353 my_loc%low_frac = my_loc%low_ix - frac
354 else
355 my_loc%low_frac = 0
356 end if
357 else
358 my_loc%low_ix = ceiling(frac)
359 my_loc%low_frac = my_loc%low_ix - frac
360 end if
361
362 end function lt_get_loc
363
364 !> Get the values of all columns at x
365 pure function lt_get_mcol(my_lt, x) result(col_values)
366 type(lt_t), intent(in) :: my_lt
367 real(dp), intent(in) :: x
368 real(dp) :: col_values(my_lt%n_cols)
369 type(lt_loc_t) :: loc
370
371 loc = lt_get_loc(my_lt, x)
372 col_values = lt_get_mcol_at_loc(my_lt, loc)
373 end function lt_get_mcol
374
375 !> Get the value of a single column at x
376 elemental function lt_get_col(my_lt, col_ix, x) result(col_value)
377 type(lt_t), intent(in) :: my_lt
378 integer, intent(in) :: col_ix
379 real(dp), intent(in) :: x
380 real(dp) :: col_value
381 type(lt_loc_t) :: loc
382
383 loc = lt_get_loc(my_lt, x)
384 col_value = lt_get_col_at_loc(my_lt, col_ix, loc)
385 end function lt_get_col
386
387 !> Get the values of all columns at a location
388 pure function lt_get_mcol_at_loc(my_lt, loc) result(col_values)
389 type(lt_t), intent(in) :: my_lt
390 type(lt_loc_t), intent(in) :: loc
391 real(dp) :: col_values(my_lt%n_cols)
392
393 col_values = loc%low_frac * my_lt%cols_rows(:, loc%low_ix) + &
394 (1-loc%low_frac) * my_lt%cols_rows(:, loc%low_ix+1)
395 end function lt_get_mcol_at_loc
396
397 !> Get the value of a single column at a location
398 elemental function lt_get_col_at_loc(my_lt, col_ix, loc) result(col_value)
399 type(lt_t), intent(in) :: my_lt
400 integer, intent(in) :: col_ix
401 type(lt_loc_t), intent(in) :: loc
402 real(dp) :: col_value
403
404 col_value = loc%low_frac * my_lt%rows_cols(loc%low_ix, col_ix) + &
405 (1-loc%low_frac) * my_lt%rows_cols(loc%low_ix+1, col_ix)
406 end function lt_get_col_at_loc
407
408 !> Write the lookup table to file (in binary, potentially unportable)
409 subroutine lt_to_file(my_lt, filename)
410 type(lt_t), intent(in) :: my_lt
411 character(len=*), intent(in) :: filename
412 integer :: my_unit
413
414 open(newunit=my_unit, file=trim(filename), form='UNFORMATTED', &
415 access='STREAM', status='REPLACE')
416 write(my_unit) my_lt%n_points, my_lt%n_cols
417 write(my_unit) my_lt%x_min, my_lt%inv_fac, my_lt%xspacing
418 write(my_unit) my_lt%x, my_lt%cols_rows
419 close(my_unit)
420 end subroutine lt_to_file
421
422 !> Read the lookup table from file (in binary, potentially unportable)
423 subroutine lt_from_file(my_lt, filename)
424 type(lt_t), intent(inout) :: my_lt
425 character(len=*), intent(in) :: filename
426 integer :: my_unit
427
428 open(newunit=my_unit, file=trim(filename), form='UNFORMATTED', &
429 access='STREAM', status='OLD')
430 read(my_unit) my_lt%n_points, my_lt%n_cols
431 read(my_unit) my_lt%x_min, my_lt%inv_fac, my_lt%xspacing
432
433 allocate(my_lt%x(my_lt%n_points))
434 allocate(my_lt%cols_rows(my_lt%n_cols, my_lt%n_points))
435 allocate(my_lt%rows_cols(my_lt%n_points, my_lt%n_cols))
436
437 read(my_unit) my_lt%x, my_lt%cols_rows
438 my_lt%rows_cols = transpose(my_lt%cols_rows)
439
440 close(my_unit)
441 end subroutine lt_from_file
442
443 ! ** 2D lookup table routines **
444
445 !> This function returns a new lookup table
446 function lt2_create(x_min, x_max, n_points, n_cols, xspacing) result(my_lt)
447 real(dp), intent(in) :: x_min(2) !< Minimum coordinate
448 real(dp), intent(in) :: x_max(2) !< Maximum coordinate
449 integer, intent(in) :: n_points(2) !< How many values to store
450 integer, intent(in) :: n_cols !< Number of variables that will be looked up
451 integer, intent(in), optional :: xspacing(2) !< Spacing of data
452 type(lt2_t) :: my_lt
453
454 if (any(x_max <= x_min)) stop "LT2_create error: x_max <= x_min"
455 if (any(n_points <= 1)) stop "LT2_create error: n_points <= 1"
456
457 my_lt%n_points = n_points
458 my_lt%n_cols = n_cols
459 my_lt%x_min = x_min
460 my_lt%xspacing = lt_xspacing_linear
461 if (present(xspacing)) my_lt%xspacing = xspacing
462
463 allocate(my_lt%x1(n_points(1)))
464 allocate(my_lt%x2(n_points(2)))
465
466 call table_set_x(n_points(1), my_lt%xspacing(1), x_min(1), x_max(1), &
467 my_lt%x1, my_lt%inv_fac(1))
468 call table_set_x(n_points(2), my_lt%xspacing(2), x_min(2), x_max(2), &
469 my_lt%x2, my_lt%inv_fac(2))
470
471 allocate(my_lt%rows_cols(n_points(1), n_points(2), n_cols))
472 my_lt%rows_cols = 0
473 end function lt2_create
474
475 !> Fill the column with index col_ix using linearly interpolated data
476 subroutine lt2_set_col(my_lt, col_ix, x1, x2, y)
477 type(lt2_t), intent(inout) :: my_lt
478 integer, intent(in) :: col_ix
479 real(dp), intent(in) :: x1(:), x2(:), y(:, :)
480 real(dp), allocatable :: tmp(:, :)
481 integer :: ix
482
483 allocate(tmp(my_lt%n_points(1), size(x2)))
484
485 ! Interpolate along first coordinate
486 do ix = 1, size(x2)
487 tmp(:, ix) = lt_get_spaced_data(x1, y(:, ix), my_lt%x1)
488 end do
489
490 ! Interpolate along second coordinate
491 do ix = 1, my_lt%n_points(1)
492 my_lt%rows_cols(ix, :, col_ix) = &
493 lt_get_spaced_data(x2, tmp(ix, :), my_lt%x2)
494 end do
495 end subroutine lt2_set_col
496
497 !> Fill the column with index col_ix with y data
498 subroutine lt2_set_col_data(my_lt, col_ix, y)
499 type(lt2_t), intent(inout) :: my_lt
500 integer, intent(in) :: col_ix
501 real(dp), intent(in) :: y(:, :)
502
503 if (col_ix < 0 .or. col_ix > my_lt%n_cols) &
504 error stop "should have 1 <= col_ix <= n_cols"
505 if (any(shape(y) /= my_lt%n_points)) error stop "shape(y) /= n_points"
506
507 my_lt%rows_cols(:, :, col_ix) = y
508 end subroutine lt2_set_col_data
509
510 !> Get a location in the lookup table
511 elemental function lt2_get_loc(my_lt, x1, x2) result(my_loc)
512 type(lt2_t), intent(in) :: my_lt
513 real(dp), intent(in) :: x1, x2
514 type(lt2_loc_t) :: my_loc
515 real(dp) :: frac(2)
516
517 frac = ([x1, x2] - my_lt%x_min) * my_lt%inv_fac
518 my_loc%low_ix = ceiling(frac)
519 my_loc%low_frac = my_loc%low_ix - frac
520
521 ! Check bounds
522 where (my_loc%low_ix < 1)
523 my_loc%low_ix = 1
524 my_loc%low_frac = 1
525 end where
526
527 where (my_loc%low_ix >= my_lt%n_points - 1)
528 my_loc%low_ix = my_lt%n_points - 1
529 my_loc%low_frac = 0
530 end where
531 end function lt2_get_loc
532
533 !> Get the value of a single column at x
534 pure function lt2_get_col(my_lt, col_ix, x1, x2) result(col_value)
535 type(lt2_t), intent(in) :: my_lt
536 integer, intent(in) :: col_ix
537 real(dp), intent(in) :: x1, x2
538 real(dp) :: col_value
539 type(lt2_loc_t) :: loc
540
541 loc = lt2_get_loc(my_lt, x1, x2)
542 col_value = lt2_get_col_at_loc(my_lt, col_ix, loc)
543 end function lt2_get_col
544
545 !> Get the value of a single column at a location
546 pure function lt2_get_col_at_loc(my_lt, col_ix, loc) result(col_value)
547 type(lt2_t), intent(in) :: my_lt
548 integer, intent(in) :: col_ix
549 type(lt2_loc_t), intent(in) :: loc
550 integer :: ix(2)
551 real(dp) :: w(2, 2)
552 real(dp) :: col_value
553
554 ! Bilinear interpolation
555 w(1, 1) = loc%low_frac(1) * loc%low_frac(2)
556 w(2, 1) = (1 - loc%low_frac(1)) * loc%low_frac(2)
557 w(1, 2) = loc%low_frac(1) * (1 - loc%low_frac(2))
558 w(2, 2) = (1 - loc%low_frac(1)) * (1 - loc%low_frac(2))
559 ix = loc%low_ix
560
561 col_value = sum(w * my_lt%rows_cols(ix(1):ix(1)+1, &
562 ix(2):ix(2)+1, col_ix))
563 end function lt2_get_col_at_loc
564
565end module m_lookup_table
A Fortran 90 module for creating lookup tables. These tables can be used to efficiently interpolate o...
subroutine, public lt_set_col(my_lt, col_ix, x, y)
Fill the column with index col_ix after linearly interpolating.
pure integer function, public find_index_bsearch(list, val)
Binary search of sorted list for the smallest ix such that list(ix) >= val. On failure,...
pure real(dp) function, public lt2_get_col(my_lt, col_ix, x1, x2)
Get the value of a single column at x.
subroutine, public lt2_set_col(my_lt, col_ix, x1, x2, y)
Fill the column with index col_ix using linearly interpolated data.
type(lt_t) function, public lt_create(x_min, x_max, n_points, n_cols, xspacing, extrapolate_above)
This function returns a new lookup table.
elemental real(dp) function, public lt_get_col_at_loc(my_lt, col_ix, loc)
Get the value of a single column at a location.
subroutine, public lt_from_file(my_lt, filename)
Read the lookup table from file (in binary, potentially unportable)
pure real(dp) function, public lt2_get_col_at_loc(my_lt, col_ix, loc)
Get the value of a single column at a location.
pure real(dp) function, dimension(my_lt%n_cols), public lt_get_mcol(my_lt, x)
Get the values of all columns at x.
pure real(dp) function, dimension(my_lt%n_cols), public lt_get_mcol_at_loc(my_lt, loc)
Get the values of all columns at a location.
subroutine, public lt_add_col(my_lt, x, y)
Add a new column by linearly interpolating the (x, y) data.
elemental type(lt2_loc_t) function, public lt2_get_loc(my_lt, x1, x2)
Get a location in the lookup table.
real(dp) function, dimension(size(new_x)), public lt_get_spaced_data(in_x, in_y, new_x)
Linearly interpolate the (x, y) input data to the new_x coordinates.
subroutine, public lt_set_col_data(my_lt, col_ix, y)
Fill the column with index col_ix with y data.
elemental real(dp) function, public lt_get_col(my_lt, col_ix, x)
Get the value of a single column at x.
subroutine, public lt2_set_col_data(my_lt, col_ix, y)
Fill the column with index col_ix with y data.
pure subroutine, public lt_lin_interp_list(x_list, y_list, x_value, y_value)
Compute by use of linear interpolation the value in the middle.
integer, parameter, public lt_xspacing_cubic
integer, parameter, public lt_xspacing_linear
pure integer function, public find_index_adaptive(list, val)
Adaptive search (combination of linear and binary search) of sorted list for the smallest ix such tha...
integer, parameter, public lt_xspacing_quadratic
subroutine, public lt_to_file(my_lt, filename)
Write the lookup table to file (in binary, potentially unportable)
type(lt2_t) function, public lt2_create(x_min, x_max, n_points, n_cols, xspacing)
This function returns a new lookup table.
elemental type(lt_loc_t) function, public lt_get_loc(my_lt, x)
Get a location in the lookup table.
pure integer function, public find_index_linear(list, val)
Linear search of sorted list for the smallest ix such that list(ix) >= val. On failure,...
Type to indicate a location in a 2D lookup table.
The 2D lookup table type.
Type to indicate a location in the lookup table, which can be used to speed up multiple lookups of di...
The lookup table type. There can be one or more columns, for which values can be looked up for a give...