ESPUTR
calculation of sputtering yields
esputr1993.f90
Go to the documentation of this file.
1 
5 
6 ! Copyright (c) 2016 Forschungszentrum Juelich GmbH
7 ! Markus Brenneis, Vladislav Kotov
8 !
9 ! This file is part of ESPUTR.
10 !
11 ! ESPUTR is free software: you can redistribute it and/or modify
12 ! it under the terms of the GNU General Public License as published by
13 ! the Free Software Foundation, either version 3 of the License, or
14 ! (at your option) any later version.
15 !
16 ! ESPUTR is distributed in the hope that it will be useful,
17 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ! GNU General Public License for more details.
20 !
21 ! You should have received a copy of the GNU General Public License
22 ! along with ESPUTR. If not, see <http://www.gnu.org/licenses/>.
23 !
24 module esputr1993
25 
26 !***********************************************************************************
27 ! DEFINITION OF PARAMETRS AND GLOBAL VARIABLES
28 !***********************************************************************************
29  use esputr
30  implicit none
36  integer, parameter, public :: esputr1993_first_col_width = 11
37  private
41  integer, save, private :: nheaderlines
43  integer, parameter, private :: col_width = 9
45  integer, parameter, private :: lines_per_target = 6
47  integer, parameter, private :: nconstants = 3
49  integer,save, private :: ntargets
51  integer,save, private :: nprojectiles
62  real(ESPUTR_DP), dimension(:,:,:), allocatable, save, private :: fitvalues
66  character(ESPUTR1993_FIRST_COL_WIDTH), dimension(:), allocatable, save, private :: targets_names
70  character(ESPUTR1993_FIRST_COL_WIDTH), dimension(:), allocatable, save, private :: projectiles_names
71 
72  contains
73 
74 !***********************************************************************************
75 ! INITIALIZATION/DEINITIALIZATION ROUTINES
76 !***********************************************************************************
81  subroutine esputr1993_init(constantsFile, err)
82 
83  character(*), intent(in) :: constantsFile
85  integer, intent(out) :: err
86  integer, parameter :: UNIT = 3
87  integer :: i, j, Nlines, res
88  character(ESPUTR_MAX_LINE_LENGTH) :: line
89  !lineCols(NPROJECTILES + 1) : data on all projectiles for a target
90  character(ESPUTR1993_FIRST_COL_WIDTH), dimension(:), allocatable :: lineCols
91  intrinsic trim
92 
93  if(allocated(fitvalues)) then
94  write(esputr_unit, *) "ERROR in esputr1993_init: esputr1993_init has already been called; &
95  &call esputr1993_deallocate first"
96  err = 100
97  return
98  end if
99 
100  err = 0
101 
102  nheaderlines = linesuntil(constantsfile, '===', err)
103  if(err /= 0) then
104  write(esputr_unit, *) "ERROR in esputr1993_init: error while determining header lines of " // trim(constantsfile)
105  err = 300
106  return
107  end if
108 
109  ! minus the two lines for the projectiles
110  nlines=numberoflines(constantsfile, err=err)-nheaderlines-2
111  if(err /= 0) then
112  write(esputr_unit, *) "ERROR in esputr1993_init: error while determining number of lines in "&
113  // trim(constantsfile), err
114  err = 300
115  return
116  end if
117  !VK to produce error if lines are missing for the last target
118  ntargets = nlines/lines_per_target
119  if (ntargets*lines_per_target<nlines) ntargets=ntargets+1 !VK
120  if(ntargets<1) then
121  write(esputr_unit, *) "ERROR in esputr1993_init: file ",trim(constantsfile)," contains no data"
122  err = 300
123  return
124  end if
125 
126  open(unit, iostat=err, file=trim(constantsfile), status='old', action='read')
127 
128  ifioerr: if(err /= 0) then
129  write(esputr_unit, *) "ERROR in esputr1993_init: cannot open file " // trim(constantsfile)
130  err = 300
131  close(unit)
132  return
133  else
134  skipheader: do i = 1, nheaderlines
135  read(unit, '(A)', iostat=err) line
136  if(err /= 0) then
137  write(esputr_unit, *) "ERROR in esputr1993_init while reading the comment (first lines) in " &
138  // trim(constantsfile)
139  err = 300
140  close(unit)
141  return
142  end if
143  end do skipheader
144 
145  ! read line with names of projectiles and allocate memory for arrays
146  read(unit, '(A)', iostat=err) line
147  if(err /= 0) goto 1100
148  ! ceiling because of missing spaces at end of line
149  nprojectiles = ceiling((len_trim(line)-esputr1993_first_col_width+1.)/col_width)
150  if(nprojectiles<1) then
151  write(esputr_unit, *) "ERROR in esputr1993_init: "//trim(constantsfile)//" contains no data"
152  err = 300
153  close(unit)
154  return
155  end if
156  allocate(targets_names(ntargets), stat=err)
157  if(err /= 0) goto 1200
158  allocate(projectiles_names(nprojectiles), stat=err)
159  if(err /= 0) goto 1200
160  allocate(fitvalues(nconstants, ntargets, nprojectiles), stat=err)
161  if(err /= 0) goto 1200
162  allocate(linecols(nprojectiles + 1), stat=err)
163  if(err /= 0) goto 1200
164  backspace(unit, iostat=err)
165  if(err /= 0) goto 1300
166  read(unit, *, iostat=err) linecols
167  if(err /= 0) goto 1100
168  projectiles_names(:) = linecols(2:)
169 
170  read(unit, *, iostat=err) linecols(:)
171  if(err /= 0) goto 1100
172 ! line with AZ of projectiles is skiped
173 ! read(lineCols(2:), *, err=1300) SPUTER1993_PROJECTILES_MASSES
174 
175  foreachtarget: do i = 1, ntargets
176  ! read name !and mass
177  read(unit, *, iostat=err) linecols(1:2)
178  if(err /= 0) goto 1300
179  read(linecols(1:1), *, iostat=err) targets_names(i) !, SPUTER1993_TARGETS_MASSES(i)
180  if(err /= 0) goto 1300
181 
182  ! skip Es
183  read(unit, *, iostat=err) line
184  if(err /= 0) goto 1300
185 
186  ! skip M2/M1
187  read(unit, *, iostat=err) line
188  if(err /= 0) goto 1300
189 
190  ! read E_tf
191  read(unit, *, iostat=err) linecols
192  if(err /= 0) goto 1300
193  read(linecols(2:nprojectiles + 1), *, iostat=err) fitvalues(1,i,:)
194  if(err /= 0) goto 1300
195 
196  ! read E_th
197  read(unit, *, iostat=err) linecols
198  if(err /= 0) goto 1300
199  read(linecols(2:nprojectiles + 1), *, iostat=err) fitvalues(2,i,:)
200  if(err /= 0) goto 1300
201 
202  ! read Q
203  read(unit, *, iostat=err) linecols
204  if(err /= 0) goto 1300
205  read(linecols(2:nprojectiles + 1), *, iostat=err) fitvalues(3,i,:)
206  if(err /= 0) goto 1300
207 
208  do j = 1, nprojectiles
209  if(err /= 0) then
210  write(esputr_unit, *) "ERROR in esputr1993_init: fitvalues are not sensible: ",&
211  "nr ", i, ", value ", fitvalues(err,i,j)
212  close(unit)
213  return
214  end if
215  end do
216  end do foreachtarget
217 
218  close(unit)
219  deallocate(linecols, stat=err)
220  if(err /= 0) then
221  write(esputr_unit, *) "WARNING from esputr1993_init: problem while deallocating memory"
222  err = -200
223  end if
224 
225  call esputr1993_check(res, err)
226  if(res /=0 .or. err /=0) then
227  err=400
228  write(esputr_unit, *) "ERROR in esputr1993_init: the data are incorrect"
229  return
230  end if
231 
232  write(esputr_unit, *) "esputr1993_init: initialization from file "//trim(constantsfile)//" completed"
233  write(esputr_unit, *) " Number of projectiles = ",nprojectiles, &
234  ", Number of targets = ",ntargets
235  return
236 
237 1100 write(esputr_unit, *) "ERROR in esputr1993_init while reading the table header in " &
238  // trim(constantsfile)
239  err = 300
240  close(unit)
241  return
242 1200 write(esputr_unit, *) "ERROR in esputr1993_init: could not allocate memory for ", ntargets,&
243  " targets and ", nprojectiles, " projectiles with ", &
244  nconstants, " parameters for each combination"
245  err = 200
246  close(unit)
247  return
248 1300 write(esputr_unit, *) "ERROR in esputr1993_init while reading " // trim(constantsfile) &
249  // " for target number ",i," (NAME = ",trim(targets_names(i)),")"
250  err = 300
251  close(unit)
252  return
253  end if ifioerr
254 
255  end subroutine esputr1993_init
256 
258  logical function esputr1993_if_initialized()
260  end function esputr1993_if_initialized
261 
263  subroutine esputr1993_check(res, err)
272  integer, intent(out) :: res
274  integer, intent(out) :: err
275 
276  integer :: itarg,iproj, n1,n2,m1,m2
277  real(ESPUTR_DP) :: E_tf, E_th, Q
278  intrinsic size
279 
280  err=0
281  res=0
282  if( (.not.allocated(fitvalues)) .or. (.not.allocated(targets_names)) &
283  .or. (.not.allocated(projectiles_names)) ) then
284  write(esputr_unit, *) "ERROR detected in esputr1993_check: some or all arrays are not allocated"
285  res=1
286  return
287  end if
288 
289  n1=size(fitvalues,2)
290  n2=size(fitvalues,3)
291  m1=size(targets_names,1)
292  m2=size(projectiles_names,1)
293  if( ntargets /= n1 .or. nprojectiles /= n2 .or. &
294  ntargets /= m1 .or. nprojectiles /= m2 ) then
295  write(esputr_unit, *) "ERROR detected in esputr1993_check: inconsistent array size"
296  write(esputr_unit, *) " NPROJECTILES , size(FITVALUES,1), size(TARGETS_NAMES,1) ",nprojectiles,n1,m1
297  write(esputr_unit, *) " NTARGETS , size(FITVALUES,2), size(PROJECTILES_NAMES,1) ",ntargets,n2,m2
298  res=2
299  return
300  end if
301 
302  do iproj=1,nprojectiles
303  do itarg=1,ntargets
304  e_tf=fitvalues(1,itarg,iproj)
305  e_th=fitvalues(2,itarg,iproj)
306  q=fitvalues(3,itarg,iproj)
307  if(e_tf <= 0) then
308  res = 2
309  write(esputr_unit, *) "ERROR detected in esputr1993_check: wrong E_tf"
310  write(esputr_unit, *) " itarg, iproj ",itarg,iproj
311  return
312  else if(e_th <= 0) then
313  res = 3
314  write(esputr_unit, *) "ERROR detected in esputr1993_check: wrong E_th"
315  write(esputr_unit, *) " itarg, iproj ",itarg,iproj
316  return
317  else if(q <= 0) then
318  res = 4
319  write(esputr_unit, *) "ERROR detected in esputr1993_check: wrong Q"
320  write(esputr_unit, *) " itarg, iproj ",itarg,iproj
321  return
322  end if
323  end do
324  end do
325  end subroutine esputr1993_check
326 
328  subroutine esputr1993_deallocate(err)
330  integer, intent(out) :: err
331  integer, dimension(3) :: errs
332  err = 0
333  errs = 0
334  if(allocated(fitvalues)) deallocate(fitvalues, stat=errs(1))
335  if(allocated(targets_names)) deallocate(targets_names, stat=errs(2))
336  if(allocated(projectiles_names)) deallocate(projectiles_names, stat=errs(3))
337  if(.not. all(errs==0)) then
338  write(esputr_unit, *) "WARNING from esputr1993_deallocate: problem while deallocating memory"
339  err = -200
340  end if
341  return
342  end subroutine esputr1993_deallocate
343 
344 !***********************************************************************************
345 ! GET INDEX
346 !***********************************************************************************
347 
351  integer function esputr1993_getprojectileid(proj, err)
353  character(*), intent(in) :: proj
357  integer, intent(out) :: err
358  intrinsic trim
359  err = 0
360 
361  if(.not. allocated(projectiles_names)) then
362  write(esputr_unit, *) "ERROR in esputr1993_getProjectileId: arrays are not initialized"
363  write(esputr_unit, *) " Call esputr1993_init first!"
365  err = 50
366  return
367  end if
368 
370 
371  if(esputr1993_getprojectileid <= 0) then
372  write(esputr_unit, *) "ERROR in esputr1993_getProjectileId: projectile "//trim(proj)//" not found"
373  err = 101
374  end if
375  end function esputr1993_getprojectileid
376 
377 
381  integer function esputr1993_gettargetid(targ, err)
383  character(*), intent(in) :: targ
387  integer, intent(out) :: err
388  intrinsic trim
389  err = 0
390 
391  if(.not. allocated(targets_names)) then
392  write(esputr_unit, *) "ERROR in esputr1993_getTargetId: arrays are not initialized"
393  write(esputr_unit, *) " Call esputr1993_init first!"
395  err = 50
396  return
397  end if
398 
399  esputr1993_gettargetid = getindexof(targ, targets_names)
400 
401  if(esputr1993_gettargetid <=0) then
402  write(esputr_unit, *) "ERROR in esputr1993_getTargetId: target "//trim(targ)//" not found"
403  err = 102
404  end if
405  end function esputr1993_gettargetid
406 
407 !***********************************************************************************
408 ! CALCULATION OF SPUTTERING YIELDS
409 !***********************************************************************************
416  real(ESPUTR_DP) function esputr1993_yn(E0, proj_id, targ_id, err)
418  real(ESPUTR_DP), intent(in) :: E0
420  integer, intent(in) :: proj_id
422  integer, intent(in) :: targ_id
424  integer, intent(out) :: err
425 
426  real(ESPUTR_DP) :: Q, E_th, E_tf, EthOverE0, s_n_KrC, eps
427 
428  err = 0
429 
430  if(.not. allocated(fitvalues)) then
431  write(esputr_unit,*) "ERROR in esputr1993_yn: arrays are not initialized"
432  write(esputr_unit,*) " Call esputr1993_init first"
433  esputr1993_yn = -1
434  err = 50
435  return
436  end if
437  if(targ_id < 1 .or. targ_id > ntargets .or.&
438  proj_id < 1 .or. proj_id > nprojectiles) then
439  write(esputr_unit, *) "ERROR in esputr1993_yn: targ_id or proj_id out of bounds", targ_id, proj_id
440  esputr1993_yn = -1.
441  err = 100
442  return
443  end if
444 
445  e_th = fitvalues(2, targ_id, proj_id)
446 
447  if(e0 > e_th) then
448  e_tf = fitvalues(1, targ_id, proj_id)
449  q = fitvalues(3, targ_id, proj_id)
450  eps = e0/e_tf
451  ethovere0 = e_th / e0
452  s_n_krc = .5 * log(1 + 1.2288*eps) / (eps + .1728*sqrt(eps) + .008*eps**0.1504)
453  esputr1993_yn = q * s_n_krc * (1 - ethovere0**(2./3.)) * (1 - ethovere0)**2
454  else
455  esputr1993_yn = 0.
456  end if
457 
458  end function esputr1993_yn
459 
467  real(ESPUTR_DP) function esputr1993_yth(theta, err)
471  real(ESPUTR_DP), intent(in) :: theta
473  integer, intent(out) :: err
474 
475  real(ESPUTR_DP) :: cosTheta
476  real(ESPUTR_DP), parameter :: f = 2., cos_th_opt= cos(75.*esputr_pi/180.) ! th_opt = 75.
477  ! Y_th(th_opt) = 3.3902
478 
479  err = 0
480 
481  if(theta < 0 .or. theta > esputr_pi2) then
482  write(esputr_unit, *) "ERROR detected in esputr1993_yth: incorrect incident angle theta (radian) ", theta
483  write(esputr_unit, *) " Incident angle cannot be < 0 or > pi/2"
484  err = 103
485  esputr1993_yth = -1
486  return
487  end if
488 
489  costheta = cos(theta)
490 
491  if(costheta > 0) then
492  esputr1993_yth = costheta**(-f) * exp(f * (1-1./costheta) * cos_th_opt)
493  else
494  esputr1993_yth = 0
495  end if
496  end function esputr1993_yth
497 
498 
499 !***********************************************************************************
500 ! AUXILIARY FUNCTIONS
501 !***********************************************************************************
502 
504  real(ESPUTR_DP) function esputr1993_eth(proj_id, targ_id, err)
506  integer, intent(in) :: proj_id
508  integer, intent(in) :: targ_id
510  integer, intent(out) :: err
511 
512  if(.not. allocated(fitvalues)) then
513  esputr1993_eth = -1
514  write(esputr_unit, *) "ERROR in esputr1993_Eth: arrays are not initialized"
515  write(esputr_unit, *) " Call esputr1993 first!"
516  err = 50
517  end if
518 
519  if(targ_id < 1 .or. targ_id > ntargets .or.&
520  proj_id < 1 .or. proj_id > nprojectiles) then
521  write(esputr_unit, *) "ERROR in esputr1993_Eth: targ_id or proj_id out of bounds", targ_id, proj_id
522  esputr1993_eth = -1.
523  err = 100
524  return
525  end if
526 
527  esputr1993_eth = fitvalues(2, targ_id, proj_id)
528  end function esputr1993_eth
529 
531  subroutine esputr1993_availablecombinations(combinations, err)
533  character(ESPUTR1993_FIRST_COL_WIDTH), dimension(:,:), allocatable, intent(inout) :: combinations
534  integer, intent(out) :: err
535  integer :: t, p, i
536 
537  err = 0
538 
539  if(.not.allocated(projectiles_names) .or. .not.allocated(targets_names)) then
540  err = 50
541  write(esputr_unit, *) "ERROR in esputr1993_availableCombinations: arrays are not initialized"
542  write(esputr_unit, *) " Call esputr1993_init first!"
543  return
544  end if
545 
546  allocate(combinations(ntargets * nprojectiles, 2), stat = err)
547  if(err /= 0) then
548  write(esputr_unit, *) "ERROR in esputr1993_availableCombinations: error while allocating memory", err
549  err = 200
550  return
551  end if
552  do t = 1, ntargets
553  do p = 1, nprojectiles
554  i = (t-1)*nprojectiles + p
555  combinations(i, 1) = projectiles_names(p)
556  combinations(i, 2) = targets_names(t)
557  end do
558  end do
559  end subroutine esputr1993_availablecombinations
560 
563  integer function linesuntil(filePath, string, err)
564 
565  character(*), intent(in) :: filePath
567  character(*), intent(in) :: string
569  integer, intent(out) :: err
570  character(len(string)) :: line
571  integer, parameter :: UNIT = 50
572  intrinsic index,trim
573  err = 0
574  linesuntil = 0
575 
576  open(unit, iostat=err, file=trim(filepath), status='old', action='read')
577  if(err /= 0) then
578  write(esputr_unit, *), "ERROR in linesUntil: while opening file", trim(filepath)
579  close(unit)
580  err = 300
581  return
582  end if
583 
584  do
585  read(unit, *, iostat=err, end=9100) line
586  if(err /= 0) then
587  write(esputr_unit, *), "ERROR in linesUntil: while reading file", trim(filepath)
588  close(unit)
589  err = 300
590  return
591  end if
592  linesuntil = linesuntil + 1
593  if(len_trim(line)>0) then
594  if(index(line,string)>0) then
595  close(unit)
596  return
597  end if
598  end if
599  end do
600 9100 linesuntil = 0
601  close(unit)
602  end function linesuntil
603 
606  pure integer function getindexof(subj, list)
607 
608  character(*), intent(in) :: subj
610  character(*), dimension(:), intent(in) :: list
611  integer :: i
612  intrinsic size
613  getindexof = 0
614  do i = 1, size(list, 1)
615  if(list(i) == subj) then
616  getindexof = i
617  exit
618  end if
619  end do
620  end function getindexof
621 
622 end module esputr1993
real(esputr_dp) function, public esputr1993_yn(E0, proj_id, targ_id, err)
Calculate sputtering yield for normal incidence with 1993-model for a given incident energy and targe...
Definition: esputr1993.f90:417
integer function, public numberoflines(fileName, ignoreComments, err)
Return number of lines in the file, without blank lines and comment lines (started with #) ...
Definition: esputr.f90:95
integer function, public esputr1993_getprojectileid(proj, err)
Return ID of the projectile for the 1993-model.
Definition: esputr1993.f90:352
subroutine, public esputr1993_deallocate(err)
Deallocate dynamic arrays used by the module ESPUTR1993.
Definition: esputr1993.f90:329
integer, save, private nprojectiles
Number of loaded projectiles.
Definition: esputr1993.f90:51
subroutine, public esputr1993_check(res, err)
Check integrity and validity of data in the module.
Definition: esputr1993.f90:264
subroutine, public esputr1993_init(constantsFile, err)
Initialization of the 1993-model.
Definition: esputr1993.f90:82
real(esputr_dp), dimension(:,:,:), allocatable, save, private fitvalues
Array with parameters of fitting formula for normal incidence for 1993-model.
Definition: esputr1993.f90:62
real(esputr_dp), parameter, public esputr_pi
Pi number.
Definition: esputr.f90:79
real(esputr_dp), parameter, public esputr_pi2
Pi divided by 2.
Definition: esputr.f90:81
integer, save, private ntargets
Number of loaded targets.
Definition: esputr1993.f90:49
integer function, public esputr1993_gettargetid(targ, err)
Return ID of the target for the 1993-model.
Definition: esputr1993.f90:382
character(esputr1993_first_col_width), dimension(:), allocatable, save, private targets_names
Array of strings with the names of targets.
Definition: esputr1993.f90:66
real(esputr_dp) function, public esputr1993_yth(theta, err)
Angular dependence of sputtering yield in 1993-model for given incident angle.
Definition: esputr1993.f90:468
character(esputr1993_first_col_width), dimension(:), allocatable, save, private projectiles_names
Array of strings with the names of projectiles.
Definition: esputr1993.f90:70
subroutine, public esputr1993_availablecombinations(combinations, err)
Return the list of available projectile-target combinations.
Definition: esputr1993.f90:532
integer, parameter, private nconstants
Number of parameters read from the input file for one target/projectile combination.
Definition: esputr1993.f90:47
integer, parameter, private lines_per_target
Number of lines for each target in in the input file (excluding blank lines)
Definition: esputr1993.f90:45
integer, parameter, private col_width
Width of the columns in the input file.
Definition: esputr1993.f90:43
logical function, public esputr1993_if_initialized()
Return .true. if module esputr1993 is initialized.
Definition: esputr1993.f90:259
integer, save, private nheaderlines
Number of comment lines in the beginning of the input file All lines including the first line which s...
Definition: esputr1993.f90:41
integer, save, public esputr_unit
Index of the unit for standard output, default value 6.
Definition: esputr.f90:73
real(esputr_dp) function, public esputr1993_eth(proj_id, targ_id, err)
Return threshold energy for the given projectile-target combination.
Definition: esputr1993.f90:505
integer, parameter, public esputr1993_first_col_width
Width of the first column in the input file.
Definition: esputr1993.f90:36