ITM AMNS: User Interface  \$Id: Doxyfile 502 2015-10-15 12:23:45Z dpc $
data_suport.F90
Go to the documentation of this file.
1 
11 
12  use f90_kind
13  use call_utils
14  use unit_h
15  use strings
16  use m_mrgrnk
17 
18  implicit none
19 
20  private
21 
22  !data types
23  !
24  !--- axes_t ----
25  type axes_t
26  real(rkind) , allocatable :: x(:)
27  integer(ikind) :: dim_x
28  integer(ikind) :: lbound
29  logical :: is_lin=.false.
30  logical :: is_log=.false.
31  logical :: is_equi=.false.
32  logical :: allocated
33  integer :: last_access
34  end type axes_t
35 
36  !
37  !--- grid_t ----
38  ! update this and all nesessary routines below for 5D
39  type grid_t
40  real(rkind) , allocatable :: f1d(:) ! Values 1D
41  real(rkind) , allocatable :: f2d(:,:) ! Values 2D
42  real(rkind) , allocatable :: f3d(:,:,:) ! Values 3D
43  real(rkind) , allocatable :: f4d(:,:,:,:) ! Values 4D
44  type (axes_t) , allocatable :: axe(:)
45  logical :: exist_f1d=.false.
46  logical :: exist_f2d=.false.
47  logical :: exist_f3d=.false.
48  logical :: exist_f4d=.false.
49  logical :: is_lin=.false.
50  logical :: is_log=.false.
51  logical :: with_warning=.false.
52  character(len=skind) :: name=""
53  integer :: interpol_function = 0
54  character(len=132) :: result_label=""
55  character(len=132) :: result_unit=""
56  character(len=132) :: state_label=""
57  integer :: ndim=0
58  end type grid_t
59 
60  !
61  !--- data_error ----
62  type data_error_t
63  integer(ikind) :: ierr
64  character (len=128) :: cerr
65  end type data_error_t
66 
67 
68  ! update this and all nesessary routines below for 5D
69 
70  !! \todo Update this interface for 5D and up
71  interface new_grid
72  module procedure new_grid_1d, &
73  new_grid_2d, &
74  new_grid_3d, &
75  new_grid_4d
76  end interface new_grid
77 
78  public :: grid_t, axes_t
79  public :: interpol, new_grid, delete
80  public :: set_option
81  public :: data_error_t
82 
83 contains
84 
85 
87  !-------------------------------------------
88  !------- new_grid_1 --------------------------
89  !-------------------------------------------
90 
91  subroutine new_grid_1d(grid,f,x)
92  implicit none
93  real(rkind), intent(in) :: f(:)
94  real(rkind), intent(in), optional :: x(:)
95  type(grid_t),intent(out):: grid
96  integer :: optargs
97 
98  ! error check
99  optargs=0
100  call assert(.not.grid%exist_f1d,"Error: grid%f1d is still allocated")
101  call assert(.not.grid%exist_f2d,"Error: grid%f2d is still allocated")
102  call assert(.not.grid%exist_f3d,"Error: grid%f3d is still allocated")
103  call assert(.not.grid%exist_f4d,"Error: grid%f4d is still allocated")
104  if(present(x)) optargs=optargs+1
105  if(optargs.eq.1) then
106  call assert(size(f)==size(x), "Error: size(f)" //size(f)// " /= =size(x) "//size(x))
107  call assert(sorted(x(:)),"not sorted x")
108  call assert(size(x(:))>=2,"not sorted x")
109  allocate(grid%axe(1))
110  allocate(grid%axe(1)%x(size(x)))
111  grid%axe(1)%x(:) = x(:)
112  grid%axe(1)%dim_x = size(x)
113  grid%axe(1)%allocated = .true.
114  endif
115  allocate(grid%f1d(size(f,1)))
116  grid%f1d(:)=f(:)
117  grid%exist_f1d=.true.
118  end subroutine new_grid_1d
119 
121  !-------------------------------------------
122  !------- new_grid_2d --------------------------
123  !-------------------------------------------
124 
125  subroutine new_grid_2d(grid,f,x,y)
126  implicit none
127  real(rkind), intent(in) :: f(:,:)
128  real(rkind), intent(in), optional :: x(:)
129  real(rkind), intent(in), optional :: y(:)
130  type(grid_t),intent(out):: grid
131  integer :: optargs
132 
133  ! error check
134  optargs=0
135  call assert(.not.grid%exist_f1d, "Error: grid%f1d is still allocated")
136  call assert(.not.grid%exist_f2d, "Error: grid%f2d is still allocated")
137  call assert(.not.grid%exist_f3d, "Error: grid%f3d is still allocated")
138  call assert(.not.grid%exist_f4d, "Error: grid%f4d is still allocated")
139  if(present(x)) optargs=optargs+1
140  if(present(y)) optargs=optargs+1
141  if(optargs.eq.2) then
142  call assert(size(f,1)==size(x), "Error: size(f,1)" //size(f,1)// ' /= =size(x) '//size(x))
143  call assert(size(f,2)==size(y), "Error: size(f,2)" //size(f,2)// ' /= =size(y) '//size(y))
144  call assert(sorted(x(:)),"not sorted x")
145  call assert(sorted(y(:)),"not sorted y")
146  call assert(size(x(:))>=2,"not sorted x")
147  call assert(size(y(:))>=2,"not sorted y")
148  allocate(grid%axe(2))
149  allocate(grid%axe(1)%x(size(x)))
150  allocate(grid%axe(2)%x(size(y)))
151  grid%axe(1)%x(:) = x(:)
152  grid%axe(2)%x(:) = y(:)
153  grid%axe(1)%dim_x = size(x)
154  grid%axe(2)%dim_x = size(y)
155  grid%axe(1)%allocated = .true.
156  grid%axe(2)%allocated = .true.
157  else
158  call assert(optargs==0, "Error: wrong number of optionl arguments for new_grid_2d")
159  endif
160  allocate(grid%f2d(size(f,1),size(f,2)))
161  grid%f2d(:,:)=f(:,:)
162  grid%exist_f2d=.true.
163  end subroutine new_grid_2d
164 
166  !-------------------------------------------
167  !------- new_grid_3d --------------------------
168  !-------------------------------------------
169 
170  subroutine new_grid_3d(grid,f,x,y,z)
171  implicit none
172  real(rkind), intent(in) :: f(:,:,:)
173  real(rkind), intent(in), optional :: x(:)
174  real(rkind), intent(in), optional :: y(:)
175  real(rkind), intent(in), optional :: z(:)
176  type(grid_t),intent(out):: grid
177  integer :: optargs
178 
179  ! error check
180  optargs=0
181  call assert(.not.grid%exist_f1d, "Error: grid%f1d is still allocated")
182  call assert(.not.grid%exist_f2d, "Error: grid%f2d is still allocated")
183  call assert(.not.grid%exist_f3d, "Error: grid%f3d is still allocated")
184  call assert(.not.grid%exist_f4d, "Error: grid%f4d is still allocated")
185  if(present(x)) optargs=optargs+1
186  if(present(y)) optargs=optargs+1
187  if(present(z)) optargs=optargs+1
188  if(optargs.eq.3) then
189  call assert(size(f,1)==size(x), "Error: size(fx,1)" //size(f,1)// ' /= =size(x) '//size(x))
190  call assert(size(f,2)==size(y), "Error: size(fx,2)" //size(f,2)// ' /= =size(y) '//size(y))
191  call assert(size(f,3)==size(z), "Error: size(fx,3)" //size(f,3)// ' /= =size(z) '//size(z))
192  call assert(sorted(x(:)),"not sorted x")
193  call assert(sorted(y(:)),"not sorted y")
194  call assert(sorted(y(:)),"not sorted z")
195  call assert(size(x(:))>=2,"not sorted x")
196  call assert(size(y(:))>=2,"not sorted y")
197  call assert(size(z(:))>=2,"not sorted z")
198  allocate(grid%axe(3))
199  allocate(grid%axe(1)%x(size(x)))
200  allocate(grid%axe(2)%x(size(y)))
201  allocate(grid%axe(3)%x(size(z)))
202  grid%axe(1)%x(:) = x(:)
203  grid%axe(2)%x(:) = y(:)
204  grid%axe(3)%x(:) = z(:)
205  grid%axe(1)%dim_x = size(x)
206  grid%axe(2)%dim_x = size(y)
207  grid%axe(3)%dim_x = size(z)
208  grid%axe(1)%allocated = .true.
209  grid%axe(2)%allocated = .true.
210  grid%axe(3)%allocated = .true.
211  else
212  call assert(optargs==0, "Error: wrong number of optionl arguments for new_grid_3d")
213  endif
214  allocate(grid%f3d(size(f,1),size(f,2),size(f,3)))
215  grid%f3d(:,:,:)=f(:,:,:)
216  grid%exist_f3d=.true.
217  end subroutine new_grid_3d
218 
220  !-------------------------------------------
221  !------- new_grid_4d --------------------------
222  !-------------------------------------------
223 
224  subroutine new_grid_4d(grid,f,w,x,y,z)
225  implicit none
226  real(rkind), intent(in) :: f(:,:,:,:)
227  real(rkind), intent(in), optional :: w(:)
228  real(rkind), intent(in), optional :: x(:)
229  real(rkind), intent(in), optional :: y(:)
230  real(rkind), intent(in), optional :: z(:)
231  type(grid_t),intent(out):: grid
232  integer :: optargs
233 
234  ! error check
235  optargs=0
236  call assert(.not.grid%exist_f1d, "Error: grid%f1d is still allocated")
237  call assert(.not.grid%exist_f2d, "Error: grid%f2d is still allocated")
238  call assert(.not.grid%exist_f3d, "Error: grid%f3d is still allocated")
239  call assert(.not.grid%exist_f4d, "Error: grid%f4d is still allocated")
240  if(present(w)) optargs=optargs+1
241  if(present(x)) optargs=optargs+1
242  if(present(y)) optargs=optargs+1
243  if(present(z)) optargs=optargs+1
244  if(optargs.eq.4) then
245  call assert(size(f,1)==size(w), "Error: size(fx,1)" //size(f,1)// ' /= =size(w) '//size(w))
246  call assert(size(f,2)==size(x), "Error: size(fx,2)" //size(f,2)// ' /= =size(x) '//size(x))
247  call assert(size(f,3)==size(y), "Error: size(fx,3)" //size(f,3)// ' /= =size(y) '//size(y))
248  call assert(size(f,4)==size(z), "Error: size(fx,4)" //size(f,4)// ' /= =size(z) '//size(z))
249  call assert(sorted(w(:)),"not sorted w")
250  call assert(sorted(x(:)),"not sorted x")
251  call assert(sorted(y(:)),"not sorted y")
252  call assert(sorted(z(:)),"not sorted z")
253  call assert(size(w(:))>=2,"not sorted w")
254  call assert(size(x(:))>=2,"not sorted x")
255  call assert(size(y(:))>=2,"not sorted y")
256  call assert(size(z(:))>=2,"not sorted z")
257  allocate(grid%axe(4))
258  allocate(grid%axe(1)%x(size(w)))
259  allocate(grid%axe(2)%x(size(x)))
260  allocate(grid%axe(3)%x(size(y)))
261  allocate(grid%axe(4)%x(size(z)))
262  grid%axe(1)%x(:) = w(:)
263  grid%axe(2)%x(:) = x(:)
264  grid%axe(3)%x(:) = y(:)
265  grid%axe(4)%x(:) = z(:)
266  grid%axe(1)%dim_x = size(w)
267  grid%axe(2)%dim_x = size(x)
268  grid%axe(3)%dim_x = size(y)
269  grid%axe(4)%dim_x = size(z)
270  grid%axe(1)%allocated = .true.
271  grid%axe(2)%allocated = .true.
272  grid%axe(3)%allocated = .true.
273  grid%axe(4)%allocated = .true.
274  else
275  call assert(optargs==0, "Error: wrong number of optionl arguments for new_grid_4d")
276  endif
277  allocate(grid%f4d(size(f,1),size(f,2),size(f,3),size(f,4)))
278  grid%f4d(:,:,:,:)=f(:,:,:,:)
279  grid%exist_f4d=.true.
280  end subroutine new_grid_4d
281 
282 
284  !-------------------------------------------
285  !------- delete ----------------------------
286  !-------------------------------------------
287  !this routine can also been used when the grid is not set.
288  subroutine delete(grid)
289  implicit none
290  type(grid_t),intent(inout):: grid
291 
292  if(allocated(grid%f1d))then
293  deallocate(grid%f1d)
294  grid%exist_f1d=.false.
295  endif
296  if(allocated(grid%f2d))then
297  deallocate(grid%f2d)
298  grid%exist_f2d=.false.
299  endif
300  if(allocated(grid%f3d))then
301  deallocate(grid%f3d)
302  grid%exist_f3d=.false.
303  endif
304  if(allocated(grid%f4d))then
305  deallocate(grid%f4d)
306  grid%exist_f4d=.false.
307  endif
308  if(allocated(grid%axe)) then
309  deallocate(grid%axe)
310  endif
311  end subroutine delete
312 
314  !---------------------------------
315  !----- set_option ----------------
316  !---------------------------------
317  subroutine set_option(grid,warning)
318  implicit none
319  type(grid_t) :: grid
320  logical,optional :: warning
321 
322  if(present(warning)) grid%with_warning =warning
323 
324  end subroutine set_option
325 
339 
340  subroutine interpol(w,x,y,z,fd1,fd2,fd3,fd4,grid,data_error)
342  implicit none
343  real (rkind), target ,intent(in) :: w(:)
344  real (rkind), target, optional ,intent(in) :: x(:)
345  real (rkind), target, optional ,intent(in) :: y(:)
346  real (rkind), target, optional ,intent(in) :: z(:)
347  real (rkind), optional ,intent(out):: fd1(:)
348  real (rkind), optional ,intent(out):: fd2(:,:)
349  real (rkind), optional ,intent(out):: fd3(:,:,:)
350  real (rkind), optional ,intent(out):: fd4(:,:,:,:)
351  type (grid_t) ,intent(inout):: grid
352  type (data_error_t), intent(out):: data_error
353 
354  ! interpolation index
355  !
356  real (rkind) :: dw(size(w))
357  integer :: iw(size(w))
358  integer :: iw_sort(size(w))
359  real (rkind), target :: w_s(size(w))
360  real (rkind), pointer :: w_p(:)
361 
362  real (rkind), allocatable :: dx(:) !size(x))
363  integer , allocatable :: ix(:) !size(x))
364  integer , allocatable :: ix_sort(:) !size(x))
365  real (rkind), allocatable, target :: x_s(:) !size(x))
366  real (rkind), pointer :: x_p(:)
367 
368  real (rkind), allocatable :: dy(:) !size(yvec))
369  integer , allocatable :: iy(:) !size(yvec))
370  integer, allocatable :: iy_sort(:) !size(yvec))
371  real (rkind), allocatable, target :: y_s(:) !size(yvec))
372  real (rkind), pointer :: y_p(:)
373 
374  real (rkind), allocatable :: dz(:) !size(zvec))
375  integer , allocatable :: iz(:) !size(zvec))
376  integer , allocatable :: iz_sort(:) !size(zvec))
377  real (rkind), allocatable, target :: z_s(:) !size(zvec))
378  real (rkind), pointer :: z_p(:)
379 
380  !local
381  logical :: with_x ! =present(x)
382  logical :: with_y ! =present(y)
383  logical :: with_z ! =present(z)
384  logical :: one_d ! =present(fd1)
385  logical :: two_d ! =present(fd2)
386  logical :: three_d ! =present(fd3)
387  logical :: four_d ! =present(fd4)
388  logical :: is_sorted_w = .false. ! =present(fgrid3)
389  logical :: is_sorted_x = .false. ! =present(fgrid3)
390  logical :: is_sorted_y = .false. ! =present(fgrid3)
391  logical :: is_sorted_z = .false. ! =present(fgrid3)
392 
393  ! help swap
394  integer :: iswap
395  !loop index
396  integer :: i, idpc
397 
398  type (fun_err_t) :: fun_err
399 
400  data_error%ierr = 0
401  data_error%cerr = ''
402  fun_err%ierr = 0
403  fun_err%cerr = ''
404 
405  with_x =present(x)
406  with_y =present(y)
407  with_z =present(z)
408  one_d =present(fd1)
409  two_d =present(fd2)
410  three_d =present(fd3)
411  four_d =present(fd4)
412 
413  !-irregular calls---
414  call assert(grid%exist_f1d .or. grid%exist_f2d .or.grid%exist_f3d.or.grid%exist_f4d, &
415  "Data not allocated for interpolation")
416 
417  if(one_d) then
418  call assert(one_d.and. .not.(two_d.or.three_d.or.four_d), &
419  "Type mismatch, only one f vector type possible!!")
420  if(with_x) call assert(size(x)==size(w), "Size w:"//size(w)// &
421  "/= Size x:"//size(x))
422  if(with_y) call assert(size(y)==size(w), "Size w:"//size(w)// &
423  "/= Size y:"//size(y))
424  if(with_z) call assert(size(z)==size(w), "Size w:"//size(x)// &
425  "/= Size z:"//size(z))
426  endif
427 
428  if(two_d)then
429  call assert(with_x.and..not.(with_y.or.with_z),"expect x present, y and z not present")
430  endif
431  if(three_d)then
432  call assert(with_y .and. .not. with_z,"expect x and y present and z not present")
433  endif
434  if(four_d)then
435  call assert(with_y .and. with_z,"expect x y and zvec present")
436  endif
437 
438  select case(grid%interpol_function)
439 
440  case (0)
442  if(with_x)then
443  allocate(dx(size(x)),ix(size(x)),ix_sort(size(x)),x_s(size(x)))
444  endif
445  if(with_y)then
446  allocate(dy(size(y)),iy(size(y)),iy_sort(size(y)),y_s(size(y)))
447  endif
448  if(with_z)then
449  allocate(dz(size(z)),iz(size(z)),iz_sort(size(z)),z_s(size(z)))
450  endif
451 
452  is_sorted_w=sorted(w(:))
453  if(with_x)is_sorted_x=sorted(x(:))
454  if(with_y)is_sorted_y=sorted(y(:))
455  if(with_z)is_sorted_z=sorted(z(:))
456 
457  ! if the vectors are not sorted, we create a sorted vector, and save index map
458  ! pointer x_p will show a sorted vector
459 
460  if(.not.is_sorted_w) then
461  iw_sort(:)= (/ (i,i=1,size(iw_sort(:)) ) /)
462  call mrgrnk(w(:),iw_sort(:))
463  w_s(:)=w(iw_sort(:))
464  w_p => w_s
465  if(grid%axe(1)%is_log) w_p = log10(w_p)
466  else
467  if(grid%axe(1)%is_log) then
468  w_s = log10(w)
469  w_p => w_s
470  else
471  w_p => w
472  endif
473  endif
474 
475  if(with_x) then
476  if(.not.is_sorted_x) then
477  ix_sort(:)= (/ (i,i=1,size(ix_sort(:)) ) /)
478  call mrgrnk(x(:),ix_sort(:))
479  x_s(:)=x(ix_sort(:))
480  x_p => x_s
481  if(grid%axe(2)%is_log) x_p = log10(x_p)
482  else
483  if(grid%axe(2)%is_log) then
484  x_s = log10(x)
485  x_p => x_s
486  else
487  x_p => x
488  endif
489  endif
490  endif
491 
492  if(with_y) then
493  if(.not.is_sorted_y)then
494  iy_sort(:)= (/ (i,i=1,size(iy_sort(:)) ) /)
495  call mrgrnk(y(:),iy_sort(:))
496  y_s(:)=y(iy_sort(:))
497  y_p => y_s
498  if(grid%axe(3)%is_log) y_p = log10(y_p)
499  else
500  if(grid%axe(3)%is_log) then
501  y_s = log10(y)
502  y_p => y_s
503  else
504  y_p => y
505  endif
506  endif
507  endif
508 
509  if(with_z) then
510  if(.not.is_sorted_z)then
511  iz_sort(:)= (/ (i,i=1,size(iz_sort(:)) ) /)
512  call mrgrnk(z(:),iz_sort(:))
513  z_s(:)=z(ix_sort(:))
514  z_p => z_s
515  if(grid%axe(4)%is_log) z_p = log10(z_p)
516  else
517  z_p => z
518  if(grid%axe(4)%is_log) then
519  z_s = log10(z)
520  z_p => z_s
521  else
522  z_p => z
523  endif
524  endif
525  endif
526 
527 
528  !---get index of w in the grid
529  call interpol_index(w_p(:),grid%axe(1)%x(:),iw(:),dw(:),grid)
530  ! reset ix to original xvec positions
531  ! next comand work, because internaly the f90 compiler works with copy comands
532 
533  if(.not. is_sorted_w)then
534  iw(iw_sort(:))=iw(:)
535  dw(iw_sort(:))=dw(:)
536  endif
537 
538 
539  if(with_x) then
540  idpc=size(x)/2
541  call interpol_index(x_p(:),grid%axe(2)%x(:),ix(:),dx(:),grid)
542  if(.not. is_sorted_x)then
543  ix(ix_sort(:))=ix(:)
544  dx(ix_sort(:))=dx(:)
545  endif
546  endif
547 
548  if(with_y) then
549  call interpol_index(y_p(:),grid%axe(3)%x(:),iy(:),dy(:),grid)
550  if(.not. is_sorted_y)then
551  iy(iy_sort(:))=iy(:)
552  dy(iy_sort(:))=dy(:)
553  endif
554  endif
555 
556  if(with_z) then
557  call interpol_index(z_p(:),grid%axe(4)%x(:),iz(:),dz(:),grid)
558  if(.not. is_sorted_z)then
559  iz(iz_sort(:))=iz(:)
560  dz(iz_sort(:))=dz(:)
561  endif
562  endif
563  !
564  !-- now interpolate
565 
566  if(with_z)then
567  if(one_d)then
568  call interpo_4_1(iw(:),ix(:),iy(:),iz(:),dw(:),dx(:),dy(:),dz(:),fd1(:),grid)
569  else
570  call interpo_4_4(iw(:),ix(:),iy(:),iz(:),dw(:),dx(:),dy(:),dz(:),fd4(:,:,:,:),grid)
571  endif
572  elseif(with_y)then
573  if(one_d)then
574  call interpo_3_1(iw(:),ix(:),iy(:),dw(:),dx(:),dy(:),fd1(:),grid)
575  else
576  call interpo_3_3(iw(:),ix(:),iy(:),dw(:),dx(:),dy(:),fd3(:,:,:),grid)
577  endif
578  elseif(with_x)then
579  if(one_d)then
580  call interpo_2_1(iw(:),ix(:),dw(:),dx(:),fd1(:),grid)
581  else
582  call interpo_2_2(iw(:),ix(:),dw(:),dx(:),fd2(:,:),grid)
583  endif
584  else
585  call interpo_1_1(iw(:),dw(:),fd1(:),grid)
586  endif
587 
588  if(with_x)then
589  deallocate(dx,ix,ix_sort,x_s)
590  endif
591  if(with_y)then
592  deallocate(dy,iy,iy_sort,y_s)
593  endif
594  if(with_z)then
595  deallocate(dz,iz,iz_sort,z_s)
596  endif
597 
598  if(grid%is_log) then
599  if(one_d) fd1 = 10.0_rkind ** fd1
600  if(two_d) fd2 = 10.0_rkind ** fd2
601  if(three_d) fd3 = 10.0_rkind ** fd3
602  if(four_d) fd4 = 10.0_rkind ** fd4
603  endif
604 
605  case (1001) ! grid%interpol_function
607  call assert(.not.(with_x.or.with_y.or.with_z), "nuclear data '1001' must be a function of 1 parameter")
608  call assert(grid%exist_f2d, "nuclear data '1001' requires 2d table of data")
609  call assert(one_d, "nuclear data '1001' expected to be passed an effective 1d array")
610  call nuclear_data_1001(grid%f2d, w, fd1, grid%with_warning, fun_err)
611 
612  case (1002) ! grid%interpol_function
614  call assert(.not.(with_x.or.with_y.or.with_z), "nuclear data '1002' must be a function of 1 parameter")
615  call assert(grid%exist_f2d, "nuclear data '1002' requires 2d table of data")
616  call assert(one_d, "nuclear data '1002' expected to be passed an effective 1d array")
617  call nuclear_data_1002(grid%f2d, w, fd1, grid%with_warning, fun_err)
618 
619  case (1003) ! grid%interpol_function
621  call assert(.not.(with_x.or.with_y.or.with_z), "resonant charge data '1003' must be a function of 1 parameter")
622  call assert(grid%exist_f1d, "resonant charge transfer data '1003' requires 1d table of data")
623  call assert(one_d, "resonant charge transfer '1003' expected to be passed an effective 1d array")
624  call rct_data_1003(grid%f1d, w, fd1, grid%with_warning, fun_err)
625 
626  case (1004) ! grid%interpol_function
628  call assert(.not.(with_y.or.with_z), "sputter data '1004' must be a function of 2 parameters")
629  call assert(grid%exist_f2d, "sputter yield '1004' requires 2d table of data")
630  call assert(one_d, "sputter yield '1004' expected to be passed an 2d array")
631  call sputter_data_1004(grid%f2d, w, x, fd1, grid%with_warning, fun_err)
632 
633  case (1005) ! grid%interpol_function
635  call assert(.not.(with_y.or.with_z), "reflection yield '1005' must be a function of 2 parameters")
636  call assert(grid%exist_f2d, "reflection yield '1005' requires 2d table of data")
637  call assert(one_d, "reflection yield '1005' expected to be passed an 2d array")
638  call reflect_data_1005(grid%f2d, w, x, fd1, grid%with_warning, fun_err)
639 
640  case (1006) ! grid%interpol_function
642  call assert(.not.(with_x.or.with_y.or.with_z), "nuclear data '1006' must be a function of 1 parameter")
643  call assert(grid%exist_f2d, "nuclear data '1006' requires 2d table of data")
644  call assert(one_d, "nuclear data '1006' expected to be passed an effective 1d array")
645  call nuclear_data_1006(grid%f2d, w, fd1, grid%with_warning, fun_err)
646 
647  case default
648  write(*,*) 'Case for grid%interpol_function = ', grid%interpol_function, ' not yet coded'
649 
650  end select
651 
652  if(fun_err%ierr.ne.0) then
653  data_error%ierr = fun_err%ierr
654  data_error%cerr = fun_err%cerr
655  endif
656 
657  end subroutine interpol
658 
660  !--------------------------------------
661  !--- sorted ---------------------------
662  !--------------------------------------
663  ! assending order
664  function sorted(x) result(result)
665  real(rkind), intent (in) :: x(:)
666  logical ::result
667 
668  ! logical:: order
669  integer:: i
670 
671  result=.true.
672  do i=1,size(x)-1
673  if(x(i)>x(i+1))then
674  result=.false.
675  exit
676  endif
677  enddo
678  end function sorted
679 
681  !------------------------------------------
682  !------ interpol_index --------------------
683  !------------------------------------------
684  subroutine interpol_index(x, axe, ix, dx, grid)
685  implicit none
686  real(rkind) , intent(in) :: x(:)
687  real(rkind) , intent(out):: axe(:)
688  real(rkind) , intent(out):: dx(:)
689  integer(ikind), intent(out):: ix(:)
690  type(grid_t) , intent(in) :: grid
691 
692 
693  real(rkind) :: dx_help(size(dx))
694  integer(ikind):: ix_lb,ix_ub
695 
696  ! after this call
697  ! ix_lb points to the 1st point >= xaxe(1)
698  ! ux_ub points to the last point <= xaxe(size(axe))
699  ! for these outside points ix is set to 0 or size(axe)+1 and
700  ! dx has been set properly
701  call bound_check(axe(:), x(:),ix(:),dx(:),ix_lb,ix_ub, grid)
702 
703  if(ix_lb>ix_ub) return
704  ! find other location of x in respect of bounds
705  call locate(axe, x(ix_lb),ix(ix_lb),dx(ix_lb))
706  call hunt(axe, x(ix_lb+1:ix_ub),ix(ix_lb+1:ix_ub),dx(ix_lb+1:ix_ub))
707  ! else
708  ! call locate(axe, xvec(:),ix(:),dx(:))
709  ! endif
710 
711  end subroutine interpol_index
712 
714  !---------------------------------------------
715  !--- bound_check ------------------------------
716  !---------------------------------------------
717  subroutine bound_check(axe, x, ix, dx, lb, ub, grid)
718  implicit none
719  real(rkind) , intent(in) :: axe(:)
720  real(rkind) , intent(in) :: x(:)
721  real(rkind) , intent(out):: dx(:)
722  integer(ikind), intent(out):: ix(:)
723  integer(ikind), intent(out):: lb, ub
724  type(grid_t) , intent(in) :: grid
725 
726 
727  integer:: i
728 
729  !axe and x are sorted in ascending order
730  !left bound
731  lb=1
732  do i=1, size(x)
733  if(x(i)>=axe(1)) then
734  exit
735  else
736  ix(i)=0
737  lb=lb+1
738  dx(i)=(x(i)-axe(1))/(axe(2)-axe(1))
739  if(grid%with_warning) call warning(.false.,"Warning "// x(i) &
740  // " < "// axe(1)// 'in grid: ?')
741  endif
742  enddo
743 
744  ! right bound
745  ub=size(x)
746  do i=size(x),1,-1
747  if(x(i)<=axe(size(axe))) then
748  exit
749  else
750  ix(i)=size(axe)+1
751  ub=ub-1
752  dx(i)=(x(i)-axe(size(axe)-1))/(axe(size(axe))-axe(size(axe)-1))
753  if(grid%with_warning) call warning(.false.," Point "// x(i) &
754  // " out of bound in grid ")
755  endif
756  enddo
757 
758  end subroutine bound_check
759 
761  !------------------------------------------
762  !------- interpo_1_1 ----------------------
763  !------------------------------------------
764  subroutine interpo_1_1(ix,dx,fgrid1,grid)
765  implicit none
766  integer(ikind), intent(in) :: ix(:)
767  real(rkind), intent(out):: fgrid1(:)
768  real(rkind), intent(in) :: dx(:)
769  type(grid_t),intent(in) :: grid
770 
771  integer :: i
772  integer :: ii1, ii2
773  !lin
774  do i=1,size(ix(:))
775  ii1=ix(i)
776  if(ix(i)<lbound(grid%f1d,1)) ii1=lbound(grid%f1d,1)
777  if(ix(i)>ubound(grid%f1d,1)) ii1=ubound(grid%f1d,1)-1
778  ii2=ii1+1
779 
780  fgrid1(i)=grid%f1d(ii1) &
781  +(grid%f1d(ii2) &
782  -grid%f1d(ii1))*dx(i)
783  enddo
784  end subroutine interpo_1_1
785 
786 
788  !------------------------------------------
789  !------- interpo_2_1 ----------------------
790  !------------------------------------------
791  subroutine interpo_2_1(ix,iy,dx,dy,fgrid1,grid)
792  implicit none
793  integer(ikind), intent(in) :: ix(:)
794  integer(ikind), intent(in) :: iy(:)
795  real(rkind), intent(out):: fgrid1(:)
796  real(rkind), intent(in) :: dx(:)
797  real(rkind), intent(in) :: dy(:)
798  type(grid_t),intent(in) :: grid
799 
800  real(rkind)::f1, f2, f3
801  integer :: i
802  integer :: ii1, ii2, jj1, jj2
803  !lin
804  do i=1,size(ix(:))
805  ii1=ix(i)
806  if(ii1<lbound(grid%f2d,1)) ii1=lbound(grid%f2d,1)
807  if(ii1>=ubound(grid%f2d,1)) ii1=ubound(grid%f2d,1)-1
808  ii2=ii1+1
809  jj1=iy(i)
810  if(jj1<lbound(grid%f2d,2)) jj1=lbound(grid%f2d,2)
811  if(jj1>=ubound(grid%f2d,2)) jj1=ubound(grid%f2d,2)-1
812  jj2=jj1+1
813 !!!
814  if(ii1.lt.1.or.ii2.gt.ubound(grid%f2d,1)) then
815  write(*,*) 'Error: ii1, ii2 = ', ii1, ii2
816  endif
817  if(jj1.lt.1.or.jj2.gt.ubound(grid%f2d,2)) then
818  write(*,*) 'Error: jj1, jj2 = ', jj1, jj2
819  endif
820  f1=grid%f2d(ii1,jj1) &
821  +(grid%f2d(ii2,jj1) &
822  -grid%f2d(ii1,jj1))*dx(i)
823  f2=grid%f2d(ii1,jj2) &
824  +(grid%f2d(ii2,jj2) &
825  -grid%f2d(ii1,jj2))*dx(i)
826  fgrid1(i)=f1+(f2-f1)*dy(i)
827  enddo
828  end subroutine interpo_2_1
829 
831  !------------------------------------------
832  !------- interpo_2_2 ----------------------
833  !------------------------------------------
834  subroutine interpo_2_2(ix,iy,dx,dy,fgrid2,grid)
835  implicit none
836  integer(ikind), intent(in) :: ix(:)
837  integer(ikind), intent(in) :: iy(:)
838  real(rkind), intent(out):: fgrid2(:,:)
839  real(rkind), intent(in) :: dx(:)
840  real(rkind), intent(in) :: dy(:)
841  type(grid_t),intent(in) :: grid
842 
843  real(rkind)::f1, f2
844  integer :: i, j
845  integer :: ii1, ii2, jj1, jj2
846  !lin
847  do j=1,size(iy(:))
848  jj1=iy(j)
849  if(jj1<lbound(grid%f2d,2)) jj1=lbound(grid%f2d,2)
850  if(jj1>ubound(grid%f2d,2)) jj1=ubound(grid%f2d,2)-1
851  jj2=jj1+1
852  do i=1,size(ix(:))
853  ii1=ix(i)
854  if(ii1<lbound(grid%f2d,1)) ii1=lbound(grid%f2d,1)
855  if(ii1>ubound(grid%f2d,1)) ii1=ubound(grid%f2d,1)-1
856  ii2=ii1+1
857  f1=grid%f2d(ii1,jj1) &
858  +(grid%f2d(ii2,jj1) &
859  -grid%f2d(ii1,jj1))*dx(i)
860  f2=grid%f2d(ii1,jj2) &
861  +(grid%f2d(ii2,jj2) &
862  -grid%f2d(ii1,jj2))*dx(i)
863  fgrid2(i,j)=f1+(f2-f1)*dy(j)
864  enddo
865  enddo
866  end subroutine interpo_2_2
867 
869  !------------------------------------------
870  !------- interpo_3_1 ----------------------
871  !------------------------------------------
872  subroutine interpo_3_1(ix,iy,iz,dx,dy,dz,fgrid1,grid)
873  implicit none
874  integer(ikind), intent(in) :: ix(:)
875  integer(ikind), intent(in) :: iy(:)
876  integer(ikind), intent(in) :: iz(:)
877  real(rkind), intent(out):: fgrid1(:)
878  real(rkind), intent(in) :: dx(:)
879  real(rkind), intent(in) :: dy(:)
880  real(rkind), intent(in) :: dz(:)
881  type(grid_t),intent(in) :: grid
882 
883  real(rkind)::f1, f2, f3, f4
884  integer :: i
885  integer :: ii1, ii2, jj1, jj2, kk1, kk2
886  !lin
887  do i=1,size(ix(:))
888  ii1=ix(i)
889  if(ii1<lbound(grid%f3d,1)) ii1=lbound(grid%f3d,1)
890  if(ii1>ubound(grid%f3d,1)) ii1=ubound(grid%f3d,1)-1
891  ii2=ii1+1
892  jj1=iy(i)
893  if(jj1<lbound(grid%f3d,2)) jj1=lbound(grid%f3d,2)
894  if(jj1>ubound(grid%f3d,2)) jj1=ubound(grid%f3d,2)-1
895  jj2=jj1+1
896  kk1=iz(i)
897  if(kk1<lbound(grid%f3d,3)) kk1=lbound(grid%f3d,3)
898  if(kk1>ubound(grid%f3d,3)) kk1=ubound(grid%f3d,3)-1
899  kk2=kk1+1
900  f1=grid%f3d(ii1,jj1,kk1) &
901  +(grid%f3d(ii2,jj1,kk1) &
902  -grid%f3d(ii1,jj1,kk1))*dx(i)
903  f2=grid%f3d(ii1,jj2,kk1) &
904  +(grid%f3d(ii2,jj2,kk1) &
905  -grid%f3d(ii1,jj2,kk1))*dx(i)
906  f3=f1+(f2-f1)*dy(i)
907  f1=grid%f3d(ii1,jj1,kk2) &
908  +(grid%f3d(ii2,jj1,kk2) &
909  -grid%f3d(ii1,jj1,kk2))*dx(i)
910  f2=grid%f3d(ii1,jj2,kk2) &
911  +(grid%f3d(ii2,jj2,kk2) &
912  -grid%f3d(ii1,jj2,kk2))*dx(i)
913  f4=f1+(f2-f1)*dy(i)
914  fgrid1(i)=f3+(f4-f3)*dz(i)
915  enddo
916  end subroutine interpo_3_1
917 
919  !------------------------------------------
920  !------- interpo_3_3 ----------------------
921  !------------------------------------------
922  subroutine interpo_3_3(ix,iy,iz,dx,dy,dz,fgrid3,grid)
923  implicit none
924  integer(ikind), intent(in) :: ix(:)
925  integer(ikind), intent(in) :: iy(:)
926  integer(ikind), intent(in) :: iz(:)
927  real(rkind), intent(out):: fgrid3(:,:,:)
928  real(rkind), intent(in) :: dx(:)
929  real(rkind), intent(in) :: dy(:)
930  real(rkind), intent(in) :: dz(:)
931  type(grid_t),intent(in) :: grid
932 
933  real(rkind)::f1, f2, f3, f4
934  integer :: i,j,k
935  integer :: ii1, ii2, jj1, jj2, kk1, kk2
936  !lin
937  do k=1,size(iz(:))
938  kk1=iz(k)
939  if(kk1<lbound(grid%f3d,3)) kk1=lbound(grid%f3d,3)
940  if(kk1>ubound(grid%f3d,3)) kk1=ubound(grid%f3d,3)-1
941  kk2=kk1+1
942  do j=1,size(iy(:))
943  jj1=iy(j)
944  if(jj1<lbound(grid%f3d,2)) jj1=lbound(grid%f3d,2)
945  if(jj1>ubound(grid%f3d,2)) jj1=ubound(grid%f3d,2)-1
946  jj2=jj1+1
947  do i=1,size(ix(:))
948  ii1=ix(i)
949  if(ii1<lbound(grid%f3d,1)) ii1=lbound(grid%f3d,1)
950  if(ii1>ubound(grid%f3d,1)) ii1=ubound(grid%f3d,1)-1
951  ii2=ii1+1
952  f1=grid%f3d(ii1,jj1,kk1)&
953  +(grid%f3d(ii2,jj1,kk1) &
954  -grid%f3d(ii1,jj1,kk1))*dx(i)
955  f2=grid%f3d(ii1,jj2,kk1) &
956  +(grid%f3d(ii2,jj2,kk1) &
957  -grid%f3d(ii1,jj2,kk1))*dx(i)
958  f3=f1+(f2-f1)*dy(j)
959  f1=grid%f3d(ii1,jj1,kk2) &
960  +(grid%f3d(ii2,jj1,kk2) &
961  -grid%f3d(ii1,jj1,kk2))*dx(i)
962  f2=grid%f3d(ii1,jj2,kk2) &
963  +(grid%f3d(ii2,jj2,kk2) &
964  -grid%f3d(ii1,jj2,kk2))*dx(i)
965  f4=f1+(f2-f1)*dy(j)
966  fgrid3(i,j,k)=f3+(f4-f3)*dz(k)
967  enddo
968  enddo
969  enddo
970  end subroutine interpo_3_3
971 
973  !------------------------------------------
974  !------- interpo_4_1 ----------------------
975  !------------------------------------------
976  subroutine interpo_4_1(iw,ix,iy,iz,dw,dx,dy,dz,fgrid1,grid)
977  implicit none
978  integer(ikind), intent(in) :: iw(:)
979  integer(ikind), intent(in) :: ix(:)
980  integer(ikind), intent(in) :: iy(:)
981  integer(ikind), intent(in) :: iz(:)
982  real(rkind), intent(out):: fgrid1(:)
983  real(rkind), intent(in) :: dw(:)
984  real(rkind), intent(in) :: dx(:)
985  real(rkind), intent(in) :: dy(:)
986  real(rkind), intent(in) :: dz(:)
987  type(grid_t),intent(in) :: grid
988 
989  real(rkind)::f1, f2, f3, f4, f5, f6
990  integer :: i
991  integer :: ll1,ll2,ii1,ii2,jj1,jj2,kk1,kk2
992  !lin
993  do i=1,size(iw(:))
994  ll1=iw(i)
995  if(ll1<lbound(grid%f4d,1)) ll1=lbound(grid%f4d,1)
996  if(ll1>ubound(grid%f4d,1)) ll1=ubound(grid%f4d,1)-1
997  ll2=ll1+1
998  ii1=ix(i)
999  if(ii1<lbound(grid%f4d,2)) ii1=lbound(grid%f4d,2)
1000  if(ii1>ubound(grid%f4d,2)) ii1=ubound(grid%f4d,2)-1
1001  ii2=ii1+1
1002  jj1=iy(i)
1003  if(jj1<lbound(grid%f4d,3)) jj1=lbound(grid%f4d,3)
1004  if(jj1>ubound(grid%f4d,3)) jj1=ubound(grid%f4d,3)-1
1005  jj2=jj1+1
1006  kk1=iz(i)
1007  if(kk1<lbound(grid%f4d,4)) kk1=lbound(grid%f4d,4)
1008  if(kk1>ubound(grid%f4d,4)) kk1=ubound(grid%f4d,4)-1
1009  kk2=kk1+1
1010  ! building interpolation for first cube
1011  f1=grid%f4d(ll1,ii1,jj1,kk1) &
1012  +(grid%f4d(ll2,ii1,jj1,kk1) &
1013  -grid%f4d(ll1,ii1,jj1,kk1))*dw(i)
1014  f2=grid%f4d(ll1,ii2,jj1,kk1) &
1015  +(grid%f4d(ll2,ii2,jj1,kk1) &
1016  -grid%f4d(ll1,ii2,jj1,kk1))*dw(i)
1017  f3=f1+(f2-f1)*dx(i)
1018  f1=grid%f4d(ll1,ii1,jj2,kk1) &
1019  +(grid%f4d(ll2,ii1,jj2,kk1) &
1020  -grid%f4d(ll1,ii1,jj2,kk1))*dw(i)
1021  f2=grid%f4d(ll1,ii2,jj2,kk1) &
1022  +(grid%f4d(ll2,ii2,jj2,kk1) &
1023  -grid%f4d(ll1,ii2,jj2,kk1))*dw(i)
1024  f4=f1+(f2-f1)*dx(i)
1025 
1026  f5=f3+(f4-f3)*dy(i)
1027  ! done
1028  ! build second cube
1029  f1=grid%f4d(ll1,ii1,jj1,kk2) &
1030  +(grid%f4d(ll2,ii1,jj1,kk2) &
1031  -grid%f4d(ll1,ii1,jj1,kk2))*dw(i)
1032  f2=grid%f4d(ll1,ii2,jj1,kk2) &
1033  +(grid%f4d(ll2,ii2,jj1,kk2) &
1034  -grid%f4d(ll1,ii2,jj1,kk2))*dw(i)
1035  f3=f1+(f2-f1)*dx(i)
1036  f1=grid%f4d(ll1,ii1,jj2,kk2) &
1037  +(grid%f4d(ll2,ii1,jj2,kk2) &
1038  -grid%f4d(ll1,ii1,jj2,kk2))*dw(i)
1039  f2=grid%f4d(ll1,ii2,jj2,kk2) &
1040  +(grid%f4d(ll2,ii2,jj2,kk2) &
1041  -grid%f4d(ll1,ii2,jj2,kk2))*dw(i)
1042  f4=f1+(f2-f1)*dx(i)
1043 
1044  f6=f3+(f4-f3)*dy(i)
1045  ! done
1046  fgrid1(i)=f5+(f6-f5)*dz(i)
1047 
1048  enddo
1049 
1050  end subroutine interpo_4_1
1051 
1052 
1054  !------------------------------------------
1055  !------- interpo_4_4 ----------------------
1056  !------------------------------------------
1057  subroutine interpo_4_4(iw,ix,iy,iz,dw,dx,dy,dz,fgrid1,grid)
1058  implicit none
1059  integer(ikind), intent(in) :: iw(:)
1060  integer(ikind), intent(in) :: ix(:)
1061  integer(ikind), intent(in) :: iy(:)
1062  integer(ikind), intent(in) :: iz(:)
1063  real(rkind), intent(out):: fgrid1(:,:,:,:)
1064  real(rkind), intent(in) :: dw(:)
1065  real(rkind), intent(in) :: dx(:)
1066  real(rkind), intent(in) :: dy(:)
1067  real(rkind), intent(in) :: dz(:)
1068  type(grid_t),intent(in) :: grid
1069 
1070  real(rkind)::f1, f2, f3, f4, f5, f6
1071  integer :: l,i,j,k
1072  integer :: ll1,ll2,ii1,ii2,jj1,jj2,kk1,kk2
1073  !lin
1074  do k=1,size(iz(:))
1075  kk1=iz(i)
1076  if(kk1<lbound(grid%f4d,4)) kk1=lbound(grid%f4d,4)
1077  if(kk1>ubound(grid%f4d,4)) kk1=ubound(grid%f4d,4)-1
1078  kk2=kk1+1
1079  do j=1,size(iy(:))
1080  jj1=iy(i)
1081  if(jj1<lbound(grid%f4d,3)) jj1=lbound(grid%f4d,3)
1082  if(jj1>ubound(grid%f4d,3)) jj1=ubound(grid%f4d,3)-1
1083  jj2=jj1+1
1084  do i=1,size(ix(:))
1085  ii1=ix(i)
1086  if(ii1<lbound(grid%f4d,2)) ii1=lbound(grid%f4d,2)
1087  if(ii1>ubound(grid%f4d,2)) ii1=ubound(grid%f4d,2)-1
1088  ii2=ii1+1
1089  do l=1,size(iw(:))
1090  ll1=iw(i)
1091  if(ll1<lbound(grid%f4d,1)) ll1=lbound(grid%f4d,1)
1092  if(ll1>ubound(grid%f4d,1)) ll1=ubound(grid%f4d,1)-1
1093  ll2=ll1+1
1094  ! building interpolation for first cube
1095  f1=grid%f4d(ll1,ii1,jj1,kk1) &
1096  +(grid%f4d(ll2,ii1,jj1,kk1) &
1097  -grid%f4d(ll1,ii1,jj1,kk1))*dw(l)
1098  f2=grid%f4d(ll1,ii2,jj1,kk1) &
1099  +(grid%f4d(ll2,ii2,jj1,kk1) &
1100  -grid%f4d(ll1,ii2,jj1,kk1))*dw(l)
1101  f3=f1+(f2-f1)*dx(i)
1102  f1=grid%f4d(ll1,ii1,jj2,kk1) &
1103  +(grid%f4d(ll2,ii1,jj2,kk1) &
1104  -grid%f4d(ll1,ii1,jj2,kk1))*dw(l)
1105  f2=grid%f4d(ll1,ii2,jj2,kk1) &
1106  +(grid%f4d(ll2,ii2,jj2,kk1) &
1107  -grid%f4d(ll1,ii2,jj2,kk1))*dw(l)
1108  f4=f1+(f2-f1)*dx(i)
1109 
1110  f5=f3+(f4-f3)*dy(i)
1111  ! done
1112  ! build second cube
1113  f1=grid%f4d(ll1,ii1,jj1,kk2) &
1114  +(grid%f4d(ll2,ii1,jj1,kk2) &
1115  -grid%f4d(ll1,ii1,jj1,kk2))*dw(l)
1116  f2=grid%f4d(ll1,ii2,jj1,kk2) &
1117  +(grid%f4d(ll2,ii2,jj1,kk2) &
1118  -grid%f4d(ll1,ii2,jj1,kk2))*dw(l)
1119  f3=f1+(f2-f1)*dx(i)
1120  f1=grid%f4d(ll1,ii1,jj2,kk2) &
1121  +(grid%f4d(ll2,ii1,jj2,kk2) &
1122  -grid%f4d(ll1,ii1,jj2,kk2))*dw(l)
1123  f2=grid%f4d(ll1,ii2,jj2,kk2) &
1124  +(grid%f4d(ll2,ii2,jj2,kk2) &
1125  -grid%f4d(ll1,ii2,jj2,kk2))*dw(l)
1126  f4=f1+(f2-f1)*dx(i)
1127 
1128  f6=f3+(f4-f3)*dy(i)
1129  ! done
1130  fgrid1(l,i,j,k)=f5+(f6-f5)*dz(i)
1131 
1132  enddo
1133  enddo
1134  enddo
1135  enddo
1136 
1137  end subroutine interpo_4_4
1138 
1140  !------------------------------------------------
1141  !-------- hunt ----------------------------------
1142  !------------------------------------------------
1143 
1144  subroutine hunt(axe,x,ix,dx)
1145  implicit none
1146  ! be careful, the axe is not necessarily starting with low bound=1
1147  ! to use the hunt search from num.rec. to get index of x the vector
1148  ! of axe must be adjusted to start with idx 1. This is done by calling
1149  ! hunt with the internal x vec. of axe. The calling mechanisme will
1150  ! addmit then that the pass vector starts with one.
1151  !
1152  ! The return indexes are then reset to the correct index after calling hunt_nrv
1153  !
1154  ! Additionaly dx is computed for interpolation
1155 
1156  real(rkind) , intent(inout) :: axe(:)
1157  real(rkind), intent(in) :: x(:)
1158  real(rkind), intent(out) :: dx(:)
1159  integer(ikind), intent(out) :: ix(:)
1160  integer(ikind), save :: last_access=1
1161 
1162  integer :: lbnd, ubnd
1163  integer :: i
1164 
1165  lbnd=lbound(axe(:),1)
1166  ubnd=ubound(axe(:),1)
1167 
1168 
1169  ! call hunt_nrv with internal vector
1170  call hunt_nrv(axe(:), x(:), ix(:), last_access)
1171  ! addjust to bound of axe
1172  ix(:)=ix(:)+lbnd-1
1173 
1174  do i=1,size(x)
1175  if(ix(i)<ubnd)then
1176  dx(i)=(x(i)-axe(ix(i)))/(axe(ix(i)+1)-axe(ix(i)))
1177  else
1178  dx(i)=0
1179  endif
1180  enddo
1181  end subroutine hunt
1182 
1184  !------------------------------------------------
1185  !-------- hunt_nrv ------------------------------
1186  !------------------------------------------------
1187  ! it is guaranteed by calling that xx and x are indexed from 1 to size(..)
1188  !
1189  ! just like hunt in num recip
1190  ! but x is a vextor and a colecting index vector is pass
1191  !
1192  subroutine hunt_nrv(xx,x,ix,jlo)
1193  implicit none
1194  !..given an array xx of length n and a value x, this routine returns a value
1195  !..jlo such that x is between xx(jlo) and xx(jlo+1). the array xx must be
1196  !..monotonic. j=0 or j=n indicates that x is out of range. on input jlo is a
1197  !..guess for the table entry, and should be used as input for the next hunt.
1198  !..one assumes the next table entry is relatively close to the old one.
1199 
1200  real(rkind), intent(in) :: xx(:)
1201  real(rkind), intent(in) :: x(:)
1202  integer(ikind), intent(out) :: ix(:)
1203  integer(ikind), intent(inout) :: jlo
1204 
1205  integer :: n,inc,jhi,jm
1206  logical :: ascnd
1207 
1208  integer :: i
1209 
1210  n=size(xx)
1211 
1212  !..logical function; true if ascending table, false if descending
1213  ascnd = (xx(n) >= xx(1))
1214 
1215  do i=1,size(x)
1216  !..initial guess is not useful; go to bisection immediatly
1217  if (jlo <= 0 .or. jlo > n) then
1218  jlo=0
1219  jhi=n+1
1220  else
1221  inc=1 ! set the initial hunting increment
1222 
1223  !..this is the hunt up section
1224  if (x(i) >= xx(jlo) .eqv. ascnd) then
1225  do
1226  jhi=jlo+inc
1227  if (jhi > n) then ! done hunting since end of table
1228  jhi=n+1
1229  exit
1230  else
1231  if (x(i) < xx(jhi) .eqv. ascnd) exit
1232  jlo=jhi !not done hunting
1233  inc=inc+inc !so double increment
1234  end if
1235  end do ! and try again
1236  else ! hunt done
1237  jhi=jlo
1238  do
1239  jlo=jhi-inc
1240  if (jlo < 1) then ! hunt done, since end of table
1241  jlo=0
1242  exit
1243  else
1244  if (x(i) >= xx(jlo) .eqv. ascnd) exit
1245  jhi=jlo !not done hunting
1246  inc=inc+inc !so double increment
1247  end if
1248  end do ! and try again
1249  end if
1250  end if ! done hunting, value bracketed
1251  do ! Hunting is done, begin final bisection phase
1252  if (jhi-jlo <= 1) then
1253  if (x(i) == xx(n)) jlo=n-1
1254  if (x(i) == xx(1)) jlo=1
1255  exit
1256  else
1257  jm=(jhi+jlo)/2
1258  if (x(i) >= xx(jm) .eqv. ascnd) then
1259  jlo=jm
1260  else
1261  jhi=jm
1262  end if
1263  end if
1264  end do
1265  ix(i)=jlo
1266  enddo!(i)
1267  end subroutine hunt_nrv
1268 
1270  !----------------------------------------------------------
1271  !------------ locate ------------------------------------
1272  !----------------------------------------------------------
1273  !
1274  ! same as hunt search, using midpoint method
1275  !
1276 
1277  subroutine locate(axe, x, ix, dx)
1278  implicit none
1279  !..given an array xx of length n, and a value of x, this routine returns
1280  !..a value j such that x is between xx(j) and xx(j+1). the array xx must be
1281  !..monotonic. j=0 or j=n indicates that x is out of range. bisection is used
1282  !..to find the entry
1283 
1284  real(rkind), intent(inout) :: axe(:)
1285  real(rkind), intent(in) :: x
1286  real(rkind), intent(out) :: dx
1287  integer(ikind), intent(out) :: ix
1288 
1289  integer :: lbnd, ubnd
1290  integer :: i
1291 
1292  lbnd=lbound(axe(:),1)
1293  ubnd=ubound(axe(:),1)
1294 
1295  ! get index
1296  ix=locate_nrv(axe(:),x)
1297  ! addjust to bound of axe
1298  ix=ix+lbnd-1
1299 
1300  if(ix<ubnd)then
1301  dx=(x-axe(ix))/(axe(ix+1)-axe(ix))
1302  else
1303  dx=0
1304  endif
1305 
1306  ! last search for hunt search
1307  ! axe%last_access=ix(size(x))+lbnd-1
1308 
1309  end subroutine locate
1310 
1311 
1313  !----------------------------------------------------------
1314  !------------ locate_nrv ----------------------------------
1315  !----------------------------------------------------------
1316 
1317  function locate_nrv(xx,x) result (result)
1318  !..given an array xx of length n, and a value of x, this routine returns
1319  !..a value j such that x is between xx(j) and xx(j+1). the array xx must be
1320  !..monotonic. j=0 or j=n indicates that x is out of range. bisection is used
1321  !..to find the entry
1322 
1323  real(rkind), intent(in) :: xx(:)
1324  real(rkind), intent(in) :: x
1325 
1326  integer :: result
1327  integer :: n,jl,jm,ju
1328  logical :: ascnd
1329 
1330  integer :: i
1331 
1332  n=size(xx)
1333  ascnd = (xx(n) >= xx(1))
1334  jl=0
1335  ju=n+1
1336  do
1337  if (ju-jl <= 1) exit
1338  !..compute a midpoint, and replace either the upper or lower limit
1339  jm=(ju+jl)/2
1340  if (ascnd .eqv. (x >= xx(jm))) then
1341  jl=jm
1342  else
1343  ju=jm
1344  end if
1345  end do
1346  if (x == xx(1)) then
1347  result=1
1348  else if (x == xx(n)) then
1349  result=n-1
1350  else
1351  result=jl
1352  end if
1353 
1354  end function locate_nrv
1355 
1356 end module data_suport
subroutine reflect_data_1005(function_parameters, energy_arr, angle_arr, refl_arr, with_warnings, fun_err)
AMNS External function ...
utils module from Silvio Gori&#39;s grid package
Definition: call_utils.F90:8
subroutine nuclear_data_1001(function_parameters, x, f, with_warnings, fun_err)
AMNS External function ...
subroutine, public interpol(w, x, y, z, fd1, fd2, fd3, fd4, grid, data_error)
interpolate in the grid
subroutine sputter_data_1004(function_parameters, energy_arr, angle_arr, yield_arr, with_warnings, fun_err)
AMNS External function ...
subroutine nuclear_data_1002(function_parameters, Tin, f, with_warnings, fun_err)
AMNS External function ...
for i
Definition: amns.pyx:365
unit_h module from Silvio Gori&#39;s grid package
Definition: unit_h.F90:9
strings module from Silvio Gori&#39;s grid package
Definition: strings.F90:19
subroutine rct_data_1003(function_parameters, Tin, f, with_warnings, fun_err)
AMNS External function ...
if error_status np ndarray[np.double_t, ndim=2] np ndarray[np.double_t, ndim=2] np ndarray[np.double_t, ndim=2] ndim
Definition: amns.pyx:287
subroutine, public warning(lcond, message)
Definition: call_utils.F90:44
subroutine, public delete(grid)
deallocate a grid
subroutine nuclear_data_1006(function_parameters, x, f, with_warnings, fun_err)
logical function sorted(x)
return true if the passed array is sorted
f90_kind module from Silvio Gori&#39;s grid package
Definition: f90_kind.F90:9
subroutine, public set_option(grid, warning)
set the &quot;with_warning&quot; flag in grid to the value of &quot;warning&quot;
subroutine, public assert(lcond, message)
Definition: call_utils.F90:29