ITM AMNS: User Interface  \$Id: Doxyfile 502 2015-10-15 12:23:45Z dpc $
amns_external_functions.F90
Go to the documentation of this file.
1 
10 
11  use itm_types
12  implicit none
13 
14  type fun_err_t
15  integer :: ierr
16  character (len=128) :: cerr
17  end type fun_err_t
18 
19 contains
20 
26  subroutine nuclear_data_1001(function_parameters, x, f, with_warnings, fun_err)
27  implicit none
28  real (R8), intent(in) :: function_parameters(:,:), x(:)
29  real (R8), intent(out) :: f(:)
30  logical, intent(in) :: with_warnings
31  type (fun_err_t), intent(out) :: fun_err
32  integer :: i, j
33  real (R8) :: e, s
34 
35  fun_err%ierr = 0
36  fun_err%cerr = ''
37 
38  if(size(function_parameters,1).ne.12) then
39  write(fun_err%cerr,*) "nuclear_data_1001: Expected the length of 'function_parameters' to be 12 in 'nuclear_data_1001' and not ", &
40  size(function_parameters)
41  fun_err%ierr = -1
42  return
43  endif
44  if(size(x).ne.size(f)) then
45  write(fun_err%cerr,*) "nuclear_data_1001: Expected the input and output vectors to be the same size in 'nuclear_data_1001'"
46  fun_err%ierr = -1
47  return
48  endif
49 
50  do i=1, size(x)
51  e = x(i) * 1.0e-3_r8
52  j=1
53  if(e.lt.function_parameters(11,j) .and. with_warnings) then
54  write(*,*) 'extrapolating below the desired range'
55  endif
56  do while(e.gt.function_parameters(12,j).and. &
57  j.lt.size(function_parameters,2))
58  j=j+1
59  enddo
60  if(e.gt.function_parameters(12,j)) then
61  if (with_warnings) then
62  write(*,*) 'extrapolating above the desired range'
63  write(*,*) j, x(i), function_parameters(12,j)
64  write(*,*) 'Taking the boundary value when calculating S!'
65  endif
66  e = function_parameters(12,j)
67  endif
68  s = ( function_parameters(2,j) &
69  & + e*(function_parameters(3,j) &
70  & + e*(function_parameters(4,j) &
71  & + e*( function_parameters(5,j) &
72  & +e*function_parameters(6,j) ) ) ) ) &
73  & /( 1 + e*(function_parameters(7,j)&
74  & + e*(function_parameters(8,j) &
75  & + e*( function_parameters(9,j) &
76  & +e*function_parameters(10,j) ) ) ) )
77  ! We clamp the energy for S (the nuclear fusion probability).
78  ! However, there is no need to clamp the energy in denominator.
79  ! The denominator roughly describes the probability of the reactants to
80  ! overcome the Coulomb barrier.
81  e = x(i) * 1.0e-3_r8
82  f(i) = s / (e * exp(function_parameters(1,j)/sqrt(e))) * 1.0e-31_r8
83  enddo
84  end subroutine nuclear_data_1001
85 
91  subroutine nuclear_data_1002(function_parameters, Tin, f, with_warnings, fun_err)
92  implicit none
93  real (R8), intent(in) :: function_parameters(:,:), tin(:)
94  real (R8), intent(out) :: f(:)
95  logical, intent(in) :: with_warnings
96  type (fun_err_t), intent(out) :: fun_err
97  integer :: it ! index for the different energy vaulues
98  integer :: ir ! index for possible different temperature ranges
99 
100  real (R8) :: t
101  real (R8) :: theta,xi,mrc2,bg
102  real (R8) :: c(1:7)
103 
104  fun_err%ierr = 0
105  fun_err%cerr = ''
106 
107  if(size(function_parameters,1).ne.11) then
108  write(fun_err%cerr,*) "nuclear_data_1002: Expected the length of 'function_parameters' to be 11 in 'nuclear_data_1002' and not ", &
109  size(function_parameters)
110  fun_err%ierr = -1
111  return
112  endif
113  if(size(tin).ne.size(f)) then
114  write(fun_err%cerr,*) "nuclear_data_1002: Expected the input and output vectors to be the same size in 'nuclear_data_1002'"
115  fun_err%ierr = -1
116  return
117  endif
118 
119 
120 
121 
122  do it=1, size(tin)
123  t=tin(it)*1e-3 ! temperature in keV
124  ir=1
125  if(t.lt.function_parameters(10,ir) .and. with_warnings) then
126  write(*,*) 'extrapolating below the desired range'
127  endif
128  do while(t.gt.function_parameters(11,ir).and. &
129  ir.lt.size(function_parameters,2))
130  ir=ir+1
131  enddo
132  if(t.gt.function_parameters(11,ir) .and. with_warnings) then
133  write(*,*) 'extrapolating above the desired range'
134 ! dpc fix: changed 12 to 11
135  write(*,*) ir, tin(it), function_parameters(11,ir)
136  endif
137 
138  bg =function_parameters(1, ir)
139  mrc2=function_parameters(2, ir)
140  c =function_parameters(3:9, ir)
141  ! (/Tmin,Tmax/) = function_parameters(10:11, iR)
142 
143  theta=t/(1-t*(c(2)+t*(c(4)+t*c(6)))&
144  /(1+t*(c(3)+t*(c(5)+t*c(7)))))
145  xi=(bg**2/(4*theta))**(1.0_r8/3.0_r8)
146  f(it) = c(1)*theta*sqrt(xi/(mrc2*t**3))&
147  *exp(-3*xi)*1.e-6 ! from cm^3/s to m^3s/
148 
149 
150 
151  end do
152 
153  end subroutine nuclear_data_1002
154 
160  subroutine rct_data_1003(function_parameters, Tin, f, with_warnings, fun_err)
161  implicit none
162  real (R8), intent(in) :: function_parameters(:), tin(:)
163  real (R8), intent(out) :: f(:)
164  logical, intent(in) :: with_warnings
165  type (fun_err_t), intent(out) :: fun_err
166  integer :: it
167 
168  fun_err%ierr = 0
169  fun_err%cerr = ''
170 
171  if(size(function_parameters,1).ne.2) then
172  write(fun_err%cerr,*) "rct_data_1003: Expected the length of 'function_parameters' to be 2 in 'rct_data_1003' and not ", &
173  size(function_parameters)
174  fun_err%ierr = -1
175  return
176  endif
177  if(size(tin).ne.size(f)) then
178  write(fun_err%cerr,*) "rct_data_1003: Expected the input and output vectors to be the same size in 'rct_data_1003'"
179  fun_err%ierr = -1
180  return
181  endif
182 
183  do it=1, size(tin)
184  f(it) = function_parameters(1)*(1.0_r8 + function_parameters(2)* log(1.0_r8/tin(it)))**2*1e-20_r8
185  end do
186 
187  end subroutine rct_data_1003
188 
196  subroutine sputter_data_1004(function_parameters, energy_arr, angle_arr, yield_arr, with_warnings, fun_err)
197  use eckstein_yields
198  implicit none
199  real (R8), intent(in) :: function_parameters(:,:), energy_arr(:), angle_arr(:)
200  real (R8), intent(out) :: yield_arr(:)
201  logical, intent(in) :: with_warnings
202  type (fun_err_t), intent(out) :: fun_err
203 
204  real (R8) :: energy, angle, yield
205  real(R8) :: matchanglee0, matchanglee1
206  real(R8) :: m1, m2, z1, z2, q, lambda, mu, eth, f,b,c,esp
207  integer :: numtab, ianglee0, numpars, boundianglee0, ipars
208  integer :: id, ia
209  logical, parameter :: debug=.true.
210 
211  integer :: have_angle_data
212 
213  fun_err%ierr = 0
214  fun_err%cerr = ''
215 
216  numtab = ubound(function_parameters, 2)
217  if(debug .and. with_warnings) then
218  write(*,*) numtab
219  endif
220  do id = lbound(energy_arr,1), ubound(energy_arr,1)
221 
222  energy = energy_arr(id)
223  angle = angle_arr(id)
224 
225  if(debug .and. with_warnings) then
226  write(*,*) energy, angle
227  endif
228 
229  matchanglee0 = 0.0
230  boundianglee0 = -1
231  have_angle_data = -1
232  do ia = lbound(function_parameters, 2), ubound(function_parameters, 2)
233  matchanglee1 = function_parameters(3, ia)
234  if(debug .and. with_warnings) then
235  write(*,*) matchanglee0, energy, matchanglee1
236  endif
237  if((matchanglee0.le.energy).and.(matchanglee1.ge.energy)) then
238  boundianglee0 = ia
239  have_angle_data = 1
240  exit
241  end if
242  if (matchanglee1 < matchanglee0) then
243  if (matchanglee1 < matchanglee0) then
244  if(debug .and. with_warnings) then
245  write(*, *) 'WARNING::sputteryield-> no angular reflection yield data available, returning value for perpendicular impact'
246  endif
247  have_angle_data = -1
248  exit
249  else
250  write(fun_err%cerr,*) 'sputter_data_1004: sputteryield-> angular dependence energies are not sorted, rebuild the database'
251  fun_err%ierr = -1
252  return
253  endif
254  end if
255  matchanglee0 = matchanglee1
256  end do
257 
258  if(boundianglee0.lt.0) then
259  if (debug .and. with_warnings) then
260  write(*,*) 'sputter_data_1004: No Bound found for: ', energy, ' angle: ', angle, 'using boundianglee0 = ', numtab
261  end if
262  boundianglee0 = ubound(function_parameters, 2)
263  end if
264 
265  m1 = function_parameters( 4, boundianglee0)
266  m2 = function_parameters( 5, boundianglee0)
267  z1 = function_parameters( 1, boundianglee0)
268  z2 = function_parameters( 2, boundianglee0)
269  q = function_parameters( 6, boundianglee0)
270  lambda = function_parameters( 9, boundianglee0)
271  eth = function_parameters( 8, boundianglee0)
272  mu = function_parameters( 7, boundianglee0)
273  f = function_parameters(10, boundianglee0)
274  b = function_parameters(11, boundianglee0)
275  c = function_parameters(12, boundianglee0)
276  esp = function_parameters(13, boundianglee0)
277 
278  yield = 0.0
279  if (energy .gt. eth) then
280  if (have_angle_data .gt. 0) then
281  yield = seyield(energy, m1, m2, z1, z2, q, lambda, mu, eth) * sayield(energy, angle, f, b, c, esp)
282  else
283  yield = seyield(energy, m1, m2, z1, z2, q, lambda, mu, eth)
284  endif
285  end if
286 
287  yield_arr(id) = yield
288 
289  enddo
290 
291  end subroutine sputter_data_1004
292 
300  subroutine reflect_data_1005(function_parameters, energy_arr, angle_arr, refl_arr, with_warnings, fun_err)
301  use eckstein_yields
302  implicit none
303  real (R8), intent(in) :: function_parameters(:,:), energy_arr(:), angle_arr(:)
304  real (R8), intent(out) :: refl_arr(:)
305  logical, intent(in) :: with_warnings
306  type (fun_err_t), intent(out) :: fun_err
307 
308  real (R8) :: energy, angle, refl
309  real(R8) :: m1, m2, z1, z2, a1, a2, a3, a4, e1, esp, anglee0, anglee1, c1, c2, c3, c4
310  real(R8) :: c1from, c2from, c3from, c4from
311  real(R8) :: c1to, c2to, c3to, c4to
312  real(R8) :: matchanglee0, matchanglee1
313  integer :: numtab, ianglee0, numpars, boundianglee0, boundianglee1, ipars
314  integer :: id, ia
315  logical, parameter :: debug=.true.
316 
317  integer :: have_angle_data
318 
319  fun_err%ierr = 0
320  fun_err%cerr = ''
321 
322  numtab = ubound(function_parameters, 2)
323  do id = lbound(energy_arr,1), ubound(energy_arr,1)
324 
325  energy = energy_arr(id)
326  angle = angle_arr(id)
327 
328  matchanglee0 = 0.0
329  boundianglee0 = -1
330  boundianglee1 = -1
331  have_angle_data = -1
332  do ia = lbound(function_parameters, 2), ubound(function_parameters, 2)
333  matchanglee1 = function_parameters(11, ia)
334  if(debug .and. with_warnings) then
335  write(*,*) matchanglee0, energy, matchanglee1
336  endif
337  if((matchanglee0.le.energy).and.(matchanglee1.ge.energy)) then
338  if (ia .gt. 1) then
339  if(ia .lt. numtab) then
340  boundianglee0 = ia - 1
341  boundianglee1 = ia
342  else
343  boundianglee0 = numtab
344  boundianglee1 = numtab
345  end if
346  else
347  boundianglee0 = 1
348  boundianglee1 = 1
349  end if
350  have_angle_data = 1
351  exit
352  end if
353  if (matchanglee1 < matchanglee0) then
354  if (matchanglee1 .lt. 0) then
355  if(debug .and. with_warnings) then
356  write(*,*) 'WARNING::reflyield-> no angular reflection yield data available, returning value for perpendicular impact'
357  endif
358  have_angle_data = -1
359  exit
360  else
361  write(fun_err%cerr,*) 'reflect_data_1005: reflyield-> angular dependence energies are not sorted, rebuild the database'
362  fun_err%ierr = -1
363  return
364  end if
365  endif
366  matchanglee0 = matchanglee1
367  end do
368 
369  if((boundianglee0.lt.0).or.(boundianglee1.lt.0)) then
370  if (matchanglee1.lt.energy) then
371  boundianglee0 = numtab
372  boundianglee1 = numtab
373  else
374  boundianglee0 = 1
375  boundianglee1 = 1
376  end if
377  if (debug .and. with_warnings) then
378  write(*,*) 'reflect_data_1005: No Bound found for: ', energy, ' angle: ', angle, 'using boundianglee0 = ', boundianglee0, 'and boundianglee1 = ',boundianglee1
379  end if
380  end if
381 
382  z1 = function_parameters( 1, boundianglee0)
383  z2 = function_parameters( 2, boundianglee0)
384  m1 = function_parameters( 3, boundianglee0)
385  m2 = function_parameters( 4, boundianglee0)
386  a1 = function_parameters( 5, boundianglee0)
387  a2 = function_parameters( 6, boundianglee0)
388  a3 = function_parameters( 7, boundianglee0)
389  a4 = function_parameters( 8, boundianglee0)
390  e1 = function_parameters( 9, boundianglee0)
391  esp = function_parameters(10, boundianglee0)
392 
393  if ((angle.lt.1.0).or.(have_angle_data.eq.-1)) then
394  if (debug .and. with_warnings) then
395  write(*,*) 'angle = ',angle, ' is small or no angular data available: using perpendicular impact model with energy dependence'
396  end if
397  refl = reyield(energy, m1, m2, z1, z2, a1, a2, a3, a4)
398  else
399  if (debug .and. with_warnings) then
400  write(*,*) 'angle = ',angle, ' is large using angular dependent model and interpolation of energy dependence'
401  end if
402  ! Interplolate the bounding table entries
403  if(boundianglee0.lt.boundianglee1) then
404  anglee0 = function_parameters(11, boundianglee0)
405  anglee1 = function_parameters(11, boundianglee1)
406  if(debug .and. with_warnings) then
407  write(*,*) 'Interpolating angular dependent reflection yield for energy' ,energy,' between values for energies ', anglee0, ' and ', anglee1
408  end if
409  c1from = function_parameters(12, boundianglee0)
410  c2from = function_parameters(13, boundianglee0)
411  c3from = function_parameters(14, boundianglee0)
412  c4from = function_parameters(15, boundianglee0)
413 
414  c1to = function_parameters(12, boundianglee1)
415  c2to = function_parameters(13, boundianglee1)
416  c3to = function_parameters(14, boundianglee1)
417  c4to = function_parameters(15, boundianglee1)
418 
419  c1 = c1from + ((energy - anglee0) * (c1to - c1from) / (anglee1 - anglee0))
420  c2 = c2from + ((energy - anglee0) * (c2to - c2from) / (anglee1 - anglee0))
421  c3 = c3from + ((energy - anglee0) * (c3to - c3from) / (anglee1 - anglee0))
422  c4 = c4from + ((energy - anglee0) * (c4to - c4from) / (anglee1 - anglee0))
423  else
424  anglee0 = function_parameters(11, boundianglee0)
425  if(debug .and. with_warnings) then
426  write(*,*) 'Energy: ',energy,' for requested angle: ',angle,' not within db bounds using anglular dependent value at energy = ', anglee0
427  end if
428  c1 = function_parameters(12, boundianglee0)
429  c2 = function_parameters(13, boundianglee0)
430  c3 = function_parameters(14, boundianglee0)
431  c4 = function_parameters(15, boundianglee0)
432  end if
433  refl = rayield(angle, c1, c2, c3, c4)
434  end if
435 
436  refl_arr(id) = min(1.0_r8, refl)
437 
438  enddo
439 
440  end subroutine reflect_data_1005
441 
442  subroutine nuclear_data_1006(function_parameters, x, f, with_warnings, fun_err)
443  implicit none
444  real (R8), intent(in) :: function_parameters(:,:), x(:)
445  real (R8), intent(out) :: f(:)
446  logical, intent(in) :: with_warnings
447  type (fun_err_t), intent(out) :: fun_err
448  integer :: i, j
449  real (R8) :: e, s
450 
451  fun_err%ierr = 0
452  fun_err%cerr = ''
453 
454  if(size(function_parameters,1).ne.14) then
455  write(fun_err%cerr,*) "nuclear_data_1006: Expected the length of 'function_parameters' to be 14 in 'nuclear_data_1006' and not ", &
456  size(function_parameters)
457  fun_err%ierr = -1
458  return
459  endif
460  if(size(x).ne.size(f)) then
461  write(fun_err%cerr,*) "nuclear_data_1006: Expected the input and output vectors to be the same size in 'nuclear_data_1006'"
462  fun_err%ierr = -1
463  return
464  endif
465 
466  do i=1, size(x)
467  e = x(i) * 1.0e-3_r8
468  j=1
469  if(e.lt.function_parameters(13,j) .and. with_warnings) then
470  write(*,*) 'extrapolating below the desired range'
471  endif
472  do while(e.gt.function_parameters(14,j).and. &
473  j.lt.size(function_parameters,2))
474  j=j+1
475  enddo
476  if(e.gt.function_parameters(14,j)) then
477  if (with_warnings) then
478  write(*,*) 'extrapolating above the desired range'
479  write(*,*) j, x(i), function_parameters(12,j)
480  write(*,*) 'Taking the boundary value when calculating S!'
481  endif
482  e = function_parameters(14,j)
483  endif
484  s = ( function_parameters(2,j) &
485  & + e*(function_parameters(3,j) &
486  & + e*(function_parameters(4,j) &
487  & + e*(function_parameters(5,j) &
488  & + e*(function_parameters(6,j) &
489  & + e* function_parameters(7,j) ) ) ) ) ) &
490  & /( 1.0_r8 &
491  & + e*(function_parameters(8,j) &
492  & + e*(function_parameters(9,j) &
493  & + e*(function_parameters(10,j) &
494  & + e*(function_parameters(11,j) &
495  & + e* function_parameters(12,j) ) ) ) ) )
496  ! We clamp the energy for S (the nuclear fusion probability).
497  ! However, there is no need to clamp the energy in denominator.
498  ! The denominator roughly describes the probability of the reactants to
499  ! overcome the Coulomb barrier.
500  e = x(i) * 1.0e-3_r8
501  f(i) = s / (e * exp(function_parameters(1,j)/sqrt(e))) * 1.0e-31_r8
502  enddo
503  end subroutine nuclear_data_1006
504 
505 end module amns_external_functions
subroutine reflect_data_1005(function_parameters, energy_arr, angle_arr, refl_arr, with_warnings, fun_err)
AMNS External function ...
subroutine nuclear_data_1001(function_parameters, x, f, with_warnings, fun_err)
AMNS External function ...
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
real(r8) function reyield(E0, M1, M2, Z1, Z2, A1, A2, A3, A4)
AMNS External utility function ...
subroutine rct_data_1003(function_parameters, Tin, f, with_warnings, fun_err)
AMNS External function ...
real(r8) function sayield(E0, theta, f, b, c, Esp)
AMNS External utility function ...
subroutine nuclear_data_1006(function_parameters, x, f, with_warnings, fun_err)
real(r8) function seyield(E0, M1, M2, Z1, Z2, q, lambda, u, ETh)
AMNS External utility function ...
real(r8) function rayield(angledeg, C1, C2, C3, C4)
AMNS External utility function ...