ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/calc_eam.F90
Revision: 492
Committed: Mon Apr 14 18:19:15 2003 UTC (21 years, 2 months ago) by chuckv
File size: 17049 byte(s)
Log Message:
Added first mangling of EAM.

File Contents

# User Rev Content
1 chuckv 492 module calc_eam
2     use definitions, ONLY : DP
3     use force_globals
4     #ifdef MPI
5     use mpiSimulation
6     #endif
7    
8    
9    
10    
11     !! standard eam stuff
12     integer :: n_eam_atypes
13     integer, allocatable, dimension(:) :: eam_atype
14     real( kind = DP ), allocatable, dimension(:) :: eam_dr
15     integer, allocatable, dimension(:) :: eam_nr
16     integer, allocatable, dimension(:) :: eam_nrho
17     real( kind = DP ), allocatable, dimension(:) :: eam_lattice
18     real( kind = DP ), allocatable, dimension(:) :: eam_drho
19     integer , allocatable, dimension(:) :: eam_atype_map
20     real( kind = DP ), allocatable, dimension(:,:) :: eam_rvals
21     real( kind = DP ), allocatable, dimension(:,:) :: eam_rhovals
22     real( kind = DP ), allocatable, dimension(:) :: eam_rcut
23     real( kind = DP ), allocatable, dimension(:,:) :: eam_F_rho
24     real( kind = DP ), allocatable, dimension(:,:) :: eam_Z_r
25     real( kind = DP ), allocatable, dimension(:,:) :: eam_rho_r
26     real( kind = DP ), allocatable, dimension(:,:) :: eam_phi_r
27     real( kind = DP ), allocatable, dimension(:,:) :: eam_F_rho_pp
28     real( kind = DP ), allocatable, dimension(:,:) :: eam_Z_r_pp
29     real( kind = DP ), allocatable, dimension(:,:) :: eam_rho_r_pp
30     real( kind = DP ), allocatable, dimension(:,:) :: eam_phi_r_pp
31    
32    
33     real( kind = DP ), private :: time0,time1,time2,time3
34    
35     integer, private :: eam_err
36    
37     private :: mass_weight
38     private :: allocate_eam_atype,allocate_eam_module,deallocate_eam_module
39     private :: read_eam_pot, get_eam_sizes
40    
41    
42     contains
43     subroutine initialize_eam()
44    
45    
46    
47     character(len=80) :: eam_pot_file
48     integer :: i, j, max_size, prev_max_size
49     integer :: number_rho, number_r
50     integer :: eam_unit
51     integer :: this_error
52     character(len=300) :: msg
53     integer, external :: nfiles
54     !for mpi
55    
56    
57     #ifdef MPI
58     if (node == 0) &
59     n_eam_atypes = nfiles(trim(eam_pot_dir)//char(0))
60    
61     call mpi_bcast(n_eam_atypes,1,mpi_integer,0,mpi_comm_world,mpi_err)
62     if (n_eam_atypes == -1) then
63     call error("INITIALIZE_EAM","NO EAM potentials found!")
64     endif
65     write(msg,'(a5,i4,a12,i5,a14)') 'Node: ',node,' reading ...', &
66     n_eam_atypes, ' eam atom types'
67     call info('INITIALIZE_EAM', trim(msg))
68     #else
69     n_eam_atypes = nfiles(trim(eam_pot_dir)//char(0))
70     if (n_eam_atypes == -1) then
71     call error("INITIALIZE_EAM","NO EAM potentials found!")
72     endif
73    
74     write(msg,'(a12,i5,a14)') ' Reading ...', &
75     n_eam_atypes, ' eam atom types'
76     call info('INITIALIZE_EAM', trim(msg))
77     #endif
78    
79    
80     call allocate_eam_atype(n_eam_atypes)
81    
82    
83    
84     !! get largest number of data points for any potential
85     #ifdef MPI
86     if (node == 0) then
87     #endif
88     prev_max_size = 0
89     do i = 1, n_eam_atypes
90     call getfilename(i, eam_pot_file)
91     max_size = max(get_eam_sizes( &
92     trim(eam_pot_dir) // '/' // eam_pot_file), &
93     prev_max_size)
94     prev_max_size = max_size
95     end do
96     #ifdef MPI
97     end if
98    
99    
100     call mpi_bcast(max_size,1,mpi_integer,0,mpi_comm_world,mpi_err)
101     #endif
102    
103     call allocate_eam_module(n_eam_atypes,max_size)
104     allocate(eam_atype_map(get_max_atype()))
105    
106     #ifdef MPI
107     if (node == 0) then
108     #endif
109     do i = 1, n_eam_atypes
110     call getfilename(i, eam_pot_file)
111     call read_eam_pot(i,trim(eam_pot_dir) // '/' // eam_pot_file, &
112     this_error)
113    
114     do j = 1, eam_nr(i)
115     eam_rvals(j,i) = dble(j-1)*eam_dr(i)
116     enddo
117    
118     do j = 1, eam_nrho(i)
119     eam_rhovals(j,i) = dble(j-1)*eam_drho(i)
120     enddo
121    
122     ! convert from eV to kcal / mol:
123     do j = 1, eam_nrho(i)
124     eam_F_rho(j,i) = eam_F_rho(j,i)*23.06054E0_DP
125     enddo
126    
127     ! precompute the pair potential and get it into kcal / mol:
128     eam_phi_r(1,i) = 0.0E0_DP
129     do j = 2, eam_nr(i)
130     eam_phi_r(j,i) = (eam_Z_r(j,i)**2)/eam_rvals(j,i)
131     eam_phi_r(j,i) = eam_phi_r(j,i)*331.999296E0_DP
132     enddo
133    
134     end do
135     #ifdef MPI
136     call info('INITIALIZE_EAM','NODE 0: Distributing spline arrays')
137     endif
138    
139     call mpi_bcast(this_error,n_eam_atypes,mpi_integer,0, &
140     mpi_comm_world,mpi_err)
141     if (this_error /= 0) then
142     call error('INITIALIZE_EAM',"Cannot read eam files")
143     endif
144    
145     call mpi_bcast(eam_atype,n_eam_atypes,mpi_integer,0, &
146     mpi_comm_world,mpi_err)
147    
148     !! distribute values to cluster......
149     call mpi_bcast(eam_nr,n_eam_atypes,mpi_integer,&
150     0,mpi_comm_world,mpi_err)
151     call mpi_bcast(eam_nrho,n_eam_atypes,mpi_integer,&
152     0,mpi_comm_world,mpi_err)
153     call mpi_bcast(eam_rvals,n_eam_atypes*max_size,mpi_double_precision, &
154     0,mpi_comm_world,mpi_err)
155     call mpi_bcast(eam_rcut,n_eam_atypes,mpi_double_precision, &
156     0,mpi_comm_world,mpi_err)
157     call mpi_bcast(eam_rhovals,n_eam_atypes*max_size,mpi_double_precision, &
158     0,mpi_comm_world,mpi_err)
159    
160     !! distribute arrays
161     call mpi_bcast(eam_rho_r,n_eam_atypes*max_size,mpi_double_precision, &
162     0,mpi_comm_world,mpi_err)
163     call mpi_bcast(eam_Z_r,n_eam_atypes*max_size,mpi_double_precision, &
164     0,mpi_comm_world,mpi_err)
165     call mpi_bcast(eam_F_rho,n_eam_atypes*max_size,mpi_double_precision, &
166     0,mpi_comm_world,mpi_err)
167     call mpi_bcast(eam_phi_r,n_eam_atypes*max_size,mpi_double_precision, &
168     0,mpi_comm_world,mpi_err)
169    
170     #endif
171     call info('INITIALIZE_EAM', 'creating splines')
172    
173     do i = 1, n_eam_atypes
174     number_r = eam_nr(i)
175     number_rho = eam_nrho(i)
176    
177     call eam_spline(i, number_r, eam_rvals, eam_rho_r, eam_rho_r_pp, &
178     0.0E0_DP, 0.0E0_DP, 'N')
179     call eam_spline(i, number_r, eam_rvals, eam_Z_r, eam_Z_r_pp, &
180     0.0E0_DP, 0.0E0_DP, 'N')
181     call eam_spline(i, number_rho, eam_rhovals, eam_F_rho, eam_F_rho_pp, &
182     0.0E0_DP, 0.0E0_DP, 'N')
183     call eam_spline(i, number_r, eam_rvals, eam_phi_r, eam_phi_r_pp, &
184     0.0E0_DP, 0.0E0_DP, 'N')
185     enddo
186    
187     do i = 1, n_eam_atypes
188     eam_atype_map(eam_atype(i)) = i
189     end do
190    
191    
192    
193     call info('INITIALIZE_EAM','Done creating splines')
194    
195     return
196     end subroutine initialize_eam
197    
198    
199     subroutine allocate_eam_atype(n_size_atype)
200     integer, intent(in) :: n_size_atype
201    
202     allocate(eam_atype(n_size_atype))
203     allocate(eam_drho(n_size_atype))
204     allocate(eam_dr(n_size_atype))
205     allocate(eam_nr(n_size_atype))
206     allocate(eam_nrho(n_size_atype))
207     allocate(eam_lattice(n_size_atype))
208     allocate(eam_rcut(n_size_atype))
209    
210     end subroutine allocate_eam_atype
211    
212     subroutine allocate_eam_module(n_size_atype,n_eam_points)
213     integer, intent(in) :: n_eam_points
214     integer, intent(in) :: n_size_atype
215    
216     allocate(eam_rvals(n_eam_points,n_size_atype))
217     allocate(eam_rhovals(n_eam_points,n_size_atype))
218     allocate(eam_F_rho(n_eam_points,n_size_atype))
219     allocate(eam_Z_r(n_eam_points,n_size_atype))
220     allocate(eam_rho_r(n_eam_points,n_size_atype))
221     allocate(eam_phi_r(n_eam_points,n_size_atype))
222     allocate(eam_F_rho_pp(n_eam_points,n_size_atype))
223     allocate(eam_Z_r_pp(n_eam_points,n_size_atype))
224     allocate(eam_rho_r_pp(n_eam_points,n_size_atype))
225     allocate(eam_phi_r_pp(n_eam_points,n_size_atype))
226    
227     end subroutine allocate_eam_module
228    
229     subroutine deallocate_eam_module()
230    
231     deallocate(eam_atype)
232     deallocate(eam_drho)
233     deallocate(eam_dr)
234     deallocate(eam_nr)
235     deallocate(eam_nrho)
236     deallocate(eam_lattice)
237     deallocate(eam_atype_map)
238     deallocate(eam_rvals)
239     deallocate(eam_rhovals)
240     deallocate(eam_rcut)
241     deallocate(eam_Z_r)
242     deallocate(eam_rho_r)
243     deallocate(eam_phi_r)
244     deallocate(eam_F_rho_pp)
245     deallocate(eam_Z_r_pp)
246     deallocate(eam_rho_r_pp)
247     deallocate(eam_phi_r_pp)
248    
249     end subroutine deallocate_eam_module
250    
251    
252     subroutine calc_eam_pair(atom1,atom2,d,rij,r2,pot,f,do_pot,do_stress)
253     !Arguments
254     integer, intent(in) :: atom1, atom2
255     real( kind = dp ), intent(in) :: rij, r2
256     real( kind = dp ) :: pot
257     real( kind = dp ), dimension(3,getNlocal()) :: f
258     real( kind = dp ), intent(in), dimension(3) :: d
259     logical, intent(in) :: do_pot, do_stress
260    
261     !Local Variables
262    
263    
264     if (rij .lt. EAM_rcut) then
265    
266     r = dsqrt(rijsq)
267     efr(1,j) = -rxij
268     efr(2,j) = -ryij
269     efr(3,j) = -rzij
270    
271    
272     call calc_eam_rho(r, rha, drha, d2rha, atype1)
273     call calc_eam_phi(r, pha, dpha, d2pha, atype1)
274     rci = eam_rcut(eam_atype_map(atype1))
275     #ifdef MPI
276     atype2 = ident_col(j)
277     #else
278     atype2 = ident(j)
279     #endif
280    
281     call calc_eam_rho(r, rhb, drhb, d2rhb, atype2)
282     call calc_eam_phi(r, phb, dphb, d2phb, atype2)
283     rcj = eam_rcut(eam_atype_map(atype2))
284    
285     phab = 0.0E0_DP
286     dvpdr = 0.0E0_DP
287     d2vpdrdr = 0.0E0_DP
288    
289     if (r.lt.rci) then
290     phab = phab + 0.5E0_DP*(rhb/rha)*pha
291     dvpdr = dvpdr + 0.5E0_DP*((rhb/rha)*dpha + &
292     pha*((drhb/rha) - (rhb*drha/rha/rha)))
293     d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rhb/rha)*d2pha + &
294     2.0E0_DP*dpha*((drhb/rha) - (rhb*drha/rha/rha)) + &
295     pha*((d2rhb/rha) - 2.0E0_DP*(drhb*drha/rha/rha) + &
296     (2.0E0_DP*rhb*drha*drha/rha/rha/rha) - (rhb*d2rha/rha/rha)))
297     endif
298    
299    
300     if (r.lt.rcj) then
301     phab = phab + 0.5E0_DP*(rha/rhb)*phb
302     dvpdr = dvpdr + 0.5E0_DP*((rha/rhb)*dphb + &
303     phb*((drha/rhb) - (rha*drhb/rhb/rhb)))
304     d2vpdrdr = d2vpdrdr + 0.5E0_DP*((rha/rhb)*d2phb + &
305     2.0E0_DP*dphb*((drha/rhb) - (rha*drhb/rhb/rhb)) + &
306     phb*((d2rha/rhb) - 2.0E0_DP*(drha*drhb/rhb/rhb) + &
307     (2.0E0_DP*rha*drhb*drhb/rhb/rhb/rhb) - (rha*d2rhb/rhb/rhb)))
308     endif
309    
310    
311     #ifdef MPI
312    
313     e_row(i) = e_row(i) + phab*0.5
314     e_col(i) = e_col(i) + phab*0.5
315     #else
316     if (do_pot) pot = pot + phab
317     #endif
318    
319     drhoidr = drha
320     drhojdr = drhb
321    
322     d2rhoidrdr = d2rha
323     d2rhojdrdr = d2rhb
324     #ifdef MPI
325     dudr = drhojdr*dfrhodrho_row(i)+drhoidr*dfrhodrho_col(j) &
326     + dvpdr
327    
328     if (nmflag) then
329     d2 = d2vpdrdr + &
330     d2rhoidrdr*dfrhodrho_col(j) + &
331     d2rhojdrdr*dfrhodrho_row(i) + &
332     drhoidr*drhoidr*d2frhodrhodrho_col(j) + &
333     drhojdr*drhojdr*d2frhodrhodrho_row(i)
334     endif
335     #else
336     dudr = drhojdr*dfrhodrho(i)+drhoidr*dfrhodrho(j) &
337     + dvpdr
338    
339     d2 = d2vpdrdr + &
340     d2rhoidrdr*dfrhodrho(j) + &
341     d2rhojdrdr*dfrhodrho(i) + &
342     drhoidr*drhoidr*d2frhodrhodrho(j) + &
343     drhojdr*drhojdr*d2frhodrhodrho(i)
344     #endif
345    
346    
347     do dim = 1, 3
348    
349     drdx1 = efr(dim,j) / r
350     ftmp = dudr * drdx1
351    
352     #ifdef MPI
353     f_col(dim,j) = f_col(dim,j) - ftmp
354     f_row(dim,i) = f_row(dim,i) + ftmp
355     #else
356     f(dim,j) = f(dim,j) - ftmp
357     f(dim,i) = f(dim,i) + ftmp
358     #endif
359    
360     if (nmflag) then
361     idim = 3 * (i-1) + dim
362     jdim = 3 * (j-1) + dim
363    
364     do dim2 = 1, 3
365    
366     kt1 = d2 * efr(dim,j) * efr(dim2,j)/r/r
367     kt2 = - dudr * efr(dim,j) * efr(dim2,j)/r/r/r
368    
369     if (dim.eq.dim2) then
370     kt3 = dudr / r
371     else
372     kt3 = 0.0E0_DP
373     endif
374    
375     ! The factor of 2 below is to compensate for
376     ! overcounting.
377     ! Mass weighting is done separately...
378    
379     ktmp = (kt1+kt2+kt3)/2.0E0_DP
380     idim2 = 3 * (i-1) + dim2
381     jdim2 = 3 * (j-1) + dim2
382    
383     d(idim, idim2) = d(idim,idim2) + ktmp
384     d(idim2, idim) = d(idim2,idim) + ktmp
385    
386     d(idim, jdim2) = d(idim,jdim2) - ktmp
387     d(idim2, jdim) = d(idim2,jdim) - ktmp
388    
389     d(jdim, idim2) = d(jdim,idim2) - ktmp
390     d(jdim2, idim) = d(jdim2,idim) - ktmp
391    
392     d(jdim, jdim2) = d(jdim,jdim2) + ktmp
393     d(jdim2, jdim) = d(jdim2,jdim) + ktmp
394    
395     enddo
396     endif
397     enddo
398    
399     endif
400     enddo
401     endif
402    
403     enddo
404    
405    
406    
407    
408     end subroutine calc_eam_pair
409    
410     subroutine calc_eam_rho(r, rho, drho, d2rho, atype)
411    
412     ! include 'headers/sizes.h'
413    
414    
415     integer atype, etype, number_r
416     real( kind = DP ) :: r, rho, drho, d2rho
417     integer :: i
418    
419    
420     etype = eam_atype_map(atype)
421    
422     if (r.lt.eam_rcut(etype)) then
423     number_r = eam_nr(etype)
424     call eam_splint(etype, number_r, eam_rvals, eam_rho_r, &
425     eam_rho_r_pp, r, rho, drho, d2rho)
426     else
427     rho = 0.0E0_DP
428     drho = 0.0E0_DP
429     d2rho = 0.0E0_DP
430     endif
431    
432     return
433     end subroutine calc_eam_rho
434    
435     subroutine calc_eam_frho(dens, u, u1, u2, atype)
436    
437     ! include 'headers/sizes.h'
438    
439     integer atype, etype, number_rho
440     real( kind = DP ) :: dens, u, u1, u2
441     real( kind = DP ) :: rho_vals
442    
443     etype = eam_atype_map(atype)
444     number_rho = eam_nrho(etype)
445     if (dens.lt.eam_rhovals(number_rho, etype)) then
446     call eam_splint(etype, number_rho, eam_rhovals, eam_f_rho, &
447     eam_f_rho_pp, dens, u, u1, u2)
448     else
449     rho_vals = eam_rhovals(number_rho,etype)
450     call eam_splint(etype, number_rho, eam_rhovals, eam_f_rho, &
451     eam_f_rho_pp, rho_vals, u, u1, u2)
452     endif
453    
454     return
455     end subroutine calc_eam_frho
456    
457     subroutine calc_eam_phi(r, phi, dphi, d2phi, atype)
458    
459    
460    
461    
462     integer atype, etype, number_r
463     real( kind = DP ) :: r, phi, dphi, d2phi
464    
465     etype = eam_atype_map(atype)
466    
467     if (r.lt.eam_rcut(etype)) then
468     number_r = eam_nr(etype)
469     call eam_splint(etype, number_r, eam_rvals, eam_phi_r, &
470     eam_phi_r_pp, r, phi, dphi, d2phi)
471     else
472     phi = 0.0E0_DP
473     dphi = 0.0E0_DP
474     d2phi = 0.0E0_DP
475     endif
476    
477     return
478     end subroutine calc_eam_phi
479    
480    
481     subroutine eam_splint(atype, nx, xa, ya, yppa, x, y, dy, d2y)
482    
483     ! include 'headers/sizes.h'
484    
485     real( kind = DP ), dimension(:,:) :: xa
486     real( kind = DP ), dimension(:,:) :: ya
487     real( kind = DP ), dimension(:,:) :: yppa
488     real( kind = DP ) :: x, y, dy, d2y
489     real( kind = DP ) :: del, h, a, b, c, d
490    
491    
492     integer atype, nx, j
493    
494    
495     ! this spline code assumes that the x points are equally spaced
496     ! do not attempt to use this code if they are not.
497    
498    
499     ! find the closest point with a value below our own:
500     j = FLOOR(dble(nx-1) * (x - xa(1,atype)) / (xa(nx,atype) - xa(1,atype))) + 1
501    
502     ! check to make sure we're inside the spline range:
503     if ((j.gt.nx).or.(j.lt.1)) call error('eam_splint', &
504     'x is outside bounds of spline')
505    
506     ! check to make sure we haven't screwed up the calculation of j:
507     if ((x.lt.xa(j,atype)).or.(x.gt.xa(j+1,atype))) then
508     if (j.ne.nx) then
509     call error('eam_splint', &
510     'x is outside bounding range')
511     endif
512     endif
513    
514     del = xa(j+1,atype) - x
515     h = xa(j+1,atype) - xa(j,atype)
516    
517     a = del / h
518     b = 1.0E0_DP - a
519     c = a*(a*a - 1.0E0_DP)*h*h/6.0E0_DP
520     d = b*(b*b - 1.0E0_DP)*h*h/6.0E0_DP
521    
522     y = a*ya(j,atype) + b*ya(j+1,atype) + c*yppa(j,atype) + d*yppa(j+1,atype)
523    
524     dy = (ya(j+1,atype)-ya(j,atype))/h &
525     - (3.0E0_DP*a*a - 1.0E0_DP)*h*yppa(j,atype)/6.0E0_DP &
526     + (3.0E0_DP*b*b - 1.0E0_DP)*h*yppa(j+1,atype)/6.0E0_DP
527    
528     d2y = a*yppa(j,atype) + b*yppa(j+1,atype)
529    
530     return
531     end subroutine eam_splint
532    
533     subroutine eam_spline(atype, nx, xa, ya, yppa, yp1, ypn, boundary)
534    
535     ! include 'headers/sizes.h'
536    
537    
538     ! yp1 and ypn are the first derivatives of y at the two endpoints
539     ! if boundary is 'L' the lower derivative is used
540     ! if boundary is 'U' the upper derivative is used
541     ! if boundary is 'B' then both derivatives are used
542     ! if boundary is anything else, then both derivatives are assumed to be 0
543    
544     integer nx, i, k, atype, max_array_size
545    
546     real( kind = DP ), dimension(:,:) :: xa
547     real( kind = DP ), dimension(:,:) :: ya
548     real( kind = DP ), dimension(:,:) :: yppa
549     real( kind = DP ), allocatable, dimension(:) :: u
550     real( kind = DP ) :: yp1,ypn,un,qn,sig,p
551     character boundary
552    
553     max_array_size = size(xa,1)
554     allocate(u(max_array_size))
555    
556    
557     if ((boundary.eq.'l').or.(boundary.eq.'L').or. &
558     (boundary.eq.'b').or.(boundary.eq.'B')) then
559     yppa(1, atype) = -0.5E0_DP
560     u(1) = (3.0E0_DP/(xa(2,atype)-xa(1,atype)))*((ya(2,atype)-&
561     ya(1,atype))/(xa(2,atype)-xa(1,atype))-yp1)
562     else
563     yppa(1,atype) = 0.0E0_DP
564     u(1) = 0.0E0_DP
565     endif
566    
567     do i = 2, nx - 1
568     sig = (xa(i,atype) - xa(i-1,atype)) / (xa(i+1,atype) - xa(i-1,atype))
569     p = sig * yppa(i-1,atype) + 2.0E0_DP
570     yppa(i,atype) = (sig - 1.0E0_DP) / p
571     u(i) = (6.0E0_DP*((ya(i+1,atype)-ya(i,atype))/(xa(i+1,atype)-xa(i,atype)) - &
572     (ya(i,atype)-ya(i-1,atype))/(xa(i,atype)-xa(i-1,atype)))/ &
573     (xa(i+1,atype)-xa(i-1,atype)) - sig * u(i-1))/p
574     enddo
575    
576     if ((boundary.eq.'u').or.(boundary.eq.'U').or. &
577     (boundary.eq.'b').or.(boundary.eq.'B')) then
578     qn = 0.5E0_DP
579     un = (3.0E0_DP/(xa(nx,atype)-xa(nx-1,atype)))* &
580     (ypn-(ya(nx,atype)-ya(nx-1,atype))/(xa(nx,atype)-xa(nx-1,atype)))
581     else
582     qn = 0.0E0_DP
583     un = 0.0E0_DP
584     endif
585    
586     yppa(nx,atype)=(un-qn*u(nx-1))/(qn*yppa(nx-1,atype)+1.0E0_DP)
587    
588     do k = nx-1, 1, -1
589     yppa(k,atype)=yppa(k,atype)*yppa(k+1,atype)+u(k)
590     enddo
591    
592     deallocate(u)
593     return
594     end subroutine eam_spline
595    
596    
597    
598    
599     end module calc_eam